1 // RUN: %clang_cc1 -fsyntax-only -Wextra-semi-stmt -verify %s
2 // RUN: cp %s %t
3 // RUN: %clang_cc1 -x c++ -Wextra-semi-stmt -fixit %t
4 // RUN: %clang_cc1 -x c++ -Wextra-semi-stmt -Werror %t
5 
6 #define GOODMACRO(varname) int varname
7 #define BETTERMACRO(varname) GOODMACRO(varname);
8 #define NULLMACRO(varname)
9 
10 enum MyEnum {
11   E1,
12   E2
13 };
14 
test()15 void test() {
16   ; // expected-warning {{empty expression statement has no effect; remove unnecessary ';' to silence this warning}}
17   ;
18 
19   // This removal of extra semi also consumes all the comments.
20   // clang-format: off
21   ;;;
22   // clang-format: on
23 
24   // clang-format: off
25   ;NULLMACRO(ZZ);
26   // clang-format: on
27 
28   {}; // expected-warning {{empty expression statement has no effect; remove unnecessary ';' to silence this warning}}
29 
30   {
31     ; // expected-warning {{empty expression statement has no effect; remove unnecessary ';' to silence this warning}}
32   }
33 
34   if (true) {
35     ; // expected-warning {{empty expression statement has no effect; remove unnecessary ';' to silence this warning}}
36   }
37 
38   GOODMACRO(v0); // OK
39 
40   GOODMACRO(v1;) // OK
41 
42   BETTERMACRO(v2) // OK
43 
44   BETTERMACRO(v3;) // Extra ';', but within macro expansion, so ignored.
45 
46   BETTERMACRO(v4); // expected-warning {{empty expression statement has no effect; remove unnecessary ';' to silence this warning}}
47 
48   BETTERMACRO(v5;); // expected-warning {{empty expression statement has no effect; remove unnecessary ';' to silence this warning}}
49 
50   NULLMACRO(v6) // OK
51 
52   NULLMACRO(v7); // OK. This could be either GOODMACRO() or BETTERMACRO() situation, so we can't know we can drop it.
53 
54   if (true)
55     ; // OK
56 
57   while (true)
58     ; // OK
59 
60   do
61     ; // OK
62   while (true);
63 
64   for (;;) // OK
65     ;      // OK
66 
67   MyEnum my_enum;
68   switch (my_enum) {
69   case E1:
70     // stuff
71     break;
72   case E2:; // OK
73   }
74 
75   for (;;) {
76     for (;;) {
77       goto contin_outer;
78     }
79   contin_outer:; // OK
80   }
81 }
82 
83 ;
84 
85 namespace NS {};
86 
foo(int x)87 void foo(int x) {
88   switch (x) {
89   case 0:
90     [[fallthrough]];
91   case 1:
92     return;
93   }
94 }
95 
96 [[]];
97