769 lines · cpp
1// RUN: %check_clang_tidy %s bugprone-branch-clone %t --2 3/* Only one expected warning per function allowed at the very end. */4 5int func(void)6{7 return 0;8}9 10int func2(void)11{12 return 0;13}14 15int funcParam(int a)16{17 return 0;18}19 20/* '!=' operator*/21 22 23/* '!=' with int pointer */24 25int checkNotEqualIntPointerLiteralCompare1(void) {26 int* p = 0;27 return (p != 0); // no warning28}29 30int checkNotEqualIntPointerLiteralCompare2(void) {31 return (6 != 7); // no warning32}33 34int checkNotEqualIntPointerDeclCompare1(void) {35 int k = 3;36 int* f = &k;37 int* g = &k;38 return (f != g); // no warning39}40 41int checkNotEqualCastIntPointerDeclCompare11(void) {42 int k = 7;43 int* f = &k;44 return ((int*)f != (int*)f);45}46int checkNotEqualCastIntPointerDeclCompare12(void) {47 int k = 7;48 int* f = &k;49 return ((int*)((char*)f) != (int*)f); // no warning50}51int checkNotEqualBinaryOpIntPointerCompare1(void) {52 int k = 7;53 int res;54 int* f= &k;55 res = (f + 4 != f + 4);56 return (0);57}58int checkNotEqualBinaryOpIntPointerCompare2(void) {59 int k = 7;60 int* f = &k;61 int* g = &k;62 return (f + 4 != g + 4); // no warning63}64 65 66int checkNotEqualBinaryOpIntPointerCompare3(void) {67 int k = 7;68 int res;69 int* f= &k;70 res = ((int*)f + 4 != (int*)f + 4);71 return (0);72}73int checkNotEqualBinaryOpIntPointerCompare4(void) {74 int k = 7;75 int res;76 int* f= &k;77 res = ((int*)f + 4 != (int*)((char*)f) + 4); // no warning78 return (0);79}80 81int checkNotEqualNestedBinaryOpIntPointerCompare1(void) {82 int res;83 int k = 7;84 int t= 1;85 int* u= &k+2;86 int* f= &k+3;87 res = ((f + (3)*t) != (f + (3)*t));88 return (0);89}90 91int checkNotEqualNestedBinaryOpIntPointerCompare2(void) {92 int res;93 int k = 7;94 int t= 1;95 int* u= &k+2;96 int* f= &k+3;97 res = (((3)*t + f) != (f + (3)*t)); // no warning98 return (0);99}100/* end '!=' int* */101 102/* '!=' with function*/103 104int checkNotEqualSameFunction() {105 unsigned a = 0;106 unsigned b = 1;107 int res = (a+func() != a+func()); // no warning108 return (0);109}110 111int checkNotEqualDifferentFunction() {112 unsigned a = 0;113 unsigned b = 1;114 int res = (a+func() != a+func2()); // no warning115 return (0);116}117 118int checkNotEqualSameFunctionSameParam() {119 unsigned a = 0;120 unsigned b = 1;121 int res = (a+funcParam(a) != a+funcParam(a)); // no warning122 return (0);123}124 125int checkNotEqualSameFunctionDifferentParam() {126 unsigned a = 0;127 unsigned b = 1;128 int res = (a+funcParam(a) != a+funcParam(b)); // no warning129 return (0);130}131 132/* end '!=' with function*/133 134/* end '!=' */135 136 137/* Checking use of identical expressions in conditional operator*/138 139unsigned test_unsigned(unsigned a) {140 unsigned b = 1;141 a = a > 5 ? b : b;142// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]143 return a;144}145 146void test_signed() {147 int a = 0;148 a = a > 5 ? a : a;149// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]150}151 152void test_bool(bool a) {153 a = a > 0 ? a : a;154// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]155}156 157void test_float() {158 float a = 0;159 float b = 0;160 a = a > 5 ? a : a;161// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]162}163 164const char *test_string() {165 float a = 0;166 return a > 5 ? "abc" : "abc";167// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]168}169 170void test_unsigned_expr() {171 unsigned a = 0;172 unsigned b = 0;173 a = a > 5 ? a+b : a+b;174// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]175}176 177void test_signed_expr() {178 int a = 0;179 int b = 1;180 a = a > 5 ? a+b : a+b;181// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]182}183 184void test_bool_expr(bool a) {185 bool b = 0;186 a = a > 0 ? a&&b : a&&b;187// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]188}189 190void test_unsigned_expr_negative() {191 unsigned a = 0;192 unsigned b = 0;193 a = a > 5 ? a+b : b+a; // no warning194}195 196void test_signed_expr_negative() {197 int a = 0;198 int b = 1;199 a = a > 5 ? b+a : a+b; // no warning200}201 202void test_bool_expr_negative(bool a) {203 bool b = 0;204 a = a > 0 ? a&&b : b&&a; // no warning205}206 207void test_float_expr_positive() {208 float a = 0;209 float b = 0;210 a = a > 5 ? a+b : a+b;211// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]212}213 214void test_expr_positive_func() {215 unsigned a = 0;216 unsigned b = 1;217 a = a > 5 ? a+func() : a+func();218// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]219}220 221void test_expr_negative_func() {222 unsigned a = 0;223 unsigned b = 1;224 a = a > 5 ? a+func() : a+func2(); // no warning225}226 227void test_expr_positive_funcParam() {228 unsigned a = 0;229 unsigned b = 1;230 a = a > 5 ? a+funcParam(b) : a+funcParam(b);231// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]232}233 234void test_expr_negative_funcParam() {235 unsigned a = 0;236 unsigned b = 1;237 a = a > 5 ? a+funcParam(a) : a+funcParam(b); // no warning238}239 240void test_expr_positive_inc() {241 unsigned a = 0;242 unsigned b = 1;243 a = a > 5 ? a++ : a++;244// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]245}246 247void test_expr_negative_inc() {248 unsigned a = 0;249 unsigned b = 1;250 a = a > 5 ? a++ : b++; // no warning251}252 253void test_expr_positive_assign() {254 unsigned a = 0;255 unsigned b = 1;256 a = a > 5 ? a=1 : a=1;257// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]258}259 260void test_expr_negative_assign() {261 unsigned a = 0;262 unsigned b = 1;263 a = a > 5 ? a=1 : a=2; // no warning264}265 266void test_signed_nested_expr() {267 int a = 0;268 int b = 1;269 int c = 3;270 a = a > 5 ? a+b+(c+a)*(a + b*(c+a)) : a+b+(c+a)*(a + b*(c+a));271// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]272}273 274void test_signed_nested_expr_negative() {275 int a = 0;276 int b = 1;277 int c = 3;278 a = a > 5 ? a+b+(c+a)*(a + b*(c+a)) : a+b+(c+a)*(a + b*(a+c)); // no warning279}280 281void test_signed_nested_cond_expr_negative() {282 int a = 0;283 int b = 1;284 int c = 3;285 a = a > 5 ? (b > 5 ? 1 : 4) : (b > 5 ? 2 : 4); // no warning286}287 288void test_signed_nested_cond_expr() {289 int a = 0;290 int b = 1;291 int c = 3;292 a = a > 5 ? (b > 5 ? 1 : 4) : (b > 5 ? 4 : 4);293// CHECK-MESSAGES: :[[@LINE-1]]:40: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]294}295 296void test_identical_branches1(bool b) {297 int i = 0;298 if (b) {299// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]300 ++i;301 } else {302// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here303 ++i;304 }305}306 307void test_identical_branches2(bool b) {308 int i = 0;309 if (b) {310// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]311 ++i;312 } else313// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here314 ++i;315}316 317void test_identical_branches3(bool b) {318 int i = 0;319 if (b) { // no warning320 ++i;321 } else {322 i++;323 }324}325 326void test_identical_branches4(bool b) {327 int i = 0;328 if (b) {329// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]330 } else {331// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here332 }333}334 335void test_identical_branches_break(bool b) {336 while (true) {337 if (b)338// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: if with identical then and else branches [bugprone-branch-clone]339 break;340 else341// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here342 break;343 }344}345 346void test_identical_branches_continue(bool b) {347 while (true) {348 if (b)349// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: if with identical then and else branches [bugprone-branch-clone]350 continue;351 else352// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here353 continue;354 }355}356 357void test_identical_branches_func(bool b) {358 if (b)359// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]360 func();361 else362// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here363 func();364}365 366void test_identical_branches_func_arguments(bool b) {367 if (b) // no-warning368 funcParam(1);369 else370 funcParam(2);371}372 373void test_identical_branches_cast1(bool b) {374 long v = -7;375 if (b) // no-warning376 v = (signed int) v;377 else378 v = (unsigned int) v;379}380 381void test_identical_branches_cast2(bool b) {382 long v = -7;383 if (b)384// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]385 v = (signed int) v;386 else387// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here388 v = (signed int) v;389}390 391int test_identical_branches_return_int(bool b) {392 int i = 0;393 if (b) {394// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]395 i++;396 return i;397 } else {398// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here399 i++;400 return i;401 }402}403 404int test_identical_branches_return_func(bool b) {405 if (b) {406// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]407 return func();408 } else {409// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here410 return func();411 }412}413 414void test_identical_branches_for(bool b) {415 int i;416 int j;417 if (b) {418// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]419 for (i = 0, j = 0; i < 10; i++)420 j += 4;421 } else {422// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here423 for (i = 0, j = 0; i < 10; i++)424 j += 4;425 }426}427 428void test_identical_branches_while(bool b) {429 int i = 10;430 if (b) {431// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]432 while (func())433 i--;434 } else {435// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here436 while (func())437 i--;438 }439}440 441void test_identical_branches_while_2(bool b) {442 int i = 10;443 if (b) { // no-warning444 while (func())445 i--;446 } else {447 while (func())448 i++;449 }450}451 452void test_identical_branches_do_while(bool b) {453 int i = 10;454 if (b) {455// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]456 do {457 i--;458 } while (func());459 } else {460// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here461 do {462 i--;463 } while (func());464 }465}466 467void test_identical_branches_if(bool b, int i) {468 if (b) {469// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]470 if (i < 5)471 i += 10;472 } else {473// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here474 if (i < 5)475 i += 10;476 }477}478 479void test_identical_bitwise1() {480 int a = 5 | 5; // no-warning481}482 483void test_identical_bitwise2() {484 int a = 5;485 int b = a | a; // no-warning486}487 488void test_identical_bitwise3() {489 int a = 5;490 int b = (a | a); // no-warning491}492 493void test_identical_bitwise4() {494 int a = 4;495 int b = a | 4; // no-warning496}497 498void test_identical_bitwise5() {499 int a = 4;500 int b = 4;501 int c = a | b; // no-warning502}503 504void test_identical_bitwise6() {505 int a = 5;506 int b = a | 4 | a;507}508 509void test_identical_bitwise7() {510 int a = 5;511 int b = func() | func();512}513 514void test_identical_logical1(int a) {515 if (a == 4 && a == 4)516 ;517}518 519void test_identical_logical2(int a) {520 if (a == 4 || a == 5 || a == 4)521 ;522}523 524void test_identical_logical3(int a) {525 if (a == 4 || a == 5 || a == 6) // no-warning526 ;527}528 529void test_identical_logical4(int a) {530 if (a == func() || a == func()) // no-warning531 ;532}533 534#pragma clang diagnostic push535#pragma clang diagnostic ignored "-Wlogical-op-parentheses"536void test_identical_logical5(int x, int y) {537 if (x == 4 && y == 5 || x == 4 && y == 6) // no-warning538 ;539}540 541void test_identical_logical6(int x, int y) {542 if (x == 4 && y == 5 || x == 4 && y == 5)543 ;544}545 546void test_identical_logical7(int x, int y) {547 // FIXME: We should warn here548 if (x == 4 && y == 5 || x == 4)549 ;550}551 552void test_identical_logical8(int x, int y) {553 // FIXME: We should warn here554 if (x == 4 || y == 5 && x == 4)555 ;556}557 558void test_identical_logical9(int x, int y) {559 // FIXME: We should warn here560 if (x == 4 || x == 4 && y == 5)561 ;562}563#pragma clang diagnostic pop564 565void test_warn_chained_if_stmts_1(int x) {566 if (x == 1)567 ;568// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: repeated branch body in conditional chain [bugprone-branch-clone]569// CHECK-MESSAGES: :[[@LINE-2]]:6: note: end of the original570 else if (x == 1)571 ;572// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here573}574 575void test_warn_chained_if_stmts_2(int x) {576 if (x == 1)577 ;578// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: repeated branch body in conditional chain [bugprone-branch-clone]579// CHECK-MESSAGES: :[[@LINE-2]]:6: note: end of the original580 else if (x == 1)581 ;582// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here583 else if (x == 1)584 ;585// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 2 starts here586}587 588void test_warn_chained_if_stmts_3(int x) {589 if (x == 1)590 ;591// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: repeated branch body in conditional chain [bugprone-branch-clone]592// CHECK-MESSAGES: :[[@LINE-2]]:6: note: end of the original593 else if (x == 2)594 ;595// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here596 else if (x == 1)597 ;598// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 2 starts here599}600 601void test_warn_chained_if_stmts_4(int x) {602 if (x == 1)603 ;604// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: repeated branch body in conditional chain [bugprone-branch-clone]605// CHECK-MESSAGES: :[[@LINE-2]]:6: note: end of the original606 else if (func())607 ;608// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here609 else if (x == 1)610 ;611// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 2 starts here612}613 614void test_warn_chained_if_stmts_5(int x) {615 if (x & 1)616 ;617// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: repeated branch body in conditional chain [bugprone-branch-clone]618// CHECK-MESSAGES: :[[@LINE-2]]:6: note: end of the original619 else if (x & 1)620 ;621// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here622}623 624void test_warn_chained_if_stmts_6(int x) {625 if (x == 1)626 ;627// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: repeated branch body in conditional chain [bugprone-branch-clone]628// CHECK-MESSAGES: :[[@LINE-2]]:6: note: end of the original629 else if (x == 2)630 ;631// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here632 else if (x == 2)633 ;634// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 2 starts here635 else if (x == 3)636 ;637}638 639void test_warn_chained_if_stmts_7(int x) {640 if (x == 1)641 ;642// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: repeated branch body in conditional chain [bugprone-branch-clone]643// CHECK-MESSAGES: :[[@LINE-2]]:6: note: end of the original644 else if (x == 2)645 ;646// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here647 else if (x == 3)648 ;649// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 2 starts here650 else if (x == 2)651 ;652// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 3 starts here653 else if (x == 5)654 ;655// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 4 starts here656}657 658void test_warn_chained_if_stmts_8(int x) {659 if (x == 1)660 ;661// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: repeated branch body in conditional chain [bugprone-branch-clone]662// CHECK-MESSAGES: :[[@LINE-2]]:6: note: end of the original663 else if (x == 2)664 ;665// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here666 else if (x == 3)667 ;668// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 2 starts here669 else if (x == 2)670 ;671// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 3 starts here672 else if (x == 5)673 ;674// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 4 starts here675 else if (x == 3)676 ;677// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 5 starts here678 else if (x == 7)679 ;680// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 6 starts here681}682 683void test_nowarn_chained_if_stmts_1(int x) {684 if (func())685 ;686// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: repeated branch body in conditional chain [bugprone-branch-clone]687// CHECK-MESSAGES: :[[@LINE-2]]:6: note: end of the original688 else if (func())689 ;690// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here691}692 693void test_nowarn_chained_if_stmts_2(int x) {694 if (func())695 ;696// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: repeated branch body in conditional chain [bugprone-branch-clone]697// CHECK-MESSAGES: :[[@LINE-2]]:6: note: end of the original698 else if (x == 1)699 ;700// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here701 else if (func())702 ;703// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 2 starts here704}705 706void test_nowarn_chained_if_stmts_3(int x) {707 if (x++)708 ;709// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: repeated branch body in conditional chain [bugprone-branch-clone]710// CHECK-MESSAGES: :[[@LINE-2]]:6: note: end of the original711 else if (x++)712 ;713// CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here714}715 716void test_warn_wchar() {717 const wchar_t * a = 0 ? L"Warning" : L"Warning";718// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]719}720void test_nowarn_wchar() {721 const wchar_t * a = 0 ? L"No" : L"Warning";722}723 724void test_nowarn_long() {725 int a = 0, b = 0;726 long c;727 if (0) {728 b -= a;729 c = 0;730 } else {731 b -= a;732 c = 0LL;733 }734}735 736// Identical inner conditions737 738void test_warn_inner_if_1(int x) {739 if (x == 1) {740// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical inner if statement [bugprone-branch-clone]741 if (x == 1)742// CHECK-MESSAGES: :[[@LINE-1]]:5: note: inner if starts here743 ;744 }745 746 // FIXME: Should warn here. The warning is currently not emitted because there747 // is code between the conditions.748 if (x == 1) {749 int y = x;750 if (x == 1)751 ;752 }753}754 755void test_nowarn_inner_if_1(int x) {756 // Don't warn when condition has side effects.757 if (x++ == 1) {758 if (x++ == 1)759 ;760 }761 762 // Don't warn when x is changed before inner condition.763 if (x < 10) {764 x++;765 if (x < 10)766 ;767 }768}769