1// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t
2
3bool a1 = false;
4
5//=-=-=-=-=-=-= operator ==
6bool aa = false == a1;
7// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant boolean literal supplied to boolean operator [readability-simplify-boolean-expr]
8// CHECK-FIXES: {{^bool aa = !a1;$}}
9bool ab = true == a1;
10// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator
11// CHECK-FIXES: {{^bool ab = a1;$}}
12bool a2 = a1 == false;
13// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
14// CHECK-FIXES: {{^bool a2 = !a1;$}}
15bool a3 = a1 == true;
16// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
17// CHECK-FIXES: {{^bool a3 = a1;$}}
18
19//=-=-=-=-=-=-= operator !=
20bool n1 = a1 != false;
21// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
22// CHECK-FIXES: {{^bool n1 = a1;$}}
23bool n2 = a1 != true;
24// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
25// CHECK-FIXES: {{^bool n2 = !a1;$}}
26bool n3 = false != a1;
27// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator
28// CHECK-FIXES: {{^bool n3 = a1;$}}
29bool n4 = true != a1;
30// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator
31// CHECK-FIXES: {{^bool n4 = !a1;$}}
32
33//=-=-=-=-=-=-= operator ||
34bool a4 = a1 || false;
35// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
36// CHECK-FIXES: {{^bool a4 = a1;$}}
37bool a5 = a1 || true;
38// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
39// CHECK-FIXES: {{^bool a5 = true;$}}
40bool a6 = false || a1;
41// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator
42// CHECK-FIXES: {{^bool a6 = a1;$}}
43bool a7 = true || a1;
44// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator
45// CHECK-FIXES: {{^bool a7 = true;$}}
46
47//=-=-=-=-=-=-= operator &&
48bool a8 = a1 && false;
49// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
50// CHECK-FIXES: {{^bool a8 = false;$}}
51bool a9 = a1 && true;
52// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
53// CHECK-FIXES: {{^bool a9 = a1;$}}
54bool ac = false && a1;
55// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator
56// CHECK-FIXES: {{^bool ac = false;$}}
57bool = true && a1;
58// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator
59// CHECK-FIXES: {{^bool ad = a1;$}}
60
61void if_with_bool_literal_condition() {
62 int i = 0;
63 if (false) {
64 i = 1;
65 } else {
66 i = 2;
67 }
68 i = 3;
69 // CHECK-MESSAGES: :[[@LINE-6]]:7: warning: {{.*}} in if statement condition
70 // CHECK-FIXES: {{^ int i = 0;$}}
71 // CHECK-FIXES-NEXT: {{^ {$}}
72 // CHECK-FIXES-NEXT: {{^ i = 2;$}}
73 // CHECK-FIXES-NEXT: {{^ }$}}
74 // CHECK-FIXES-NEXT: {{^ i = 3;$}}
75
76 i = 4;
77 if (true) {
78 i = 5;
79 } else {
80 i = 6;
81 }
82 i = 7;
83 // CHECK-MESSAGES: :[[@LINE-6]]:7: warning: {{.*}} in if statement condition
84 // CHECK-FIXES: {{^ i = 4;$}}
85 // CHECK-FIXES-NEXT: {{^ {$}}
86 // CHECK-FIXES-NEXT: {{^ i = 5;$}}
87 // CHECK-FIXES-NEXT: {{^ }$}}
88 // CHECK-FIXES-NEXT: {{^ i = 7;$}}
89
90 i = 8;
91 if (false) {
92 i = 9;
93 }
94 i = 11;
95 // CHECK-MESSAGES: :[[@LINE-4]]:7: warning: {{.*}} in if statement condition
96 // CHECK-FIXES: {{^ i = 8;$}}
97 // CHECK-FIXES-NEXT: {{^ $}}
98 // CHECK-FIXES-NEXT: {{^ i = 11;$}}
99}
100
101void if_with_negated_bool_condition() {
102 int i = 10;
103 if (!true) {
104 i = 11;
105 } else {
106 i = 12;
107 }
108 i = 13;
109 // CHECK-MESSAGES: :[[@LINE-6]]:7: warning: {{.*}} in if statement condition
110 // CHECK-FIXES: {{^ int i = 10;$}}
111 // CHECK-FIXES-NEXT: {{^ {$}}
112 // CHECK-FIXES-NEXT: {{^ i = 12;$}}
113 // CHECK-FIXES-NEXT: {{^ }$}}
114 // CHECK-FIXES-NEXT: {{^ i = 13;$}}
115
116 i = 14;
117 if (!false) {
118 i = 15;
119 } else {
120 i = 16;
121 }
122 i = 17;
123 // CHECK-MESSAGES: :[[@LINE-6]]:7: warning: {{.*}} in if statement condition
124 // CHECK-FIXES: {{^ i = 14;$}}
125 // CHECK-FIXES-NEXT: {{^ {$}}
126 // CHECK-FIXES-NEXT: {{^ i = 15;$}}
127 // CHECK-FIXES-NEXT: {{^ }$}}
128 // CHECK-FIXES-NEXT: {{^ i = 17;$}}
129
130 i = 18;
131 if (!true) {
132 i = 19;
133 }
134 i = 20;
135 // CHECK-MESSAGES: :[[@LINE-4]]:7: warning: {{.*}} in if statement condition
136 // CHECK-FIXES: {{^ i = 18;$}}
137 // CHECK-FIXES-NEXT: {{^ $}}
138 // CHECK-FIXES-NEXT: {{^ i = 20;$}}
139}
140
141void operator_equals() {
142 int i = 0;
143 bool b1 = (i > 2);
144 if (b1 == true) {
145 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} to boolean operator
146 // CHECK-FIXES: {{^ if \(b1\) {$}}
147 i = 5;
148 } else {
149 i = 6;
150 }
151 bool b2 = (i > 4);
152 if (b2 == false) {
153 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} to boolean operator
154 // CHECK-FIXES: {{^ if \(!b2\) {$}}
155 i = 7;
156 } else {
157 i = 9;
158 }
159 bool b3 = (i > 6);
160 if (true == b3) {
161 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator
162 // CHECK-FIXES: {{^ if \(b3\) {$}}
163 i = 10;
164 } else {
165 i = 11;
166 }
167 bool b4 = (i > 8);
168 if (false == b4) {
169 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator
170 // CHECK-FIXES: {{^ if \(!b4\) {$}}
171 i = 12;
172 } else {
173 i = 13;
174 }
175}
176
177void operator_or() {
178 int i = 0;
179 bool b5 = (i > 10);
180 if (b5 || false) {
181 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} to boolean operator
182 // CHECK-FIXES: {{^ if \(b5\) {$}}
183 i = 14;
184 } else {
185 i = 15;
186 }
187 bool b6 = (i > 10);
188 if (b6 || true) {
189 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} to boolean operator
190 // CHECK-FIXES: {{^ if \(true\) {$}}
191 i = 16;
192 } else {
193 i = 17;
194 }
195 bool b7 = (i > 10);
196 if (false || b7) {
197 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator
198 // CHECK-FIXES: {{^ if \(b7\) {$}}
199 i = 18;
200 } else {
201 i = 19;
202 }
203 bool b8 = (i > 10);
204 if (true || b8) {
205 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator
206 // CHECK-FIXES: {{^ if \(true\) {$}}
207 i = 20;
208 } else {
209 i = 21;
210 }
211}
212
213void operator_and() {
214 int i = 0;
215 bool b9 = (i > 20);
216 if (b9 && false) {
217 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} to boolean operator
218 // CHECK-FIXES: {{^ if \(false\) {$}}
219 i = 22;
220 } else {
221 i = 23;
222 }
223 bool ba = (i > 20);
224 if (ba && true) {
225 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} to boolean operator
226 // CHECK-FIXES: {{^ if \(ba\) {$}}
227 i = 24;
228 } else {
229 i = 25;
230 }
231 bool bb = (i > 20);
232 if (false && bb) {
233 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator
234 // CHECK-FIXES: {{^ if \(false\) {$}}
235 i = 26;
236 } else {
237 i = 27;
238 }
239 bool bc = (i > 20);
240 if (true && bc) {
241 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator
242 // CHECK-FIXES: {{^ if \(bc\) {$}}
243 i = 28;
244 } else {
245 i = 29;
246 }
247}
248
249void ternary_operator() {
250 int i = 0;
251 bool bd = (i > 20) ? true : false;
252 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: {{.*}} in ternary expression result
253 // CHECK-FIXES: {{^ bool bd = i > 20;$}}
254
255 bool be = (i > 20) ? false : true;
256 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: {{.*}} in ternary expression result
257 // CHECK-FIXES: {{^ bool be = i <= 20;$}}
258
259 bool bf = ((i > 20)) ? false : true;
260 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: {{.*}} in ternary expression result
261 // CHECK-FIXES: {{^ bool bf = i <= 20;$}}
262}
263
264void operator_not_equal() {
265 int i = 0;
266 bool bf = (i > 20);
267 if (false != bf) {
268 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator
269 // CHECK-FIXES: {{^ if \(bf\) {$}}
270 i = 30;
271 } else {
272 i = 31;
273 }
274 bool bg = (i > 20);
275 if (true != bg) {
276 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator
277 // CHECK-FIXES: {{^ if \(!bg\) {$}}
278 i = 32;
279 } else {
280 i = 33;
281 }
282 bool bh = (i > 20);
283 if (bh != false) {
284 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} to boolean operator
285 // CHECK-FIXES: {{^ if \(bh\) {$}}
286 i = 34;
287 } else {
288 i = 35;
289 }
290 bool bi = (i > 20);
291 if (bi != true) {
292 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} to boolean operator
293 // CHECK-FIXES: {{^ if \(!bi\) {$}}
294 i = 36;
295 } else {
296 i = 37;
297 }
298}
299
300void nested_booleans() {
301 if (false || (true || false)) {
302 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
303 // CHECK-FIXES: {{^ if \(false \|\| \(true\)\) {$}}
304 }
305 if (true && (true || false)) {
306 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} to boolean operator
307 // CHECK-FIXES: {{^ if \(true && \(true\)\) {$}}
308 }
309 if (false || (true && false)) {
310 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
311 // CHECK-FIXES: {{^ if \(false \|\| \(false\)\) {$}}
312 }
313 if (true && (true && false)) {
314 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} to boolean operator
315 // CHECK-FIXES: {{^ if \(true && \(false\)\) {$}}
316 }
317}
318
319static constexpr bool truthy() {
320 return true;
321}
322
323#define HAS_XYZ_FEATURE true
324#define M1(what) M2(true, what)
325#define M2(condition, what) if (condition) what
326
327void macros_and_constexprs(int i = 0) {
328 bool b = (i == 1);
329 if (b && truthy()) {
330 // leave this alone; if you want it simplified, then you should
331 // inline the constexpr function first.
332 i = 1;
333 }
334 i = 2;
335 if (b && HAS_XYZ_FEATURE) {
336 // leave this alone; if you want it simplified, then you should
337 // inline the macro first.
338 i = 3;
339 }
340 if (HAS_XYZ_FEATURE) {
341 i = 5;
342 }
343 i = 4;
344 M1(i = 7);
345}
346
347#undef HAS_XYZ_FEATURE
348
349bool conditional_return_statements(int i) {
350 if (i == 0) return true; else return false;
351}
352// CHECK-MESSAGES: :[[@LINE-2]]:22: warning: {{.*}} in conditional return statement
353// CHECK-FIXES: {{^}} return i == 0;{{$}}
354// CHECK-FIXES-NEXT: {{^}$}}
355
356bool conditional_return_statements_then_expr(int i, int j) {
357 if (i == j) return (i == 0); else return false;
358}
359
360bool conditional_return_statements_else_expr(int i, int j) {
361 if (i == j) return true; else return (i == 0);
362}
363
364bool negated_conditional_return_statements(int i) {
365 if (i == 0) return false; else return true;
366}
367// CHECK-MESSAGES: :[[@LINE-2]]:22: warning: {{.*}} in conditional return statement
368// CHECK-FIXES: {{^}} return i != 0;{{$}}
369// CHECK-FIXES-NEXT: {{^}$}}
370
371bool negative_condition_conditional_return_statement(int i) {
372 if (!(i == 0)) return false; else return true;
373}
374// CHECK-MESSAGES: :[[@LINE-2]]:25: warning: {{.*}} in conditional return statement
375// CHECK-FIXES: {{^}} return i == 0;{{$}}
376// CHECK-FIXES-NEXT: {{^}$}}
377
378bool conditional_compound_return_statements(int i) {
379 if (i == 1) {
380 return true;
381 } else {
382 return false;
383 }
384}
385// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return statement
386// CHECK-FIXES: {{^}}bool conditional_compound_return_statements(int i) {{{$}}
387// CHECK-FIXES-NEXT: {{^}} return i == 1;{{$}}
388// CHECK-FIXES-NEXT: {{^}$}}
389
390bool negated_conditional_compound_return_statements(int i) {
391 if (i == 1) {
392 return false;
393 } else {
394 return true;
395 }
396}
397// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return statement
398// CHECK-FIXES: {{^}}bool negated_conditional_compound_return_statements(int i) {{{$}}
399// CHECK-FIXES-NEXT: {{^}} return i != 1;{{$}}
400// CHECK-FIXES-NEXT: {{^}$}}
401
402bool conditional_return_statements_side_effects_then(int i) {
403 if (i == 2) {
404 macros_and_constexprs();
405 return true;
406 } else
407 return false;
408}
409
410bool negated_conditional_return_statements_side_effects_then(int i) {
411 if (i == 2) {
412 macros_and_constexprs();
413 return false;
414 } else
415 return true;
416}
417
418bool conditional_return_statements_side_effects_else(int i) {
419 if (i == 2)
420 return true;
421 else {
422 macros_and_constexprs();
423 return false;
424 }
425}
426
427bool negated_conditional_return_statements_side_effects_else(int i) {
428 if (i == 2)
429 return false;
430 else {
431 macros_and_constexprs();
432 return true;
433 }
434}
435
436void lambda_conditional_return_statements() {
437 auto lambda = [](int n) -> bool { if (n > 0) return true; else return false; };
438 // CHECK-MESSAGES: :[[@LINE-1]]:55: warning: {{.*}} in conditional return statement
439 // CHECK-FIXES: {{^}} auto lambda = [](int n) -> bool { return n > 0; };{{$}}
440
441 auto lambda2 = [](int n) -> bool {
442 if (n > 0) {
443 return true;
444 } else {
445 return false;
446 }
447 };
448 // CHECK-MESSAGES: :[[@LINE-5]]:16: warning: {{.*}} in conditional return statement
449 // CHECK-FIXES: {{^}} auto lambda2 = [](int n) -> bool {{{$}}
450 // CHECK-FIXES-NEXT: {{^}} return n > 0;{{$}}
451 // CHECK-FIXES-NEXT: {{^}} };{{$}}
452
453 auto lambda3 = [](int n) -> bool { if (n > 0) {macros_and_constexprs(); return true; } else return false; };
454
455 auto lambda4 = [](int n) -> bool {
456 if (n > 0)
457 return true;
458 else {
459 macros_and_constexprs();
460 return false;
461 }
462 };
463
464 auto lambda5 = [](int n) -> bool { if (n > 0) return false; else return true; };
465 // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: {{.*}} in conditional return statement
466 // CHECK-FIXES: {{^}} auto lambda5 = [](int n) -> bool { return n <= 0; };{{$}}
467
468 auto lambda6 = [](int n) -> bool {
469 if (n > 0) {
470 return false;
471 } else {
472 return true;
473 }
474 };
475 // CHECK-MESSAGES: :[[@LINE-5]]:16: warning: {{.*}} in conditional return statement
476 // CHECK-FIXES: {{^}} auto lambda6 = [](int n) -> bool {{{$}}
477 // CHECK-FIXES-NEXT: {{^}} return n <= 0;{{$}}
478 // CHECK-FIXES-NEXT: {{^}} };{{$}}
479}
480
481bool condition_variable_return_stmt(int i) {
482 // Unchanged: condition variable.
483 if (bool Res = i == 0)
484 return true;
485 else
486 return false;
487}
488
489void simple_conditional_assignment_statements(int i) {
490 bool b;
491 if (i > 10)
492 b = true;
493 else
494 b = false;
495 bool bb = false;
496 // CHECK-MESSAGES: :[[@LINE-4]]:9: warning: {{.*}} in conditional assignment
497 // CHECK-FIXES: bool b;
498 // CHECK-FIXES: {{^ }}b = i > 10;{{$}}
499 // CHECK-FIXES: bool bb = false;
500
501 bool c;
502 if (i > 20)
503 c = false;
504 else
505 c = true;
506 bool c2 = false;
507 // CHECK-MESSAGES: :[[@LINE-4]]:9: warning: {{.*}} in conditional assignment
508 // CHECK-FIXES: bool c;
509 // CHECK-FIXES: {{^ }}c = i <= 20;{{$}}
510 // CHECK-FIXES: bool c2 = false;
511
512 // Unchanged: different variables.
513 bool b2;
514 if (i > 12)
515 b = true;
516 else
517 b2 = false;
518
519 // Unchanged: no else statement.
520 bool b3;
521 if (i > 15)
522 b3 = true;
523
524 // Unchanged: not boolean assignment.
525 int j;
526 if (i > 17)
527 j = 10;
528 else
529 j = 20;
530
531 // Unchanged: different variables assigned.
532 int k = 0;
533 bool b4 = false;
534 if (i > 10)
535 b4 = true;
536 else
537 k = 10;
538}
539
540void complex_conditional_assignment_statements(int i) {
541 bool d;
542 if (i > 30) {
543 d = true;
544 } else {
545 d = false;
546 }
547 d = false;
548 // CHECK-MESSAGES: :[[@LINE-5]]:9: warning: {{.*}} in conditional assignment
549 // CHECK-FIXES: bool d;
550 // CHECK-FIXES: {{^ }}d = i > 30;{{$}}
551 // CHECK-FIXES: d = false;
552
553 bool e;
554 if (i > 40) {
555 e = false;
556 } else {
557 e = true;
558 }
559 e = false;
560 // CHECK-MESSAGES: :[[@LINE-5]]:9: warning: {{.*}} in conditional assignment
561 // CHECK-FIXES: bool e;
562 // CHECK-FIXES: {{^ }}e = i <= 40;{{$}}
563 // CHECK-FIXES: e = false;
564
565 // Unchanged: no else statement.
566 bool b3;
567 if (i > 15) {
568 b3 = true;
569 }
570
571 // Unchanged: not a boolean assignment.
572 int j;
573 if (i > 17) {
574 j = 10;
575 } else {
576 j = 20;
577 }
578
579 // Unchanged: multiple statements.
580 bool f;
581 if (j > 10) {
582 j = 10;
583 f = true;
584 } else {
585 j = 20;
586 f = false;
587 }
588
589 // Unchanged: multiple statements.
590 bool g;
591 if (j > 10)
592 g = true;
593 else {
594 j = 20;
595 g = false;
596 }
597
598 // Unchanged: multiple statements.
599 bool h;
600 if (j > 10) {
601 j = 10;
602 h = true;
603 } else
604 h = false;
605
606 // Unchanged: condition variable.
607 bool k;
608 if (bool Res = j > 10)
609 k = true;
610 else
611 k = false;
612}
613
614// Unchanged: chained return statements, but ChainedConditionalReturn not set.
615bool chained_conditional_compound_return(int i) {
616 if (i < 0) {
617 return true;
618 } else if (i < 10) {
619 return false;
620 } else if (i > 20) {
621 return true;
622 } else {
623 return false;
624 }
625}
626
627// Unchanged: chained return statements, but ChainedConditionalReturn not set.
628bool chained_conditional_return(int i) {
629 if (i < 0)
630 return true;
631 else if (i < 10)
632 return false;
633 else if (i > 20)
634 return true;
635 else
636 return false;
637}
638
639// Unchanged: chained assignments, but ChainedConditionalAssignment not set.
640void chained_conditional_compound_assignment(int i) {
641 bool b;
642 if (i < 0) {
643 b = true;
644 } else if (i < 10) {
645 b = false;
646 } else if (i > 20) {
647 b = true;
648 } else {
649 b = false;
650 }
651}
652
653// Unchanged: chained return statements, but ChainedConditionalReturn not set.
654void chained_conditional_assignment(int i) {
655 bool b;
656 if (i < 0)
657 b = true;
658 else if (i < 10)
659 b = false;
660 else if (i > 20)
661 b = true;
662 else
663 b = false;
664}
665
666// Unchanged: chained return statements, but ChainedConditionalReturn not set.
667bool chained_simple_if_return_negated(int i) {
668 if (i < 5)
669 return false;
670 if (i > 10)
671 return false;
672 return true;
673}
674
675// Unchanged: chained return statements, but ChainedConditionalReturn not set.
676bool complex_chained_if_return_return(int i) {
677 if (i < 5) {
678 return true;
679 }
680 if (i > 10) {
681 return true;
682 }
683 return false;
684}
685
686// Unchanged: chained return statements, but ChainedConditionalReturn not set.
687bool complex_chained_if_return_return_negated(int i) {
688 if (i < 5) {
689 return false;
690 }
691 if (i > 10) {
692 return false;
693 }
694 return true;
695}
696
697// Unchanged: chained return statements, but ChainedConditionalReturn not set.
698bool chained_simple_if_return(int i) {
699 if (i < 5)
700 return true;
701 if (i > 10)
702 return true;
703 return false;
704}
705
706bool simple_if_return_return(int i) {
707 if (i > 10)
708 return true;
709 return false;
710}
711// CHECK-MESSAGES: :[[@LINE-3]]:12: warning: {{.*}} in conditional return
712// CHECK-FIXES: {{^}}bool simple_if_return_return(int i) {{{$}}
713// CHECK-FIXES: {{^ return i > 10;$}}
714// CHECK-FIXES: {{^}$}}
715
716bool simple_if_return_return_negated(int i) {
717 if (i > 10)
718 return false;
719 return true;
720}
721// CHECK-MESSAGES: :[[@LINE-3]]:12: warning: {{.*}} in conditional return
722// CHECK-FIXES: {{^}}bool simple_if_return_return_negated(int i) {{{$}}
723// CHECK-FIXES: {{^ return i <= 10;$}}
724// CHECK-FIXES: {{^}$}}
725
726bool complex_if_return_return(int i) {
727 if (i > 10) {
728 return true;
729 }
730 return false;
731}
732// CHECK-MESSAGES: :[[@LINE-4]]:12: warning: {{.*}} in conditional return
733// CHECK-FIXES: {{^}}bool complex_if_return_return(int i) {{{$}}
734// CHECK-FIXES: {{^ return i > 10;$}}
735// CHECK-FIXES: {{^}$}}
736
737bool complex_if_return_return_negated(int i) {
738 if (i > 10) {
739 return false;
740 }
741 return true;
742}
743// CHECK-MESSAGES: :[[@LINE-4]]:12: warning: {{.*}} in conditional return
744// CHECK-FIXES: {{^}}bool complex_if_return_return_negated(int i) {{{$}}
745// CHECK-FIXES: {{^ return i <= 10;$}}
746// CHECK-FIXES: {{^}$}}
747
748bool if_implicit_bool_expr(int i) {
749 if (i & 1) {
750 return true;
751 } else {
752 return false;
753 }
754}
755// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
756// CHECK-FIXES: {{^}} return (i & 1) != 0;{{$}}
757
758bool negated_if_implicit_bool_expr(int i) {
759 if (i - 1) {
760 return false;
761 } else {
762 return true;
763 }
764}
765// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
766// CHECK-FIXES: {{^}} return (i - 1) == 0;{{$}}
767
768bool implicit_int(int i) {
769 if (i) {
770 return true;
771 } else {
772 return false;
773 }
774}
775// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
776// CHECK-FIXES: {{^}} return i != 0;{{$}}
777
778bool explicit_bool(bool b) {
779 if (b) {
780 return true;
781 } else {
782 return false;
783 }
784}
785// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
786// CHECK-FIXES: {{^}} return b;{{$}}
787
788class Implicit {
789public:
790 operator bool() {
791 return true;
792 }
793};
794
795bool object_bool_implicit_conversion(Implicit O) {
796 if (O) {
797 return true;
798 } else {
799 return false;
800 }
801}
802// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
803// CHECK-FIXES: {{^}} return O;{{$}}
804
805bool negated_explicit_bool(bool b) {
806 if (!b) {
807 return true;
808 } else {
809 return false;
810 }
811}
812// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
813// CHECK-FIXES: {{^}} return !b;{{$}}
814
815bool bitwise_complement_conversion(int i) {
816 if (~i) {
817 return true;
818 } else {
819 return false;
820 }
821}
822// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
823// CHECK-FIXES: {{^}} return ~i != 0;{{$}}
824
825bool logical_or(bool a, bool b) {
826 if (a || b) {
827 return true;
828 } else {
829 return false;
830 }
831}
832// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
833// CHECK-FIXES: {{^}} return a || b;{{$}}
834
835bool logical_and(bool a, bool b) {
836 if (a && b) {
837 return true;
838 } else {
839 return false;
840 }
841}
842// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
843// CHECK-FIXES: {{^}} return a && b;{{$}}
844
845class Comparable
846{
847public:
848 bool operator==(Comparable const &rhs) { return true; }
849 bool operator!=(Comparable const &rhs) { return false; }
850};
851
852bool comparable_objects() {
853 Comparable c;
854 Comparable d;
855 if (c == d) {
856 return true;
857 } else {
858 return false;
859 }
860}
861// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
862// CHECK-FIXES: {{^}} return c == d;{{$}}
863
864bool negated_comparable_objects() {
865 Comparable c;
866 Comparable d;
867 if (c == d) {
868 return false;
869 } else {
870 return true;
871 }
872}
873// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
874// CHECK-FIXES: {{^}} return c != d;{{$}}
875
876struct X {
877 explicit operator bool();
878};
879
880void explicit_conversion_assignment(X x) {
881 bool y;
882 if (x) {
883 y = true;
884 } else {
885 y = false;
886 }
887}
888// CHECK-MESSAGES: :[[@LINE-5]]:9: warning: {{.*}} in conditional assignment
889// CHECK-FIXES: {{^ bool y;$}}
890// CHECK-FIXES: {{^}} y = static_cast<bool>(x);{{$}}
891
892void ternary_integer_condition(int i) {
893 bool b = i ? true : false;
894}
895// CHECK-MESSAGES: :[[@LINE-2]]:16: warning: {{.*}} in ternary expression result
896// CHECK-FIXES: bool b = i != 0;{{$}}
897
898bool non_null_pointer_condition(int *p1) {
899 if (p1) {
900 return true;
901 } else {
902 return false;
903 }
904}
905// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
906// CHECK-FIXES: return p1 != nullptr;{{$}}
907
908bool null_pointer_condition(int *p2) {
909 if (!p2) {
910 return true;
911 } else {
912 return false;
913 }
914}
915// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
916// CHECK-FIXES: return p2 == nullptr;{{$}}
917
918bool negated_non_null_pointer_condition(int *p3) {
919 if (p3) {
920 return false;
921 } else {
922 return true;
923 }
924}
925// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
926// CHECK-FIXES: return p3 == nullptr;{{$}}
927
928bool negated_null_pointer_condition(int *p4) {
929 if (!p4) {
930 return false;
931 } else {
932 return true;
933 }
934}
935// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
936// CHECK-FIXES: return p4 != nullptr;{{$}}
937
938bool comments_in_the_middle(bool b) {
939 if (b) {
940 return true;
941 } else {
942 // something wicked this way comes
943 return false;
944 }
945}
946// CHECK-MESSAGES: :[[@LINE-6]]:12: warning: {{.*}} in conditional return
947// CHECK-FIXES: {{^}} if (b) {
948// CHECK-FIXES: // something wicked this way comes{{$}}
949
950bool preprocessor_in_the_middle(bool b) {
951 if (b) {
952 return true;
953 } else {
954#define SOMETHING_WICKED false
955 return false;
956 }
957}
958// CHECK-MESSAGES: :[[@LINE-6]]:12: warning: {{.*}} in conditional return
959// CHECK-FIXES: {{^}} if (b) {
960// CHECK-FIXES: {{^}}#define SOMETHING_WICKED false
961
962bool integer_not_zero(int i) {
963 if (i) {
964 return false;
965 } else {
966 return true;
967 }
968}
969// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
970// CHECK-FIXES: {{^}} return i == 0;{{$}}
971
972class A {
973public:
974 int m;
975};
976
977bool member_pointer_nullptr(int A::*p) {
978 if (p) {
979 return true;
980 } else {
981 return false;
982 }
983}
984// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
985// CHECK-FIXES: return p != nullptr;{{$}}
986
987bool integer_member_implicit_cast(A *p) {
988 if (p->m) {
989 return true;
990 } else {
991 return false;
992 }
993}
994// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
995// CHECK-FIXES: return p->m != 0;{{$}}
996
997bool operator!=(const A&, const A&) { return false; }
998bool expr_with_cleanups(A &S) {
999 if (S != (A)S)
1000 return false;
1001
1002 return true;
1003}
1004// CHECK-MESSAGES: :[[@LINE-4]]:12: warning: {{.*}} in conditional return
1005// CHECK-FIXES: S == (A)S;{{$}}
1006
1007template <bool B>
1008void ignoreInstantiations() {
1009 if (B) {
1010 return;
1011 } else {
1012 return;
1013 }
1014}
1015
1016void instantiate() {
1017 // Just make sure the check isn't fooled by template instantiations.
1018 ignoreInstantiations<true>();
1019 ignoreInstantiations<false>();
1020}
1021

source code of clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr.cpp