1// RUN: %check_clang_tidy --match-partial-fixes %s readability-implicit-bool-conversion %t -- -- -std=c23
2// RUN: %check_clang_tidy -check-suffix=UPPER-CASE %s readability-implicit-bool-conversion %t -- \
3// RUN: -config='{CheckOptions: { \
4// RUN: readability-implicit-bool-conversion.UseUpperCaseLiteralSuffix: true \
5// RUN: }}' -- -std=c23
6
7#undef NULL
8#define NULL 0L
9
10void functionTakingBool(bool);
11void functionTakingInt(int);
12void functionTakingUnsignedLong(unsigned long);
13void functionTakingChar(char);
14void functionTakingFloat(float);
15void functionTakingDouble(double);
16void functionTakingSignedChar(signed char);
17
18
19////////// Implicit conversion from bool.
20
21void implicitConversionFromBoolSimpleCases() {
22 bool boolean = true;
23
24 functionTakingBool(boolean);
25
26 functionTakingInt(boolean);
27 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: implicit conversion 'bool' -> 'int' [readability-implicit-bool-conversion]
28 // CHECK-FIXES: functionTakingInt((int)boolean);
29
30 functionTakingUnsignedLong(boolean);
31 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: implicit conversion 'bool' -> 'unsigned long'
32 // CHECK-FIXES: functionTakingUnsignedLong((unsigned long)boolean);
33
34 functionTakingChar(boolean);
35 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'bool' -> 'char'
36 // CHECK-FIXES: functionTakingChar((char)boolean);
37
38 functionTakingFloat(boolean);
39 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion 'bool' -> 'float'
40 // CHECK-FIXES: functionTakingFloat((float)boolean);
41
42 functionTakingDouble(boolean);
43 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'bool' -> 'double'
44 // CHECK-FIXES: functionTakingDouble((double)boolean);
45}
46
47float implicitConversionFromBoolInReturnValue() {
48 bool boolean = false;
49 return boolean;
50 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'bool' -> 'float'
51 // CHECK-FIXES: return (float)boolean;
52}
53
54void implicitConversionFromBoolInSingleBoolExpressions(bool b1, bool b2) {
55 bool boolean = true;
56 boolean = b1 ^ b2;
57 boolean |= !b1 || !b2;
58 boolean &= b1;
59
60 int integer = boolean - 3;
61 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit conversion 'bool' -> 'int'
62 // CHECK-FIXES: int integer = (int)boolean - 3;
63
64 float floating = boolean / 0.3f;
65 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion 'bool' -> 'float'
66 // CHECK-FIXES: float floating = (float)boolean / 0.3f;
67
68 char character = boolean;
69 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion 'bool' -> 'char'
70 // CHECK-FIXES: char character = (char)boolean;
71}
72
73void implicitConversionFromBoolInComplexBoolExpressions() {
74 bool boolean = true;
75 bool anotherBoolean = false;
76
77 int integer = boolean && anotherBoolean;
78 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit conversion 'bool' -> 'int'
79 // CHECK-MESSAGES: :[[@LINE-2]]:28: warning: implicit conversion 'bool' -> 'int'
80 // CHECK-FIXES: int integer = (int)boolean && (int)anotherBoolean;
81
82 float floating = (boolean || anotherBoolean) * 0.3f;
83 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: implicit conversion 'bool' -> 'int'
84 // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: implicit conversion 'bool' -> 'int'
85 // CHECK-FIXES: float floating = ((int)boolean || (int)anotherBoolean) * 0.3f;
86
87 double doubleFloating = (boolean && (anotherBoolean || boolean)) * 0.3;
88 // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: implicit conversion 'bool' -> 'int'
89 // CHECK-MESSAGES: :[[@LINE-2]]:40: warning: implicit conversion 'bool' -> 'int'
90 // CHECK-MESSAGES: :[[@LINE-3]]:58: warning: implicit conversion 'bool' -> 'int'
91 // CHECK-FIXES: double doubleFloating = ((int)boolean && ((int)anotherBoolean || (int)boolean)) * 0.3;
92}
93
94void implicitConversionFromBoolLiterals() {
95 functionTakingInt(true);
96 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: implicit conversion 'bool' -> 'int'
97 // CHECK-FIXES: functionTakingInt(1);
98
99 functionTakingUnsignedLong(false);
100 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: implicit conversion 'bool' -> 'unsigned long'
101 // CHECK-FIXES: functionTakingUnsignedLong(0u);
102 // CHECK-FIXES-UPPER-CASE: functionTakingUnsignedLong(0U);
103
104 functionTakingSignedChar(true);
105 // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: implicit conversion 'bool' -> 'signed char'
106 // CHECK-FIXES: functionTakingSignedChar(1);
107
108 functionTakingFloat(false);
109 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion 'bool' -> 'float'
110 // CHECK-FIXES: functionTakingFloat(0.0f);
111 // CHECK-FIXES-UPPER-CASE: functionTakingFloat(0.0F);
112
113 functionTakingDouble(true);
114 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'bool' -> 'double'
115 // CHECK-FIXES: functionTakingDouble(1.0);
116}
117
118void implicitConversionFromBoolInComparisons() {
119 bool boolean = true;
120 int integer = 0;
121
122 functionTakingBool(boolean == integer);
123 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'bool' -> 'int'
124 // CHECK-FIXES: functionTakingBool((int)boolean == integer);
125
126 functionTakingBool(integer != boolean);
127 // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion 'bool' -> 'int'
128 // CHECK-FIXES: functionTakingBool(integer != (int)boolean);
129}
130
131void ignoreBoolComparisons() {
132 bool boolean = true;
133 bool anotherBoolean = false;
134
135 functionTakingBool(boolean == anotherBoolean);
136 functionTakingBool(boolean != anotherBoolean);
137}
138
139void ignoreExplicitCastsFromBool() {
140 bool boolean = true;
141
142 int integer = (int)boolean + 3;
143 float floating = (float)boolean * 0.3f;
144 char character = (char)boolean;
145}
146
147void ignoreImplicitConversionFromBoolInMacroExpansions() {
148 bool boolean = true;
149
150 #define CAST_FROM_BOOL_IN_MACRO_BODY boolean + 3
151 int integerFromMacroBody = CAST_FROM_BOOL_IN_MACRO_BODY;
152
153 #define CAST_FROM_BOOL_IN_MACRO_ARGUMENT(x) x + 3
154 int integerFromMacroArgument = CAST_FROM_BOOL_IN_MACRO_ARGUMENT(boolean);
155}
156
157////////// Implicit conversions to bool.
158
159void implicitConversionToBoolSimpleCases() {
160 int integer = 10;
161 functionTakingBool(integer);
162 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'int' -> 'bool'
163 // CHECK-FIXES: functionTakingBool(integer != 0);
164
165 unsigned long unsignedLong = 10;
166 functionTakingBool(unsignedLong);
167 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'unsigned long' -> 'bool'
168 // CHECK-FIXES: functionTakingBool(unsignedLong != 0u);
169 // CHECK-FIXES-UPPER-CASE: functionTakingBool(unsignedLong != 0U);
170
171 float floating = 0.0f;
172 functionTakingBool(floating);
173 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'float' -> 'bool'
174 // CHECK-FIXES: functionTakingBool(floating != 0.0f);
175 // CHECK-FIXES-UPPER-CASE: functionTakingBool(floating != 0.0F);
176
177 double doubleFloating = 1.0f;
178 functionTakingBool(doubleFloating);
179 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'double' -> 'bool'
180 // CHECK-FIXES: functionTakingBool(doubleFloating != 0.0);
181
182 signed char character = 'a';
183 functionTakingBool(character);
184 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'signed char' -> 'bool'
185 // CHECK-FIXES: functionTakingBool(character != 0);
186
187 int* pointer = nullptr;
188 functionTakingBool(pointer);
189 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'int *' -> 'bool'
190 // CHECK-FIXES: functionTakingBool(pointer != nullptr);
191}
192
193void implicitConversionToBoolInSingleExpressions() {
194 int integer = 10;
195 bool boolComingFromInt;
196 boolComingFromInt = integer;
197 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion 'int' -> 'bool'
198 // CHECK-FIXES: boolComingFromInt = (integer != 0);
199
200 float floating = 10.0f;
201 bool boolComingFromFloat;
202 boolComingFromFloat = floating;
203 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion 'float' -> 'bool'
204 // CHECK-FIXES: boolComingFromFloat = (floating != 0.0f);
205 // CHECK-FIXES-UPPER-CASE: boolComingFromFloat = (floating != 0.0F);
206
207 signed char character = 'a';
208 bool boolComingFromChar;
209 boolComingFromChar = character;
210 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'signed char' -> 'bool'
211 // CHECK-FIXES: boolComingFromChar = (character != 0);
212
213 int* pointer = nullptr;
214 bool boolComingFromPointer;
215 boolComingFromPointer = pointer;
216 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: implicit conversion 'int *' -> 'bool'
217 // CHECK-FIXES: boolComingFromPointer = (pointer != nullptr);
218}
219
220void implicitConversionToBoolInComplexExpressions() {
221 bool boolean = true;
222
223 int integer = 10;
224 int anotherInteger = 20;
225 bool boolComingFromInteger;
226 boolComingFromInteger = integer + anotherInteger;
227 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: implicit conversion 'int' -> 'bool'
228 // CHECK-FIXES: boolComingFromInteger = ((integer + anotherInteger) != 0);
229}
230
231void implicitConversionInNegationExpressions() {
232 int integer = 10;
233 bool boolComingFromNegatedInt;
234 boolComingFromNegatedInt = !integer;
235 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: implicit conversion 'int' -> 'bool'
236 // CHECK-FIXES: boolComingFromNegatedInt = ((!integer) != 0);
237}
238
239bool implicitConversionToBoolInReturnValue() {
240 float floating = 1.0f;
241 return floating;
242 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'float' -> 'bool'
243 // CHECK-FIXES: return floating != 0.0f;
244}
245
246void implicitConversionToBoolFromLiterals() {
247 functionTakingBool(0);
248 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'int' -> 'bool'
249 // CHECK-FIXES: functionTakingBool(false);
250
251 functionTakingBool(1);
252 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'int' -> 'bool'
253 // CHECK-FIXES: functionTakingBool(true);
254
255 functionTakingBool(2ul);
256 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'unsigned long' -> 'bool'
257 // CHECK-FIXES: functionTakingBool(true);
258
259 functionTakingBool(0.0f);
260 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'float' -> 'bool'
261 // CHECK-FIXES: functionTakingBool(false);
262
263 functionTakingBool(1.0f);
264 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'float' -> 'bool'
265 // CHECK-FIXES: functionTakingBool(true);
266
267 functionTakingBool(2.0);
268 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'double' -> 'bool'
269 // CHECK-FIXES: functionTakingBool(true);
270
271 functionTakingBool('\0');
272 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'int' -> 'bool'
273 // CHECK-FIXES: functionTakingBool(false);
274
275 functionTakingBool('a');
276 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'int' -> 'bool'
277 // CHECK-FIXES: functionTakingBool(true);
278
279 functionTakingBool("");
280 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'char *' -> 'bool'
281 // CHECK-FIXES: functionTakingBool(true);
282
283 functionTakingBool("abc");
284 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'char *' -> 'bool'
285 // CHECK-FIXES: functionTakingBool(true);
286
287 functionTakingBool(NULL);
288 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'long' -> 'bool'
289 // CHECK-FIXES: functionTakingBool(false);
290}
291
292void implicitConversionToBoolFromUnaryMinusAndZeroLiterals() {
293 functionTakingBool(-0);
294 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'int' -> 'bool'
295 // CHECK-FIXES: functionTakingBool((-0) != 0);
296
297 functionTakingBool(-0.0f);
298 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'float' -> 'bool'
299 // CHECK-FIXES: functionTakingBool((-0.0f) != 0.0f);
300 // CHECK-FIXES-UPPER-CASE: functionTakingBool((-0.0f) != 0.0F);
301
302 functionTakingBool(-0.0);
303 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'double' -> 'bool'
304 // CHECK-FIXES: functionTakingBool((-0.0) != 0.0);
305}
306
307void ignoreImplicitCastToBoolForComparisonResult() {
308 bool boolFromComparison0 = 1 != 0;
309 bool boolFromComparison1 = 1 == 0;
310 bool boolFromComparison2 = 1 > 0;
311 bool boolFromComparison3 = 1 >= 0;
312 bool boolFromComparison4 = 1 < 0;
313 bool boolFromComparison5 = 1 <= 0;
314}
315
316void ignoreExplicitCastsToBool() {
317 int integer = 10;
318 bool boolComingFromInt = (bool)integer;
319
320 float floating = 10.0f;
321 bool boolComingFromFloat = (bool)floating;
322
323 char character = 'a';
324 bool boolComingFromChar = (bool)character;
325
326 int* pointer = nullptr;
327 bool booleanComingFromPointer = (bool)pointer;
328}
329
330void ignoreImplicitConversionToBoolInMacroExpansions() {
331 int integer = 3;
332
333 #define CAST_TO_BOOL_IN_MACRO_BODY integer && false
334 bool boolFromMacroBody = CAST_TO_BOOL_IN_MACRO_BODY;
335
336 #define CAST_TO_BOOL_IN_MACRO_ARGUMENT(x) x || true
337 bool boolFromMacroArgument = CAST_TO_BOOL_IN_MACRO_ARGUMENT(integer);
338}
339
340int implicitConversionReturnInt()
341{
342 return true;
343 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int'
344 // CHECK-FIXES: return 1
345}
346
347int implicitConversionReturnIntWithParens()
348{
349 return (true);
350 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int'
351 // CHECK-FIXES: return 1
352}
353
354bool implicitConversionReturnBool()
355{
356 return 1;
357 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool'
358 // CHECK-FIXES: return true
359}
360
361bool implicitConversionReturnBoolWithParens()
362{
363 return (1);
364 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool'
365 // CHECK-FIXES: return true
366}
367
368int keepCompactReturnInC_PR71848() {
369 bool foo = false;
370 return( foo );
371// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion 'bool' -> 'int' [readability-implicit-bool-conversion]
372// CHECK-FIXES: return(int)( foo );
373}
374

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c