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 | |
10 | void functionTakingBool(bool); |
11 | void functionTakingInt(int); |
12 | void functionTakingUnsignedLong(unsigned long); |
13 | void functionTakingChar(char); |
14 | void functionTakingFloat(float); |
15 | void functionTakingDouble(double); |
16 | void functionTakingSignedChar(signed char); |
17 | |
18 | |
19 | ////////// Implicit conversion from bool. |
20 | |
21 | void 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 | |
47 | float 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 | |
54 | void 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 | |
73 | void 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 | |
94 | void 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 | |
118 | void 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 | |
131 | void ignoreBoolComparisons() { |
132 | bool boolean = true; |
133 | bool anotherBoolean = false; |
134 | |
135 | functionTakingBool(boolean == anotherBoolean); |
136 | functionTakingBool(boolean != anotherBoolean); |
137 | } |
138 | |
139 | void 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 | |
147 | void 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 | |
159 | void 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 | |
193 | void 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 | |
220 | void 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 | |
231 | void 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 | |
239 | bool 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 | |
246 | void 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 | |
292 | void 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 | |
307 | void 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 | |
316 | void 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 | |
330 | void 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 | |
340 | int implicitConversionReturnInt() |
341 | { |
342 | return true; |
343 | // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int' |
344 | // CHECK-FIXES: return 1 |
345 | } |
346 | |
347 | int implicitConversionReturnIntWithParens() |
348 | { |
349 | return (true); |
350 | // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int' |
351 | // CHECK-FIXES: return 1 |
352 | } |
353 | |
354 | bool implicitConversionReturnBool() |
355 | { |
356 | return 1; |
357 | // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool' |
358 | // CHECK-FIXES: return true |
359 | } |
360 | |
361 | bool implicitConversionReturnBoolWithParens() |
362 | { |
363 | return (1); |
364 | // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool' |
365 | // CHECK-FIXES: return true |
366 | } |
367 | |
368 | int 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 |
Definitions
- implicitConversionFromBoolSimpleCases
- implicitConversionFromBoolInReturnValue
- implicitConversionFromBoolInSingleBoolExpressions
- implicitConversionFromBoolInComplexBoolExpressions
- implicitConversionFromBoolLiterals
- implicitConversionFromBoolInComparisons
- ignoreBoolComparisons
- ignoreExplicitCastsFromBool
- ignoreImplicitConversionFromBoolInMacroExpansions
- implicitConversionToBoolSimpleCases
- implicitConversionToBoolInSingleExpressions
- implicitConversionToBoolInComplexExpressions
- implicitConversionInNegationExpressions
- implicitConversionToBoolInReturnValue
- implicitConversionToBoolFromLiterals
- implicitConversionToBoolFromUnaryMinusAndZeroLiterals
- ignoreImplicitCastToBoolForComparisonResult
- ignoreExplicitCastsToBool
- ignoreImplicitConversionToBoolInMacroExpansions
- implicitConversionReturnInt
- implicitConversionReturnIntWithParens
- implicitConversionReturnBool
- implicitConversionReturnBoolWithParens
Improve your Profiling and Debugging skills
Find out more