|  | // RUN: %check_clang_tidy %s bugprone-branch-clone %t -- -- -fno-delayed-template-parsing | 
|  |  | 
|  | void test_basic1(int in, int &out) { | 
|  | if (in > 77) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | out++; | 
|  | else | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here | 
|  | out++; | 
|  |  | 
|  | out++; | 
|  | } | 
|  |  | 
|  | void test_basic2(int in, int &out) { | 
|  | if (in > 77) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | out++; | 
|  | } | 
|  | else { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here | 
|  | out++; | 
|  | } | 
|  |  | 
|  | out++; | 
|  | } | 
|  |  | 
|  | void test_basic3(int in, int &out) { | 
|  | if (in > 77) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | out++; | 
|  | } | 
|  | else | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here | 
|  | out++; | 
|  |  | 
|  | out++; | 
|  | } | 
|  |  | 
|  | void test_basic4(int in, int &out) { | 
|  | if (in > 77) { | 
|  | out--; | 
|  | } | 
|  | else { | 
|  | out++; | 
|  | } | 
|  | } | 
|  |  | 
|  | void test_basic5(int in, int &out) { | 
|  | if (in > 77) { | 
|  | out++; | 
|  | } | 
|  | else { | 
|  | out++; | 
|  | out++; | 
|  | } | 
|  | } | 
|  |  | 
|  | void test_basic6(int in, int &out) { | 
|  | if (in > 77) { | 
|  | out++; | 
|  | } | 
|  | else { | 
|  | out++, out++; | 
|  | } | 
|  | } | 
|  |  | 
|  | void test_basic7(int in, int &out) { | 
|  | if (in > 77) { | 
|  | out++; | 
|  | out++; | 
|  | } | 
|  | else | 
|  | out++; | 
|  |  | 
|  | out++; | 
|  | } | 
|  |  | 
|  | void test_basic8(int in, int &out) { | 
|  | if (in > 77) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | out++; | 
|  | out++; | 
|  | } else { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here | 
|  | out++; | 
|  | out++; | 
|  | } | 
|  |  | 
|  | if (in % 2) | 
|  | out++; | 
|  | } | 
|  |  | 
|  | void test_basic9(int in, int &out) { | 
|  | if (in > 77) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | if (in % 2) | 
|  | out++; | 
|  | else | 
|  | out--; | 
|  | } else { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here | 
|  | if (in % 2) | 
|  | out++; | 
|  | else | 
|  | out--; | 
|  | } | 
|  | } | 
|  |  | 
|  | // If we remove the braces from the previous example, the check recognizes it | 
|  | // as an `else if`. | 
|  | void test_basic10(int in, int &out) { | 
|  | if (in > 77) | 
|  | if (in % 2) | 
|  | out++; | 
|  | else | 
|  | out--; | 
|  | else | 
|  | if (in % 2) | 
|  | out++; | 
|  | else | 
|  | out--; | 
|  |  | 
|  | } | 
|  |  | 
|  | void test_basic11(int in, int &out) { | 
|  | if (in > 77) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | if (in % 2) | 
|  | out++; | 
|  | else | 
|  | out--; | 
|  | if (in % 3) | 
|  | out++; | 
|  | else | 
|  | out--; | 
|  | } else { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here | 
|  | if (in % 2) | 
|  | out++; | 
|  | else | 
|  | out--; | 
|  | if (in % 3) | 
|  | out++; | 
|  | else | 
|  | out--; | 
|  | } | 
|  | } | 
|  |  | 
|  | void test_basic12(int in, int &out) { | 
|  | if (in > 77) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | } else { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here | 
|  | } | 
|  | } | 
|  |  | 
|  | void test_basic13(int in, int &out) { | 
|  | if (in > 77) { | 
|  | // Empty compound statement is not identical to null statement. | 
|  | } else; | 
|  | } | 
|  |  | 
|  | // We use a comparison that ignores redundant parentheses: | 
|  | void test_basic14(int in, int &out) { | 
|  | if (in > 77) | 
|  | out += 2; | 
|  | else | 
|  | (out) += (2); | 
|  | } | 
|  |  | 
|  | void test_basic15(int in, int &out) { | 
|  | if (in > 77) | 
|  | ((out += 2)); | 
|  | else | 
|  | out += 2; | 
|  | } | 
|  |  | 
|  | // ..but does not apply additional simplifications: | 
|  | void test_basic16(int in, int &out) { | 
|  | if (in > 77) | 
|  | out += 2; | 
|  | else | 
|  | out += 1 + 1; | 
|  | } | 
|  |  | 
|  | // ..and does not forget important parentheses: | 
|  | int test_basic17(int a, int b, int c, int mode) { | 
|  | if (mode>8) | 
|  | return (a + b) * c; | 
|  | else | 
|  | return a + b * c; | 
|  | } | 
|  |  | 
|  | //=========--------------------==========// | 
|  |  | 
|  | #define PASTE_CODE(x) x | 
|  |  | 
|  | void test_macro1(int in, int &out) { | 
|  | PASTE_CODE( | 
|  | if (in > 77) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | out++; | 
|  | else | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here | 
|  | out++; | 
|  | ) | 
|  |  | 
|  | out--; | 
|  | } | 
|  |  | 
|  | void test_macro2(int in, int &out) { | 
|  | PASTE_CODE( | 
|  | if (in > 77) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | out++; | 
|  | ) | 
|  | else | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here | 
|  | out++; | 
|  | } | 
|  |  | 
|  | void test_macro3(int in, int &out) { | 
|  | if (in > 77) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | out++; | 
|  | PASTE_CODE( | 
|  | else | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here | 
|  | out++; | 
|  | ) | 
|  | } | 
|  |  | 
|  | void test_macro4(int in, int &out) { | 
|  | if (in > 77) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | out++; | 
|  | else | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here | 
|  | PASTE_CODE( | 
|  | out++; | 
|  | ) | 
|  | } | 
|  |  | 
|  | void test_macro5(int in, int &out) { | 
|  | PASTE_CODE(if) (in > 77) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | out++; | 
|  | PASTE_CODE(else) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:14: note: else branch starts here | 
|  | out++; | 
|  | } | 
|  |  | 
|  | #define OTHERWISE_INCREASE else out++ | 
|  |  | 
|  | void test_macro6(int in, int &out) { | 
|  | if (in > 77) | 
|  | out++; | 
|  | // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | OTHERWISE_INCREASE; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here | 
|  | // CHECK-MESSAGES: :[[@LINE-8]]:28: note: expanded from macro 'OTHERWISE_INCREASE' | 
|  | } | 
|  |  | 
|  | #define COND_INCR(a, b, c) \ | 
|  | do {                     \ | 
|  | if ((a))               \ | 
|  | (b)++;               \ | 
|  | else                   \ | 
|  | (c)++;               \ | 
|  | } while (0) | 
|  |  | 
|  | void test_macro7(int in, int &out1, int &out2) { | 
|  | COND_INCR(in, out1, out1); | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | // CHECK-MESSAGES: :[[@LINE-9]]:5: note: expanded from macro 'COND_INCR' | 
|  | // CHECK-MESSAGES: :[[@LINE-3]]:3: note: else branch starts here | 
|  | // CHECK-MESSAGES: :[[@LINE-9]]:5: note: expanded from macro 'COND_INCR' | 
|  | } | 
|  |  | 
|  | void test_macro8(int in, int &out1, int &out2) { | 
|  | COND_INCR(in, out1, out2); | 
|  | } | 
|  |  | 
|  | void test_macro9(int in, int &out1, int &out2) { | 
|  | COND_INCR(in, out2, out2); | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | // CHECK-MESSAGES: :[[@LINE-21]]:5: note: expanded from macro 'COND_INCR' | 
|  | // CHECK-MESSAGES: :[[@LINE-3]]:3: note: else branch starts here | 
|  | // CHECK-MESSAGES: :[[@LINE-21]]:5: note: expanded from macro 'COND_INCR' | 
|  | } | 
|  |  | 
|  | #define CONCAT(a, b) a##b | 
|  |  | 
|  | void test_macro10(int in, int &out) { | 
|  | CONCAT(i, f) (in > 77) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | out++; | 
|  | CONCAT(el, se) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here | 
|  | out++; | 
|  | } | 
|  |  | 
|  | #define PROBLEM (-1) | 
|  |  | 
|  | int test_macro11(int count) { | 
|  | if (!count) | 
|  | return PROBLEM; | 
|  | else if (count == 13) | 
|  | return -1; | 
|  | else | 
|  | return count * 2; | 
|  | } | 
|  |  | 
|  | #define IF if ( | 
|  | #define THEN ) { | 
|  | #define ELSE } else { | 
|  | #define END } | 
|  |  | 
|  | void test_macro12(int in, int &out) { | 
|  | IF in > 77 THEN | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | // CHECK-MESSAGES: :[[@LINE-8]]:12: note: expanded from macro 'IF' | 
|  | out++; | 
|  | out++; | 
|  | ELSE | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here | 
|  | // CHECK-MESSAGES: :[[@LINE-11]]:16: note: expanded from macro 'ELSE' | 
|  | out++; | 
|  | out++; | 
|  | END | 
|  | } | 
|  |  | 
|  | // A hack for implementing a switch with no fallthrough: | 
|  | #define SWITCH(x) switch (x) { | 
|  | #define CASE(x) break; case (x): | 
|  | #define DEFAULT break; default: | 
|  |  | 
|  | void test_macro13(int in, int &out) { | 
|  | SWITCH(in) | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: switch has 3 consecutive identical branches [bugprone-branch-clone] | 
|  | CASE(1) | 
|  | out++; | 
|  | out++; | 
|  | CASE(2) | 
|  | out++; | 
|  | out++; | 
|  | CASE(3) | 
|  | out++; | 
|  | out++; | 
|  | // CHECK-MESSAGES: :[[@LINE-15]]:24: note: expanded from macro 'CASE' | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:9: note: last of these clones ends here | 
|  | CASE(4) | 
|  | out++; | 
|  | CASE(5) | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: switch has 2 consecutive identical branches [bugprone-branch-clone] | 
|  | CASE(6) | 
|  | out--; | 
|  | CASE(7) | 
|  | out--; | 
|  | // CHECK-MESSAGES: :[[@LINE-25]]:24: note: expanded from macro 'CASE' | 
|  | // CHECK-MESSAGES: :[[@LINE+2]]:9: note: last of these clones ends here | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: switch has 2 consecutive identical branches [bugprone-branch-clone] | 
|  | CASE(8) | 
|  | out++; | 
|  | out++; | 
|  | CASE(9) | 
|  | out++; | 
|  | out++; | 
|  | // CHECK-MESSAGES: :[[@LINE-34]]:24: note: expanded from macro 'CASE' | 
|  | // CHECK-MESSAGES: :[[@LINE+2]]:12: note: last of these clones ends here | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: switch has 2 consecutive identical branches [bugprone-branch-clone] | 
|  | DEFAULT | 
|  | out--; | 
|  | out--; | 
|  | CASE(10) | 
|  | out--; | 
|  | out--; | 
|  | // CHECK-MESSAGES: :[[@LINE-42]]:24: note: expanded from macro 'DEFAULT' | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:9: note: last of these clones ends here | 
|  | CASE(12) | 
|  | out++; | 
|  | CASE(13) | 
|  | out++; | 
|  | END | 
|  | } | 
|  |  | 
|  | //=========--------------------==========// | 
|  |  | 
|  | void test_chain1(int in, int &out) { | 
|  | if (in > 77) | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: repeated branch in conditional chain [bugprone-branch-clone] | 
|  | out++; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:10: note: end of the original | 
|  | else if (in > 55) | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 1 starts here | 
|  | out++; | 
|  |  | 
|  | out++; | 
|  | } | 
|  |  | 
|  | void test_chain2(int in, int &out) { | 
|  | if (in > 77) | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: repeated branch in conditional chain [bugprone-branch-clone] | 
|  | out++; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:10: note: end of the original | 
|  | else if (in > 55) | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 1 starts here | 
|  | out++; | 
|  | else if (in > 42) | 
|  | out--; | 
|  | else if (in > 28) | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 2 starts here | 
|  | out++; | 
|  | else if (in > 12) { | 
|  | out++; | 
|  | out *= 7; | 
|  | } else if (in > 7) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:22: note: clone 3 starts here | 
|  | out++; | 
|  | } | 
|  | } | 
|  |  | 
|  | void test_chain3(int in, int &out) { | 
|  | if (in > 77) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: repeated branch in conditional chain [bugprone-branch-clone] | 
|  | out++; | 
|  | out++; | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:4: note: end of the original | 
|  | } else if (in > 55) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:23: note: clone 1 starts here | 
|  | out++; | 
|  | out++; | 
|  | } else if (in > 42) | 
|  | out--; | 
|  | else if (in > 28) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:21: note: clone 2 starts here | 
|  | out++; | 
|  | out++; | 
|  | } else if (in > 12) { | 
|  | out++; | 
|  | out++; | 
|  | out++; | 
|  | out *= 7; | 
|  | } else if (in > 7) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:22: note: clone 3 starts here | 
|  | out++; | 
|  | out++; | 
|  | } | 
|  | } | 
|  |  | 
|  | // In this chain there are two clone families; notice that the checker | 
|  | // describes all branches of the first one before mentioning the second one. | 
|  | void test_chain4(int in, int &out) { | 
|  | if (in > 77) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: repeated branch in conditional chain [bugprone-branch-clone] | 
|  | out++; | 
|  | out++; | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:4: note: end of the original | 
|  | } else if (in > 55) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:23: note: clone 1 starts here | 
|  | // CHECK-MESSAGES: :[[@LINE+8]]:21: note: clone 2 starts here | 
|  | // CHECK-MESSAGES: :[[@LINE+15]]:22: note: clone 3 starts here | 
|  | out++; | 
|  | out++; | 
|  | } else if (in > 42) | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: repeated branch in conditional chain [bugprone-branch-clone] | 
|  | out--; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:10: note: end of the original | 
|  | else if (in > 28) { | 
|  | out++; | 
|  | out++; | 
|  | } else if (in > 12) { | 
|  | out++; | 
|  | out++; | 
|  | out++; | 
|  | out *= 7; | 
|  | } else if (in > 7) { | 
|  | out++; | 
|  | out++; | 
|  | } else if (in > -3) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:23: note: clone 1 starts here | 
|  | out--; | 
|  | } | 
|  | } | 
|  |  | 
|  | void test_chain5(int in, int &out) { | 
|  | if (in > 77) | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: repeated branch in conditional chain [bugprone-branch-clone] | 
|  | out++; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:10: note: end of the original | 
|  | else if (in > 55) | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 1 starts here | 
|  | out++; | 
|  | else if (in > 42) | 
|  | out--; | 
|  | else if (in > 28) | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 2 starts here | 
|  | out++; | 
|  | else if (in > 12) { | 
|  | out++; | 
|  | out *= 7; | 
|  | } else { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:10: note: clone 3 starts here | 
|  | out++; | 
|  | } | 
|  | } | 
|  |  | 
|  | void test_chain6(int in, int &out) { | 
|  | if (in > 77) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: repeated branch in conditional chain [bugprone-branch-clone] | 
|  | out++; | 
|  | out++; | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:4: note: end of the original | 
|  | } else if (in > 55) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:23: note: clone 1 starts here | 
|  | out++; | 
|  | out++; | 
|  | } else if (in > 42) | 
|  | out--; | 
|  | else if (in > 28) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:21: note: clone 2 starts here | 
|  | out++; | 
|  | out++; | 
|  | } else if (in > 12) { | 
|  | out++; | 
|  | out++; | 
|  | out++; | 
|  | out *= 7; | 
|  | } else { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:10: note: clone 3 starts here | 
|  | out++; | 
|  | out++; | 
|  | } | 
|  | } | 
|  |  | 
|  | void test_nested(int a, int b, int c, int &out) { | 
|  | if (a > 5) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | // CHECK-MESSAGES: :[[@LINE+27]]:5: note: else branch starts here | 
|  | if (b > 5) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: repeated branch in conditional chain [bugprone-branch-clone] | 
|  | // CHECK-MESSAGES: :[[@LINE+9]]:6: note: end of the original | 
|  | // CHECK-MESSAGES: :[[@LINE+8]]:24: note: clone 1 starts here | 
|  | // CHECK-MESSAGES: :[[@LINE+14]]:12: note: clone 2 starts here | 
|  | if (c > 5) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | out++; | 
|  | else | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here | 
|  | out++; | 
|  | } else if (b > 15) { | 
|  | if (c > 5) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | out++; | 
|  | else | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here | 
|  | out++; | 
|  | } else { | 
|  | if (c > 5) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | out++; | 
|  | else | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here | 
|  | out++; | 
|  | } | 
|  | } else { | 
|  | if (b > 5) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: repeated branch in conditional chain [bugprone-branch-clone] | 
|  | // CHECK-MESSAGES: :[[@LINE+9]]:6: note: end of the original | 
|  | // CHECK-MESSAGES: :[[@LINE+8]]:24: note: clone 1 starts here | 
|  | // CHECK-MESSAGES: :[[@LINE+14]]:12: note: clone 2 starts here | 
|  | if (c > 5) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | out++; | 
|  | else | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here | 
|  | out++; | 
|  | } else if (b > 15) { | 
|  | if (c > 5) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | out++; | 
|  | else | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here | 
|  | out++; | 
|  | } else { | 
|  | if (c > 5) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | out++; | 
|  | else | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here | 
|  | out++; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | //=========--------------------==========// | 
|  |  | 
|  | template <class T> | 
|  | void test_template_not_instantiated(const T &t) { | 
|  | int a; | 
|  | if (t) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | a++; | 
|  | else | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here | 
|  | a++; | 
|  | } | 
|  |  | 
|  | template <class T> | 
|  | void test_template_instantiated(const T &t) { | 
|  | int a; | 
|  | if (t) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | a++; | 
|  | else | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here | 
|  | a++; | 
|  | } | 
|  |  | 
|  | template void test_template_instantiated<int>(const int &t); | 
|  |  | 
|  | template <class T> | 
|  | void test_template2(T t, int a) { | 
|  | if (a) { | 
|  | T b(0); | 
|  | a += b; | 
|  | } else { | 
|  | int b(0); | 
|  | a += b; | 
|  | } | 
|  | } | 
|  |  | 
|  | template void test_template2<int>(int t, int a); | 
|  |  | 
|  | template <class T> | 
|  | void test_template3(T t, int a) { | 
|  | if (a) { | 
|  | T b(0); | 
|  | a += b; | 
|  | } else { | 
|  | int b(0); | 
|  | a += b; | 
|  | } | 
|  | } | 
|  |  | 
|  | template void test_template3<short>(short t, int a); | 
|  |  | 
|  | template <class T> | 
|  | void test_template_two_instances(T t, int &a) { | 
|  | if (a) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | a += int(t); | 
|  | } else { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here | 
|  | a += int(t); | 
|  | } | 
|  | } | 
|  |  | 
|  | template void test_template_two_instances<short>(short t, int &a); | 
|  | template void test_template_two_instances<long>(long t, int &a); | 
|  |  | 
|  | class C { | 
|  | int member; | 
|  | void inline_method(int arg) { | 
|  | if (arg) | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | member = 3; | 
|  | else | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here | 
|  | member = 3; | 
|  | } | 
|  | int other_method(); | 
|  | }; | 
|  |  | 
|  | int C::other_method() { | 
|  | if (member) { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone] | 
|  | return 8; | 
|  | } else { | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here | 
|  | return 8; | 
|  | } | 
|  | } | 
|  |  | 
|  | //=========--------------------==========// | 
|  |  | 
|  | int simple_switch(char ch) { | 
|  | switch (ch) { | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone] | 
|  | case 'a': | 
|  | return 10; | 
|  | case 'A': | 
|  | return 10; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:14: note: last of these clones ends here | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone] | 
|  | case 'b': | 
|  | return 11; | 
|  | case 'B': | 
|  | return 11; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:14: note: last of these clones ends here | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone] | 
|  | case 'c': | 
|  | return 10; | 
|  | case 'C': | 
|  | return 10; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:14: note: last of these clones ends here | 
|  | default: | 
|  | return 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | int long_sequence_switch(char ch) { | 
|  | switch (ch) { | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 7 consecutive identical branches [bugprone-branch-clone] | 
|  | case 'a': | 
|  | return 10; | 
|  | case 'A': | 
|  | return 10; | 
|  | case 'b': | 
|  | return 10; | 
|  | case 'B': | 
|  | return 10; | 
|  | case 'c': | 
|  | return 10; | 
|  | case 'C': | 
|  | return 10; | 
|  | default: | 
|  | return 10; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:14: note: last of these clones ends here | 
|  | } | 
|  | } | 
|  |  | 
|  | int nested_switch(int a, int b, int c) { | 
|  | switch (a) { | 
|  | // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: switch has 3 consecutive identical branches [bugprone-branch-clone] | 
|  | // CHECK-MESSAGES: :[[@LINE+114]]:6: note: last of these clones ends here | 
|  | case 1: | 
|  | switch (b) { | 
|  | // CHECK-MESSAGES: :[[@LINE+2]]:5: warning: switch has 3 consecutive identical branches [bugprone-branch-clone] | 
|  | // CHECK-MESSAGES: :[[@LINE+33]]:8: note: last of these clones ends here | 
|  | case 1: | 
|  | switch (c) { | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone] | 
|  | case 1: | 
|  | return 42; | 
|  | case 2: | 
|  | return 42; | 
|  | default: | 
|  | return 42; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here | 
|  | } | 
|  | case 2: | 
|  | switch (c) { | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone] | 
|  | case 1: | 
|  | return 42; | 
|  | case 2: | 
|  | return 42; | 
|  | default: | 
|  | return 42; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here | 
|  | } | 
|  | default: | 
|  | switch (c) { | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone] | 
|  | case 1: | 
|  | return 42; | 
|  | case 2: | 
|  | return 42; | 
|  | default: | 
|  | return 42; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here | 
|  | } | 
|  | } | 
|  | case 2: | 
|  | switch (b) { | 
|  | // CHECK-MESSAGES: :[[@LINE+2]]:5: warning: switch has 3 consecutive identical branches [bugprone-branch-clone] | 
|  | // CHECK-MESSAGES: :[[@LINE+33]]:8: note: last of these clones ends here | 
|  | case 1: | 
|  | switch (c) { | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone] | 
|  | case 1: | 
|  | return 42; | 
|  | case 2: | 
|  | return 42; | 
|  | default: | 
|  | return 42; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here | 
|  | } | 
|  | case 2: | 
|  | switch (c) { | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone] | 
|  | case 1: | 
|  | return 42; | 
|  | case 2: | 
|  | return 42; | 
|  | default: | 
|  | return 42; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here | 
|  | } | 
|  | default: | 
|  | switch (c) { | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone] | 
|  | case 1: | 
|  | return 42; | 
|  | case 2: | 
|  | return 42; | 
|  | default: | 
|  | return 42; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here | 
|  | } | 
|  | } | 
|  | default: | 
|  | switch (b) { | 
|  | // CHECK-MESSAGES: :[[@LINE+2]]:5: warning: switch has 3 consecutive identical branches [bugprone-branch-clone] | 
|  | // CHECK-MESSAGES: :[[@LINE+33]]:8: note: last of these clones ends here | 
|  | case 1: | 
|  | switch (c) { | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone] | 
|  | case 1: | 
|  | return 42; | 
|  | case 2: | 
|  | return 42; | 
|  | default: | 
|  | return 42; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here | 
|  | } | 
|  | case 2: | 
|  | switch (c) { | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone] | 
|  | case 1: | 
|  | return 42; | 
|  | case 2: | 
|  | return 42; | 
|  | default: | 
|  | return 42; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here | 
|  | } | 
|  | default: | 
|  | switch (c) { | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone] | 
|  | case 1: | 
|  | return 42; | 
|  | case 2: | 
|  | return 42; | 
|  | default: | 
|  | return 42; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | //=========--------------------==========// | 
|  |  | 
|  | // This should not produce warnings, as in switch statements we only report | 
|  | // identical branches when they are consecutive. Also note that a branch | 
|  | // terminated by a break is different from a branch terminated by the end of | 
|  | // the switch statement. | 
|  | int interleaved_cases(int a, int b) { | 
|  | switch (a) { | 
|  | case 3: | 
|  | case 4: | 
|  | b = 2; | 
|  | break; | 
|  | case 5: | 
|  | b = 3; | 
|  | break; | 
|  | case 6: | 
|  | b = 2; | 
|  | break; | 
|  | case 7: | 
|  | if (b % 2) { | 
|  | b++; | 
|  | } else { | 
|  | b++; | 
|  | break; | 
|  | } | 
|  | b = 2; | 
|  | break; | 
|  | case 8: | 
|  | b = 2; | 
|  | case 9: | 
|  | b = 3; | 
|  | break; | 
|  | default: | 
|  | b = 3; | 
|  | } | 
|  | return b; | 
|  | } | 
|  |  | 
|  |  | 
|  | // A case: or default: is only considered to be the start of a branch if it is a direct child of the CompoundStmt forming the body of the switch | 
|  | int buried_cases(int foo) { | 
|  | switch (foo) { | 
|  | { | 
|  | case 36: | 
|  | return 8; | 
|  | default: | 
|  | return 8; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // Here the `case 7:` is a child statement of the GotoLabelStmt, so the checker | 
|  | // thinks that it is part of the `case 9:` branch. While this result is | 
|  | // counterintuitve, mixing goto labels and switch statements in this fashion is | 
|  | // pretty rare, so it does not deserve a special case in the checker code. | 
|  | int decorated_cases(int z) { | 
|  | if (!(z % 777)) { | 
|  | goto lucky; | 
|  | } | 
|  | switch (z) { | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone] | 
|  | case 1: | 
|  | case 2: | 
|  | case 3: | 
|  | z++; | 
|  | break; | 
|  | case 4: | 
|  | case 5: | 
|  | z++; | 
|  | break; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:10: note: last of these clones ends here | 
|  | case 9: | 
|  | z++; | 
|  | break; | 
|  | lucky: | 
|  | case 7: | 
|  | z += 3; | 
|  | z *= 2; | 
|  | break; | 
|  | case 92: | 
|  | z += 3; | 
|  | z *= 2; | 
|  | break; | 
|  | default: | 
|  | z++; | 
|  | } | 
|  | return z + 92; | 
|  | } | 
|  |  | 
|  | // The child of the switch statement is not necessarily a compound statement, | 
|  | // do not crash in this unusual case. | 
|  | char no_real_body(int in, int &out) { | 
|  | switch (in) | 
|  | case 42: | 
|  | return 'A'; | 
|  |  | 
|  | if (in > 77) | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: repeated branch in conditional chain [bugprone-branch-clone] | 
|  | out++; | 
|  | // CHECK-MESSAGES: :[[@LINE-1]]:10: note: end of the original | 
|  | else if (in > 55) | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 1 starts here | 
|  | out++; | 
|  | else if (in > 34) | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 2 starts here | 
|  | out++; | 
|  |  | 
|  | return '|'; | 
|  | } | 
|  |  | 
|  | // Duff's device [https://en.wikipedia.org/wiki/Duff's_device] | 
|  | // The check does not try to distinguish branches in this sort of convoluted | 
|  | // code, but it should avoid crashing. | 
|  | void send(short *to, short *from, int count) | 
|  | { | 
|  | int n = (count + 7) / 8; | 
|  | switch (count % 8) { | 
|  | case 0: do { *to = *from++; | 
|  | case 7:      *to = *from++; | 
|  | case 6:      *to = *from++; | 
|  | case 5:      *to = *from++; | 
|  | case 4:      *to = *from++; | 
|  | case 3:      *to = *from++; | 
|  | case 2:      *to = *from++; | 
|  | case 1:      *to = *from++; | 
|  | } while (--n > 0); | 
|  | } | 
|  | } | 
|  |  | 
|  | //=========--------------------==========// | 
|  |  | 
|  | void ternary1(bool b, int &x) { | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:6: warning: conditional operator with identical true and false expressions [bugprone-branch-clone] | 
|  | (b ? x : x) = 42; | 
|  | } | 
|  |  | 
|  | int ternary2(bool b, int x) { | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:12: warning: conditional operator with identical true and false expressions [bugprone-branch-clone] | 
|  | return b ? 42 : 42; | 
|  | } | 
|  |  | 
|  | int ternary3(bool b, int x) { | 
|  | return b ? 42 : 43; | 
|  | } | 
|  |  | 
|  | int ternary4(bool b, int x) { | 
|  | return b ? true ? 45 : 44 : false ? 45 : 44; | 
|  | } | 
|  |  | 
|  | // We do not detect chains of conditional operators. | 
|  | int ternary5(bool b1, bool b2, int x) { | 
|  | return b1 ? 42 : b2 ? 43 : 42; | 
|  | } | 
|  |  | 
|  | #define SWITCH_WITH_LBRACE(b) switch (b) { | 
|  | #define SEMICOLON_CASE_COLON(b)                                                \ | 
|  | ;                                                                            \ | 
|  | case b: | 
|  | int d, e; | 
|  | void dontCrash() { | 
|  | SWITCH_WITH_LBRACE(d) | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone] | 
|  | SEMICOLON_CASE_COLON(1) | 
|  | e++; | 
|  | e++; | 
|  | SEMICOLON_CASE_COLON(2) | 
|  | e++; | 
|  | e++; | 
|  | // CHECK-MESSAGES: :[[@LINE-11]]:3: note: expanded from macro 'SEMICOLON_CASE_COLON' | 
|  | // CHECK-MESSAGES: :[[@LINE+1]]:23: note: last of these clones ends here | 
|  | SEMICOLON_CASE_COLON(3); | 
|  | } | 
|  | } |