1 // RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t 2 3 bool a1 = false; 4 5 //=-=-=-=-=-=-= operator == 6 bool 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;$}} 9 bool ab = true == a1; 10 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator 11 // CHECK-FIXES: {{^bool ab = a1;$}} 12 bool a2 = a1 == false; 13 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator 14 // CHECK-FIXES: {{^bool a2 = !a1;$}} 15 bool a3 = a1 == true; 16 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator 17 // CHECK-FIXES: {{^bool a3 = a1;$}} 18 19 //=-=-=-=-=-=-= operator != 20 bool n1 = a1 != false; 21 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator 22 // CHECK-FIXES: {{^bool n1 = a1;$}} 23 bool n2 = a1 != true; 24 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator 25 // CHECK-FIXES: {{^bool n2 = !a1;$}} 26 bool n3 = false != a1; 27 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator 28 // CHECK-FIXES: {{^bool n3 = a1;$}} 29 bool n4 = true != a1; 30 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator 31 // CHECK-FIXES: {{^bool n4 = !a1;$}} 32 33 //=-=-=-=-=-=-= operator || 34 bool a4 = a1 || false; 35 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator 36 // CHECK-FIXES: {{^bool a4 = a1;$}} 37 bool a5 = a1 || true; 38 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator 39 // CHECK-FIXES: {{^bool a5 = true;$}} 40 bool a6 = false || a1; 41 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator 42 // CHECK-FIXES: {{^bool a6 = a1;$}} 43 bool a7 = true || a1; 44 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator 45 // CHECK-FIXES: {{^bool a7 = true;$}} 46 47 //=-=-=-=-=-=-= operator && 48 bool a8 = a1 && false; 49 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator 50 // CHECK-FIXES: {{^bool a8 = false;$}} 51 bool a9 = a1 && true; 52 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator 53 // CHECK-FIXES: {{^bool a9 = a1;$}} 54 bool ac = false && a1; 55 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator 56 // CHECK-FIXES: {{^bool ac = false;$}} 57 bool ad = true && a1; 58 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator 59 // CHECK-FIXES: {{^bool ad = a1;$}} 60 61 void 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 101 void 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 141 void 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 177 void 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 213 void 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 249 void 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 264 void 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 300 void 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 319 static 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 327 void 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 349 bool 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 356 bool conditional_return_statements_then_expr(int i, int j) { 357 if (i == j) return (i == 0); else return false; 358 } 359 360 bool conditional_return_statements_else_expr(int i, int j) { 361 if (i == j) return true; else return (i == 0); 362 } 363 364 bool 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 371 bool 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 378 bool 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 390 bool 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 402 bool 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 410 bool 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 418 bool 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 427 bool 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 436 void 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 481 bool 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 489 void 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 540 void 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. 615 bool 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. 628 bool 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. 640 void 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. 654 void 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. 667 bool 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. 676 bool 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. 687 bool 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. 698 bool 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 706 bool 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 716 bool 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 726 bool 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 737 bool 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 748 bool 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 758 bool 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 768 bool 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 778 bool 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 788 class Implicit { 789 public: 790 operator bool() { 791 return true; 792 } 793 }; 794 795 bool 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 805 bool 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 815 bool 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 825 bool 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 835 bool 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 845 class Comparable 846 { 847 public: 848 bool operator==(Comparable const &rhs) { return true; } 849 bool operator!=(Comparable const &rhs) { return false; } 850 }; 851 852 bool 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 864 bool 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 876 struct X { 877 explicit operator bool(); 878 }; 879 880 void 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 892 void 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 898 bool 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 908 bool 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 918 bool 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 928 bool 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 938 bool 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 950 bool 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 962 bool 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 972 class A { 973 public: 974 int m; 975 }; 976 977 bool 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 987 bool 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 997 bool operator!=(const A&, const A&) { return false; } 998 bool 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 1007 template <bool B> 1008 void ignoreInstantiations() { 1009 if (B) { 1010 return; 1011 } else { 1012 return; 1013 } 1014 } 1015 1016 void instantiate() { 1017 // Just make sure the check isn't fooled by template instantiations. 1018 ignoreInstantiations<true>(); 1019 ignoreInstantiations<false>(); 1020 } 1021