xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone/branch-clone-2.cpp (revision 8e1cb96db84a70b2c803c28a359c8bb71395f35e)
1 // RUN: %check_clang_tidy %s bugprone-branch-clone %t --
2 
3 /* Only one expected warning per function allowed at the very end. */
4 
5 int func(void)
6 {
7   return 0;
8 }
9 
10 int func2(void)
11 {
12   return 0;
13 }
14 
15 int funcParam(int a)
16 {
17   return 0;
18 }
19 
20 /* '!=' operator*/
21 
22 
23 /* '!=' with int pointer */
24 
25 int checkNotEqualIntPointerLiteralCompare1(void) {
26   int* p = 0;
27   return (p != 0); // no warning
28 }
29 
30 int checkNotEqualIntPointerLiteralCompare2(void) {
31   return (6 != 7); // no warning
32 }
33 
34 int checkNotEqualIntPointerDeclCompare1(void) {
35   int k = 3;
36   int* f = &k;
37   int* g = &k;
38   return (f != g); // no warning
39 }
40 
41 int checkNotEqualCastIntPointerDeclCompare11(void) {
42   int k = 7;
43   int* f = &k;
44   return ((int*)f != (int*)f);
45 }
46 int checkNotEqualCastIntPointerDeclCompare12(void) {
47   int k = 7;
48   int* f = &k;
49   return ((int*)((char*)f) != (int*)f); // no warning
50 }
51 int checkNotEqualBinaryOpIntPointerCompare1(void) {
52   int k = 7;
53   int res;
54   int* f= &k;
55   res = (f + 4 != f + 4);
56   return (0);
57 }
58 int checkNotEqualBinaryOpIntPointerCompare2(void) {
59   int k = 7;
60   int* f = &k;
61   int* g = &k;
62   return (f + 4 != g + 4); // no warning
63 }
64 
65 
66 int 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 }
73 int checkNotEqualBinaryOpIntPointerCompare4(void) {
74   int k = 7;
75   int res;
76   int* f= &k;
77   res = ((int*)f + 4 != (int*)((char*)f) + 4);  // no warning
78   return (0);
79 }
80 
81 int 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 
91 int 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 warning
98   return (0);
99 }
100 /*   end '!=' int*          */
101 
102 /* '!=' with function*/
103 
104 int checkNotEqualSameFunction() {
105   unsigned a = 0;
106   unsigned b = 1;
107   int res = (a+func() != a+func());  // no warning
108   return (0);
109 }
110 
111 int checkNotEqualDifferentFunction() {
112   unsigned a = 0;
113   unsigned b = 1;
114   int res = (a+func() != a+func2());  // no warning
115   return (0);
116 }
117 
118 int checkNotEqualSameFunctionSameParam() {
119   unsigned a = 0;
120   unsigned b = 1;
121   int res = (a+funcParam(a) != a+funcParam(a));  // no warning
122   return (0);
123 }
124 
125 int checkNotEqualSameFunctionDifferentParam() {
126   unsigned a = 0;
127   unsigned b = 1;
128   int res = (a+funcParam(a) != a+funcParam(b));  // no warning
129   return (0);
130 }
131 
132 /*   end '!=' with function*/
133 
134 /*   end '!=' */
135 
136 
137 /* Checking use of identical expressions in conditional operator*/
138 
139 unsigned 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 
146 void 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 
152 void 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 
157 void 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 
164 const 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 
170 void 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 
177 void 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 
184 void 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 
190 void test_unsigned_expr_negative() {
191   unsigned a = 0;
192   unsigned b = 0;
193   a = a > 5 ? a+b : b+a; // no warning
194 }
195 
196 void test_signed_expr_negative() {
197   int a = 0;
198   int b = 1;
199   a = a > 5 ? b+a : a+b; // no warning
200 }
201 
202 void test_bool_expr_negative(bool a) {
203   bool b = 0;
204   a = a > 0 ? a&&b : b&&a; // no warning
205 }
206 
207 void 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 
214 void 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 
221 void test_expr_negative_func() {
222   unsigned a = 0;
223   unsigned b = 1;
224   a = a > 5 ? a+func() : a+func2(); // no warning
225 }
226 
227 void 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 
234 void test_expr_negative_funcParam() {
235   unsigned a = 0;
236   unsigned b = 1;
237   a = a > 5 ? a+funcParam(a) : a+funcParam(b); // no warning
238 }
239 
240 void 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 
247 void test_expr_negative_inc() {
248   unsigned a = 0;
249   unsigned b = 1;
250   a = a > 5 ? a++ : b++; // no warning
251 }
252 
253 void 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 
260 void test_expr_negative_assign() {
261   unsigned a = 0;
262   unsigned b = 1;
263   a = a > 5 ? a=1 : a=2; // no warning
264 }
265 
266 void 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 
274 void 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 warning
279 }
280 
281 void 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 warning
286 }
287 
288 void 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 
296 void 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 here
303     ++i;
304   }
305 }
306 
307 void 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   } else
313 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here
314     ++i;
315 }
316 
317 void test_identical_branches3(bool b) {
318   int i = 0;
319   if (b) { // no warning
320     ++i;
321   } else {
322     i++;
323   }
324 }
325 
326 void 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 here
332   }
333 }
334 
335 void 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     else
341 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here
342       break;
343   }
344 }
345 
346 void 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     else
352 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here
353       continue;
354   }
355 }
356 
357 void 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   else
362 // CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here
363     func();
364 }
365 
366 void test_identical_branches_func_arguments(bool b) {
367   if (b) // no-warning
368     funcParam(1);
369   else
370     funcParam(2);
371 }
372 
373 void test_identical_branches_cast1(bool b) {
374   long v = -7;
375   if (b) // no-warning
376     v = (signed int) v;
377   else
378     v = (unsigned int) v;
379 }
380 
381 void 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   else
387 // CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here
388     v = (signed int) v;
389 }
390 
391 int 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 here
399     i++;
400     return i;
401   }
402 }
403 
404 int 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 here
410     return func();
411   }
412 }
413 
414 void 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 here
423     for (i = 0, j = 0; i < 10; i++)
424       j += 4;
425   }
426 }
427 
428 void 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 here
436     while (func())
437       i--;
438   }
439 }
440 
441 void test_identical_branches_while_2(bool b) {
442   int i = 10;
443   if (b) { // no-warning
444     while (func())
445       i--;
446   } else {
447     while (func())
448       i++;
449   }
450 }
451 
452 void 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 here
461     do {
462       i--;
463     } while (func());
464   }
465 }
466 
467 void 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 here
474     if (i < 5)
475       i += 10;
476   }
477 }
478 
479 void test_identical_bitwise1() {
480   int a = 5 | 5; // no-warning
481 }
482 
483 void test_identical_bitwise2() {
484   int a = 5;
485   int b = a | a; // no-warning
486 }
487 
488 void test_identical_bitwise3() {
489   int a = 5;
490   int b = (a | a); // no-warning
491 }
492 
493 void test_identical_bitwise4() {
494   int a = 4;
495   int b = a | 4; // no-warning
496 }
497 
498 void test_identical_bitwise5() {
499   int a = 4;
500   int b = 4;
501   int c = a | b; // no-warning
502 }
503 
504 void test_identical_bitwise6() {
505   int a = 5;
506   int b = a | 4 | a;
507 }
508 
509 void test_identical_bitwise7() {
510   int a = 5;
511   int b = func() | func();
512 }
513 
514 void test_identical_logical1(int a) {
515   if (a == 4 && a == 4)
516     ;
517 }
518 
519 void test_identical_logical2(int a) {
520   if (a == 4 || a == 5 || a == 4)
521     ;
522 }
523 
524 void test_identical_logical3(int a) {
525   if (a == 4 || a == 5 || a == 6) // no-warning
526     ;
527 }
528 
529 void test_identical_logical4(int a) {
530   if (a == func() || a == func()) // no-warning
531     ;
532 }
533 
534 #pragma clang diagnostic push
535 #pragma clang diagnostic ignored "-Wlogical-op-parentheses"
536 void test_identical_logical5(int x, int y) {
537   if (x == 4 && y == 5 || x == 4 && y == 6) // no-warning
538     ;
539 }
540 
541 void test_identical_logical6(int x, int y) {
542   if (x == 4 && y == 5 || x == 4 && y == 5)
543     ;
544 }
545 
546 void test_identical_logical7(int x, int y) {
547   // FIXME: We should warn here
548   if (x == 4 && y == 5 || x == 4)
549     ;
550 }
551 
552 void test_identical_logical8(int x, int y) {
553   // FIXME: We should warn here
554   if (x == 4 || y == 5 && x == 4)
555     ;
556 }
557 
558 void test_identical_logical9(int x, int y) {
559   // FIXME: We should warn here
560   if (x == 4 || x == 4 && y == 5)
561     ;
562 }
563 #pragma clang diagnostic pop
564 
565 void 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 original
570   else if (x == 1)
571     ;
572 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here
573 }
574 
575 void 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 original
580   else if (x == 1)
581     ;
582 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here
583   else if (x == 1)
584     ;
585 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 2 starts here
586 }
587 
588 void 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 original
593   else if (x == 2)
594     ;
595 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here
596   else if (x == 1)
597     ;
598 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 2 starts here
599 }
600 
601 void 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 original
606   else if (func())
607     ;
608 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here
609   else if (x == 1)
610     ;
611 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 2 starts here
612 }
613 
614 void 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 original
619   else if (x & 1)
620     ;
621 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here
622 }
623 
624 void 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 original
629   else if (x == 2)
630     ;
631 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here
632   else if (x == 2)
633     ;
634 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 2 starts here
635   else if (x == 3)
636     ;
637 }
638 
639 void 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 original
644   else if (x == 2)
645     ;
646 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here
647   else if (x == 3)
648     ;
649 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 2 starts here
650   else if (x == 2)
651     ;
652 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 3 starts here
653   else if (x == 5)
654     ;
655 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 4 starts here
656 }
657 
658 void 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 original
663   else if (x == 2)
664     ;
665 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here
666   else if (x == 3)
667     ;
668 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 2 starts here
669   else if (x == 2)
670     ;
671 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 3 starts here
672   else if (x == 5)
673     ;
674 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 4 starts here
675   else if (x == 3)
676     ;
677 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 5 starts here
678   else if (x == 7)
679     ;
680 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 6 starts here
681 }
682 
683 void 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 original
688   else if (func())
689     ;
690 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here
691 }
692 
693 void 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 original
698   else if (x == 1)
699     ;
700 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here
701   else if (func())
702     ;
703 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 2 starts here
704 }
705 
706 void 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 original
711   else if (x++)
712     ;
713 // CHECK-MESSAGES: :[[@LINE-1]]:5: note: clone 1 starts here
714 }
715 
716 void 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 }
720 void test_nowarn_wchar() {
721   const wchar_t * a = 0 ? L"No" : L"Warning";
722 }
723 
724 void 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 conditions
737 
738 void 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 here
743       ;
744   }
745 
746   // FIXME: Should warn here. The warning is currently not emitted because there
747   // is code between the conditions.
748   if (x == 1) {
749     int y = x;
750     if (x == 1)
751       ;
752   }
753 }
754 
755 void 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