brintos

brintos / llvm-project-archived public Read only

0
0
Text · 27.3 KiB · 4223174 Raw
1072 lines · cpp
1// RUN: %check_clang_tidy %s bugprone-branch-clone %t -- -- -fno-delayed-template-parsing2 3void test_basic1(int in, int &out) {4  if (in > 77)5// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]6    out++;7  else8// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here9    out++;10 11  out++;12}13 14void test_basic2(int in, int &out) {15  if (in > 77) {16// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]17    out++;18  }19  else {20// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here21    out++;22  }23 24  out++;25}26 27void test_basic3(int in, int &out) {28  if (in > 77) {29// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]30    out++;31  }32  else33// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here34    out++;35 36  out++;37}38 39void test_basic4(int in, int &out) {40  if (in > 77) {41    out--;42  }43  else {44    out++;45  }46}47 48void test_basic5(int in, int &out) {49  if (in > 77) {50    out++;51  }52  else {53    out++;54    out++;55  }56}57 58void test_basic6(int in, int &out) {59  if (in > 77) {60    out++;61  }62  else {63    out++, out++;64  }65}66 67void test_basic7(int in, int &out) {68  if (in > 77) {69    out++;70    out++;71  }72  else73    out++;74 75  out++;76}77 78void test_basic8(int in, int &out) {79  if (in > 77) {80// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]81    out++;82    out++;83  } else {84// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here85    out++;86    out++;87  }88 89  if (in % 2)90    out++;91}92 93void test_basic9(int in, int &out) {94  if (in > 77) {95// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]96    if (in % 2)97      out++;98    else99      out--;100  } else {101// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here102    if (in % 2)103      out++;104    else105      out--;106  }107}108 109// If we remove the braces from the previous example, the check recognizes it110// as an `else if`.111void test_basic10(int in, int &out) {112  if (in > 77)113    if (in % 2)114      out++;115    else116      out--;117  else118    if (in % 2)119      out++;120    else121      out--;122 123}124 125void test_basic11(int in, int &out) {126  if (in > 77) {127// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]128    if (in % 2)129      out++;130    else131      out--;132    if (in % 3)133      out++;134    else135      out--;136  } else {137// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here138    if (in % 2)139      out++;140    else141      out--;142    if (in % 3)143      out++;144    else145      out--;146  }147}148 149void test_basic12(int in, int &out) {150  if (in > 77) {151// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]152  } else {153// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here154  }155}156 157void test_basic13(int in, int &out) {158  if (in > 77) {159    // Empty compound statement is not identical to null statement.160  } else;161}162 163// We use a comparison that ignores redundant parentheses:164void test_basic14(int in, int &out) {165  if (in > 77)166    out += 2;167  else168    (out) += (2);169}170 171void test_basic15(int in, int &out) {172  if (in > 77)173    ((out += 2));174  else175    out += 2;176}177 178// ..but does not apply additional simplifications:179void test_basic16(int in, int &out) {180  if (in > 77)181    out += 2;182  else183    out += 1 + 1;184}185 186// ..and does not forget important parentheses:187int test_basic17(int a, int b, int c, int mode) {188  if (mode>8)189    return (a + b) * c;190  else191    return a + b * c;192}193 194//=========--------------------==========//195 196#define PASTE_CODE(x) x197 198void test_macro1(int in, int &out) {199  PASTE_CODE(200    if (in > 77)201// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: if with identical then and else branches [bugprone-branch-clone]202      out++;203    else204// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here205      out++;206  )207 208  out--;209}210 211void test_macro2(int in, int &out) {212  PASTE_CODE(213    if (in > 77)214// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: if with identical then and else branches [bugprone-branch-clone]215      out++;216  )217  else218// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here219    out++;220}221 222void test_macro3(int in, int &out) {223  if (in > 77)224// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]225    out++;226  PASTE_CODE(227    else228// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here229      out++;230  )231}232 233void test_macro4(int in, int &out) {234  if (in > 77)235// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]236    out++;237  else238// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here239    PASTE_CODE(240      out++;241    )242}243 244void test_macro5(int in, int &out) {245  PASTE_CODE(if) (in > 77)246// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: if with identical then and else branches [bugprone-branch-clone]247    out++;248  PASTE_CODE(else)249// CHECK-MESSAGES: :[[@LINE-1]]:14: note: else branch starts here250    out++;251}252 253#define OTHERWISE_INCREASE else out++254 255void test_macro6(int in, int &out) {256  if (in > 77)257      out++;258// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: if with identical then and else branches [bugprone-branch-clone]259  OTHERWISE_INCREASE;260// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here261// CHECK-MESSAGES: :[[@LINE-8]]:28: note: expanded from macro 'OTHERWISE_INCREASE'262}263 264#define COND_INCR(a, b, c) \265  do {                     \266    if ((a))               \267      (b)++;               \268    else                   \269      (c)++;               \270  } while (0)271 272void test_macro7(int in, int &out1, int &out2) {273  COND_INCR(in, out1, out1);274// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]275// CHECK-MESSAGES: :[[@LINE-9]]:5: note: expanded from macro 'COND_INCR'276// CHECK-MESSAGES: :[[@LINE-3]]:3: note: else branch starts here277// CHECK-MESSAGES: :[[@LINE-9]]:5: note: expanded from macro 'COND_INCR'278}279 280void test_macro8(int in, int &out1, int &out2) {281  COND_INCR(in, out1, out2);282}283 284void test_macro9(int in, int &out1, int &out2) {285  COND_INCR(in, out2, out2);286// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]287// CHECK-MESSAGES: :[[@LINE-21]]:5: note: expanded from macro 'COND_INCR'288// CHECK-MESSAGES: :[[@LINE-3]]:3: note: else branch starts here289// CHECK-MESSAGES: :[[@LINE-21]]:5: note: expanded from macro 'COND_INCR'290}291 292#define CONCAT(a, b) a##b293 294void test_macro10(int in, int &out) {295  CONCAT(i, f) (in > 77)296// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]297    out++;298  CONCAT(el, se)299// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here300    out++;301}302 303#define PROBLEM (-1)304 305int test_macro11(int count) {306  if (!count)307    return PROBLEM;308  else if (count == 13)309    return -1;310  else311    return count * 2;312}313 314#define IF if (315#define THEN ) {316#define ELSE } else {317#define END }318 319void test_macro12(int in, int &out) {320  IF in > 77 THEN321// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]322// CHECK-MESSAGES: :[[@LINE-8]]:12: note: expanded from macro 'IF'323    out++;324    out++;325  ELSE326// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here327// CHECK-MESSAGES: :[[@LINE-11]]:16: note: expanded from macro 'ELSE'328    out++;329    out++;330  END331}332 333// A hack for implementing a switch with no fallthrough:334#define SWITCH(x) switch (x) {335#define CASE(x) break; case (x):336#define DEFAULT break; default:337 338void test_macro13(int in, int &out) {339  SWITCH(in)340// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]341    CASE(1)342      out++;343      out++;344    CASE(2)345      out++;346      out++;347    CASE(3)348      out++;349      out++;350// CHECK-MESSAGES: :[[@LINE-15]]:24: note: expanded from macro 'CASE'351// CHECK-MESSAGES: :[[@LINE+1]]:9: note: last of these clones ends here352    CASE(4)353      out++;354    CASE(5)355// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: switch has 2 consecutive identical branches [bugprone-branch-clone]356    CASE(6)357      out--;358    CASE(7)359      out--;360// CHECK-MESSAGES: :[[@LINE-25]]:24: note: expanded from macro 'CASE'361// CHECK-MESSAGES: :[[@LINE+2]]:9: note: last of these clones ends here362// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: switch has 2 consecutive identical branches [bugprone-branch-clone]363    CASE(8)364      out++;365      out++;366    CASE(9)367      out++;368      out++;369// CHECK-MESSAGES: :[[@LINE-34]]:24: note: expanded from macro 'CASE'370// CHECK-MESSAGES: :[[@LINE+2]]:12: note: last of these clones ends here371// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: switch has 2 consecutive identical branches [bugprone-branch-clone]372    DEFAULT373      out--;374      out--;375    CASE(10)376      out--;377      out--;378// CHECK-MESSAGES: :[[@LINE-42]]:24: note: expanded from macro 'DEFAULT'379// CHECK-MESSAGES: :[[@LINE+1]]:9: note: last of these clones ends here380    CASE(12)381      out++;382    CASE(13)383      out++;384  END385}386 387//=========--------------------==========//388 389void test_chain1(int in, int &out) {390  if (in > 77)391// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: repeated branch body in conditional chain [bugprone-branch-clone]392    out++;393// CHECK-MESSAGES: :[[@LINE-1]]:10: note: end of the original394  else if (in > 55)395// CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 1 starts here396    out++;397 398  out++;399}400 401void test_chain2(int in, int &out) {402  if (in > 77)403// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: repeated branch body in conditional chain [bugprone-branch-clone]404    out++;405// CHECK-MESSAGES: :[[@LINE-1]]:10: note: end of the original406  else if (in > 55)407// CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 1 starts here408    out++;409  else if (in > 42)410    out--;411  else if (in > 28)412// CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 2 starts here413    out++;414  else if (in > 12) {415    out++;416    out *= 7;417  } else if (in > 7) {418// CHECK-MESSAGES: :[[@LINE-1]]:22: note: clone 3 starts here419    out++;420  }421}422 423void test_chain3(int in, int &out) {424  if (in > 77) {425// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: repeated branch body in conditional chain [bugprone-branch-clone]426    out++;427    out++;428// CHECK-MESSAGES: :[[@LINE+1]]:4: note: end of the original429  } else if (in > 55) {430// CHECK-MESSAGES: :[[@LINE-1]]:23: note: clone 1 starts here431    out++;432    out++;433  } else if (in > 42)434    out--;435  else if (in > 28) {436// CHECK-MESSAGES: :[[@LINE-1]]:21: note: clone 2 starts here437    out++;438    out++;439  } else if (in > 12) {440    out++;441    out++;442    out++;443    out *= 7;444  } else if (in > 7) {445// CHECK-MESSAGES: :[[@LINE-1]]:22: note: clone 3 starts here446    out++;447    out++;448  }449}450 451// In this chain there are two clone families; notice that the checker452// describes all branches of the first one before mentioning the second one.453void test_chain4(int in, int &out) {454  if (in > 77) {455// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: repeated branch body in conditional chain [bugprone-branch-clone]456    out++;457    out++;458// CHECK-MESSAGES: :[[@LINE+1]]:4: note: end of the original459  } else if (in > 55) {460// CHECK-MESSAGES: :[[@LINE-1]]:23: note: clone 1 starts here461// CHECK-MESSAGES: :[[@LINE+8]]:21: note: clone 2 starts here462// CHECK-MESSAGES: :[[@LINE+15]]:22: note: clone 3 starts here463    out++;464    out++;465  } else if (in > 42)466// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: repeated branch body in conditional chain [bugprone-branch-clone]467    out--;468// CHECK-MESSAGES: :[[@LINE-1]]:10: note: end of the original469  else if (in > 28) {470    out++;471    out++;472  } else if (in > 12) {473    out++;474    out++;475    out++;476    out *= 7;477  } else if (in > 7) {478    out++;479    out++;480  } else if (in > -3) {481// CHECK-MESSAGES: :[[@LINE-1]]:23: note: clone 1 starts here482    out--;483  }484}485 486void test_chain5(int in, int &out) {487  if (in > 77)488// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: repeated branch body in conditional chain [bugprone-branch-clone]489    out++;490// CHECK-MESSAGES: :[[@LINE-1]]:10: note: end of the original491  else if (in > 55)492// CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 1 starts here493    out++;494  else if (in > 42)495    out--;496  else if (in > 28)497// CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 2 starts here498    out++;499  else if (in > 12) {500    out++;501    out *= 7;502  } else {503// CHECK-MESSAGES: :[[@LINE-1]]:10: note: clone 3 starts here504    out++;505  }506}507 508void test_chain6(int in, int &out) {509  if (in > 77) {510// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: repeated branch body in conditional chain [bugprone-branch-clone]511    out++;512    out++;513// CHECK-MESSAGES: :[[@LINE+1]]:4: note: end of the original514  } else if (in > 55) {515// CHECK-MESSAGES: :[[@LINE-1]]:23: note: clone 1 starts here516    out++;517    out++;518  } else if (in > 42)519    out--;520  else if (in > 28) {521// CHECK-MESSAGES: :[[@LINE-1]]:21: note: clone 2 starts here522    out++;523    out++;524  } else if (in > 12) {525    out++;526    out++;527    out++;528    out *= 7;529  } else {530// CHECK-MESSAGES: :[[@LINE-1]]:10: note: clone 3 starts here531    out++;532    out++;533  }534}535 536void test_nested(int a, int b, int c, int &out) {537  if (a > 5) {538// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]539// CHECK-MESSAGES: :[[@LINE+27]]:5: note: else branch starts here540    if (b > 5) {541// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: repeated branch body in conditional chain [bugprone-branch-clone]542// CHECK-MESSAGES: :[[@LINE+9]]:6: note: end of the original543// CHECK-MESSAGES: :[[@LINE+8]]:24: note: clone 1 starts here544// CHECK-MESSAGES: :[[@LINE+14]]:12: note: clone 2 starts here545      if (c > 5)546// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone]547        out++;548      else549// CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here550        out++;551    } else if (b > 15) {552      if (c > 5)553// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone]554        out++;555      else556// CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here557        out++;558    } else {559      if (c > 5)560// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone]561        out++;562      else563// CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here564        out++;565    }566  } else {567    if (b > 5) {568// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: repeated branch body in conditional chain [bugprone-branch-clone]569// CHECK-MESSAGES: :[[@LINE+9]]:6: note: end of the original570// CHECK-MESSAGES: :[[@LINE+8]]:24: note: clone 1 starts here571// CHECK-MESSAGES: :[[@LINE+14]]:12: note: clone 2 starts here572      if (c > 5)573// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone]574        out++;575      else576// CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here577        out++;578    } else if (b > 15) {579      if (c > 5)580// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone]581        out++;582      else583// CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here584        out++;585    } else {586      if (c > 5)587// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone]588        out++;589      else590// CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here591        out++;592    }593  }594}595 596//=========--------------------==========//597 598template <class T>599void test_template_not_instantiated(const T &t) {600  int a;601  if (t)602// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]603    a++;604  else605// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here606    a++;607}608 609template <class T>610void test_template_instantiated(const T &t) {611  int a;612  if (t)613// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]614    a++;615  else616// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here617    a++;618}619 620template void test_template_instantiated<int>(const int &t);621 622template <class T>623void test_template2(T t, int a) {624  if (a) {625    T b(0);626    a += b;627  } else {628    int b(0);629    a += b;630  }631}632 633template void test_template2<int>(int t, int a);634 635template <class T>636void test_template3(T t, int a) {637  if (a) {638    T b(0);639    a += b;640  } else {641    int b(0);642    a += b;643  }644}645 646template void test_template3<short>(short t, int a);647 648template <class T>649void test_template_two_instances(T t, int &a) {650  if (a) {651// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]652    a += int(t);653  } else {654// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here655    a += int(t);656  }657}658 659template void test_template_two_instances<short>(short t, int &a);660template void test_template_two_instances<long>(long t, int &a);661 662class C {663  int member;664  void inline_method(int arg) {665    if (arg)666// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: if with identical then and else branches [bugprone-branch-clone]667      member = 3;668    else669// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here670      member = 3;671  }672  int other_method();673};674 675int C::other_method() {676  if (member) {677// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]678    return 8;679  } else {680// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here681    return 8;682  }683}684 685//=========--------------------==========//686 687int simple_switch(char ch) {688  switch (ch) {689// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone]690  case 'a':691    return 10;692  case 'A':693    return 10;694// CHECK-MESSAGES: :[[@LINE-1]]:14: note: last of these clones ends here695// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone]696  case 'b':697    return 11;698  case 'B':699    return 11;700// CHECK-MESSAGES: :[[@LINE-1]]:14: note: last of these clones ends here701// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone]702  case 'c':703    return 10;704  case 'C':705    return 10;706// CHECK-MESSAGES: :[[@LINE-1]]:14: note: last of these clones ends here707  default:708    return 0;709  }710}711 712int long_sequence_switch(char ch) {713  switch (ch) {714// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 7 consecutive identical branches [bugprone-branch-clone]715  case 'a':716    return 10;717  case 'A':718    return 10;719  case 'b':720    return 10;721  case 'B':722    return 10;723  case 'c':724    return 10;725  case 'C':726    return 10;727  default:728    return 10;729// CHECK-MESSAGES: :[[@LINE-1]]:14: note: last of these clones ends here730  }731}732 733int nested_switch(int a, int b, int c) {734  switch (a) {735// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]736// CHECK-MESSAGES: :[[@LINE+114]]:6: note: last of these clones ends here737  case 1:738    switch (b) {739// CHECK-MESSAGES: :[[@LINE+2]]:5: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]740// CHECK-MESSAGES: :[[@LINE+33]]:8: note: last of these clones ends here741    case 1:742      switch (c) {743// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]744      case 1:745        return 42;746      case 2:747        return 42;748      default:749        return 42;750// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here751      }752    case 2:753      switch (c) {754// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]755      case 1:756        return 42;757      case 2:758        return 42;759      default:760        return 42;761// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here762      }763    default:764      switch (c) {765// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]766      case 1:767        return 42;768      case 2:769        return 42;770      default:771        return 42;772// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here773      }774    }775  case 2:776    switch (b) {777// CHECK-MESSAGES: :[[@LINE+2]]:5: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]778// CHECK-MESSAGES: :[[@LINE+33]]:8: note: last of these clones ends here779    case 1:780      switch (c) {781// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]782      case 1:783        return 42;784      case 2:785        return 42;786      default:787        return 42;788// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here789      }790    case 2:791      switch (c) {792// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]793      case 1:794        return 42;795      case 2:796        return 42;797      default:798        return 42;799// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here800      }801    default:802      switch (c) {803// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]804      case 1:805        return 42;806      case 2:807        return 42;808      default:809        return 42;810// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here811      }812    }813  default:814    switch (b) {815// CHECK-MESSAGES: :[[@LINE+2]]:5: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]816// CHECK-MESSAGES: :[[@LINE+33]]:8: note: last of these clones ends here817    case 1:818      switch (c) {819// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]820      case 1:821        return 42;822      case 2:823        return 42;824      default:825        return 42;826// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here827      }828    case 2:829      switch (c) {830// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]831      case 1:832        return 42;833      case 2:834        return 42;835      default:836        return 42;837// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here838      }839    default:840      switch (c) {841// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]842      case 1:843        return 42;844      case 2:845        return 42;846      default:847        return 42;848// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here849      }850    }851  }852}853 854//=========--------------------==========//855 856// This should not produce warnings, as in switch statements we only report857// identical branches when they are consecutive. Also note that a branch858// terminated by a break is different from a branch terminated by the end of859// the switch statement.860int interleaved_cases(int a, int b) {861  switch (a) {862  case 3:863  case 4:864    b = 2;865    break;866  case 5:867    b = 3;868    break;869  case 6:870    b = 2;871    break;872  case 7:873    if (b % 2) {874      b++;875    } else {876      b++;877      break;878    }879    b = 2;880    break;881  case 8:882    b = 2;883  case 9:884    b = 3;885    break;886  default:887    b = 3;888  }889  return b;890}891 892 893// 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 switch894int buried_cases(int foo) {895  switch (foo) {896    {897    case 36:898      return 8;899    default:900      return 8;901    }902  }903}904 905// Here the `case 7:` is a child statement of the GotoLabelStmt, so the checker906// thinks that it is part of the `case 9:` branch. While this result is907// counterintuitve, mixing goto labels and switch statements in this fashion is908// pretty rare, so it does not deserve a special case in the checker code.909int decorated_cases(int z) {910  if (!(z % 777)) {911    goto lucky;912  }913  switch (z) {914// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone]915  case 1:916  case 2:917  case 3:918    z++;919    break;920  case 4:921  case 5:922    z++;923    break;924// CHECK-MESSAGES: :[[@LINE-1]]:10: note: last of these clones ends here925  case 9:926    z++;927    break;928  lucky:929  case 7:930    z += 3;931    z *= 2;932    break;933  case 92:934    z += 3;935    z *= 2;936    break;937  default:938    z++;939  }940  return z + 92;941}942 943// The child of the switch statement is not necessarily a compound statement,944// do not crash in this unusual case.945char no_real_body(int in, int &out) {946  switch (in)947  case 42:948    return 'A';949 950  if (in > 77)951// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: repeated branch body in conditional chain [bugprone-branch-clone]952    out++;953// CHECK-MESSAGES: :[[@LINE-1]]:10: note: end of the original954  else if (in > 55)955// CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 1 starts here956    out++;957  else if (in > 34)958// CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 2 starts here959    out++;960 961  return '|';962}963 964// Duff's device [https://en.wikipedia.org/wiki/Duff's_device]965// The check does not try to distinguish branches in this sort of convoluted966// code, but it should avoid crashing.967void send(short *to, short *from, int count)968{969    int n = (count + 7) / 8;970    switch (count % 8) {971    case 0: do { *to = *from++;972    case 7:      *to = *from++;973    case 6:      *to = *from++;974    case 5:      *to = *from++;975    case 4:      *to = *from++;976    case 3:      *to = *from++;977    case 2:      *to = *from++;978    case 1:      *to = *from++;979            } while (--n > 0);980    }981}982 983//=========--------------------==========//984 985void ternary1(bool b, int &x) {986// CHECK-MESSAGES: :[[@LINE+1]]:6: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]987  (b ? x : x) = 42;988}989 990int ternary2(bool b, int x) {991// CHECK-MESSAGES: :[[@LINE+1]]:12: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]992  return b ? 42 : 42;993}994 995int ternary3(bool b, int x) {996  return b ? 42 : 43;997}998 999int ternary4(bool b, int x) {1000  return b ? true ? 45 : 44 : false ? 45 : 44;1001}1002 1003// We do not detect chains of conditional operators.1004int ternary5(bool b1, bool b2, int x) {1005  return b1 ? 42 : b2 ? 43 : 42;1006}1007 1008#define SWITCH_WITH_LBRACE(b) switch (b) {1009#define SEMICOLON_CASE_COLON(b)                                                \1010  ;                                                                            \1011  case b:1012int d, e;1013void dontCrash() {1014  SWITCH_WITH_LBRACE(d)1015// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone]1016  SEMICOLON_CASE_COLON(1)1017    e++;1018    e++;1019  SEMICOLON_CASE_COLON(2)1020    e++;1021    e++;1022  // CHECK-MESSAGES: :[[@LINE-11]]:3: note: expanded from macro 'SEMICOLON_CASE_COLON'1023  // CHECK-MESSAGES: :[[@LINE+1]]:23: note: last of these clones ends here1024  SEMICOLON_CASE_COLON(3);1025  }1026}1027 1028namespace PR62693 {1029  class Object {1030    public:1031      template <typename T>1032        bool ConvertableTo() const;1033 1034      template <typename T>1035        void Handle();1036  };1037 1038  template <typename T>1039  void update(Object &a) {1040    if (a.ConvertableTo<char *>()) {1041      a.Handle<char *>();1042    } else {1043      a.Handle<T>();1044    }1045  }1046 1047  template <typename T>1048  void update2(Object &a) {1049    if (a.ConvertableTo<char *>()) {1050      a.Handle<char *>();1051    } else {1052      a.Handle<T>();1053    }1054  }1055 1056  void foo(Object &a) {1057    update<int>(a);1058    update2<char *>(a);1059  }1060 1061  template <typename T>1062  int branch_clone_in_template(T t) {1063    // CHECK-MESSAGES: :[[@LINE+2]]:5: warning: if with identical then and else branches [bugprone-branch-clone]1064    // CHECK-MESSAGES: :[[@LINE+3]]:7: note: else branch starts here1065    if (t) {1066      return 42;1067    } else {1068      return 42;1069    }1070  }1071}1072