xref: /llvm-project/clang/test/Parser/switch-recovery.cpp (revision 0f1c1be1968076d6f96f8a7bcc4a15cf195ecd97)
1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 
3 struct A {};
4 struct B {
fooB5   void foo(int b) {
6     switch (a) { // expected-error{{use of undeclared identifier 'a'}}
7     default:
8       return;
9     }
10 
11     switch (b) {
12     case 17 // expected-error{{expected ':' after 'case'}}
13       break;
14 
15     default // expected-error{{expected ':' after 'default'}}
16       return;
17     }
18   }
19 
test2B20   void test2() {
21     enum X { Xa, Xb } x;
22 
23     switch (x) { // expected-warning {{enumeration value 'Xb' not handled in switch}}
24     case Xa; // expected-error {{expected ':' after 'case'}}
25       break;
26     }
27 
28     switch (x) {
29     default; // expected-error {{expected ':' after 'default'}}
30       break;
31     }
32   }
33 
test3B34   int test3(int i) {
35     switch (i) {
36       case 1: return 0;
37       2: return 1;  // expected-error {{expected 'case' keyword before expression}}
38       default: return 5;
39     }
40   }
41 };
42 
test4(int i)43 int test4(int i) {
44   switch (i)
45     1: return -1;  // expected-error {{expected 'case' keyword before expression}}
46   return 0;
47 }
48 
test5(int i)49 int test5(int i) {
50   switch (i) {
51     case 1: case 2: case 3: return 1;
52     {
53     4:5:6:7: return 2;  // expected-error 4{{expected 'case' keyword before expression}}
54     }
55     default: return -1;
56   }
57 }
58 
test6(int i)59 int test6(int i) {
60   switch (i) {
61     case 1:
62     case 4:
63       // This class provides extra single colon tokens.  Make sure no
64       // errors are seen here.
65       class foo{
66         public:
67         protected:
68         private:
69       };
70     case 2:
71     5:  // expected-error {{expected 'case' keyword before expression}}
72     default: return 1;
73   }
74 }
75 
test7(int i)76 int test7(int i) {
77   switch (i) {
78     case false ? 1 : 2:
79     true ? 1 : 2:  // expected-error {{expected 'case' keyword before expression}}
80     case 10:
81       14 ? 3 : 4;  // expected-warning {{expression result unused}}
82     default:
83       return 1;
84   }
85 }
86 
87 enum foo { A, B, C};
test8(foo x)88 int test8( foo x ) {
89   switch (x) {
90     A: return 0;  // FIXME: give a warning for unused labels that could also be
91                   // a case expression.
92     default: return 1;
93   }
94 }
95 
96 // Stress test to make sure Clang doesn't crash.
test9(int x)97 void test9(int x) { // expected-note {{'x' declared here}}
98   switch(x) {
99     case 1: return;
100     2: case; // expected-error {{expected 'case' keyword before expression}} \
101                 expected-error {{expected expression}}
102     4:5:6: return; // expected-error 3{{expected 'case' keyword before expression}}
103     7: :x; // expected-error {{expected 'case' keyword before expression}} \
104               expected-error {{expected expression}}
105     8:: x; // expected-error {{expected ';' after expression}} \
106               expected-error {{no member named 'x' in the global namespace; did you mean simply 'x'?}} \
107               expected-warning {{expression result unused}}
108     9:: :y; // expected-error {{expected ';' after expression}} \
109                expected-error {{expected unqualified-id}} \
110                expected-warning {{expression result unused}}
111     :; // expected-error {{expected expression}}
112     ::; // expected-error {{expected unqualified-id}}
113   }
114 }
115 
test10(int x)116 void test10(int x) {
117   switch (x) {
118     case 1: {
119       struct Inner {
120         void g(int y) {
121           2: y++;  // expected-error {{expected ';' after expression}} \
122                    // expected-warning {{expression result unused}}
123         }
124       };
125       break;
126     }
127   }
128 }
129 
130 template<typename T>
131 struct test11 {
132   enum { E };
133 
ftest11134   void f(int x) {
135     switch (x) {
136       E: break;    // FIXME: give a 'case' fix-it for unused labels that
137                    // could also be an expression an a case label.
138       E+1: break;  // expected-error {{expected 'case' keyword before expression}}
139     }
140   }
141 };
142 
test12(int x)143 void test12(int x) {
144   switch (x) {
145     0:  // expected-error {{expected 'case' keyword before expression}}
146     while (x) {
147       1:  // expected-error {{expected 'case' keyword before expression}}
148       for (;x;) {
149         2:  // expected-error {{expected 'case' keyword before expression}}
150         if (x > 0) {
151           3:  // expected-error {{expected 'case' keyword before expression}}
152           --x;
153         }
154       }
155     }
156   }
157 }
158 
missing_statement_case(int x)159 void missing_statement_case(int x) {
160   switch (x) {
161     case 1:
162     case 0:
163   } // expected-warning {{label at end of compound statement is a C++23 extension}}
164 }
165 
missing_statement_default(int x)166 void missing_statement_default(int x) {
167   switch (x) {
168     case 0:
169     default:
170   } // expected-warning {{label at end of compound statement is a C++23 extension}}
171 }
172 
pr19022_1()173 void pr19022_1() {
174   switch (int x)  // expected-error {{variable declaration in condition must have an initializer}}
175   case v: ;  // expected-error {{use of undeclared identifier 'v'}}
176 }
177 
pr19022_1a(int x)178 void pr19022_1a(int x) {
179   switch(x) {
180   case 1  // expected-error{{expected ':' after 'case'}}
181   } // expected-warning {{label at end of compound statement is a C++23 extension}}
182 }
183 
184 void pr19022_1b(int x) {
185   switch(x) {
186   case v  // expected-error{{use of undeclared identifier 'v'}} \
187           // expected-error{{expected ':' after 'case'}}
188   } // expected-error{{expected statement}}
189  }
190 
191 void pr19022_2() {
192   switch (int x)  // expected-error {{variable declaration in condition must have an initializer}}
193   case v1: case v2: ;  // expected-error {{use of undeclared identifier 'v1'}} \
194                        // expected-error {{use of undeclared identifier 'v2'}}
195 }
196 
197 void pr19022_3(int x) {
198   switch (x)
199   case 1: case v2: ;  // expected-error {{use of undeclared identifier 'v2'}}
200 }
201 
202 int pr19022_4(int x) {
203   switch(x) {
204   case 1  // expected-error{{expected ':' after 'case'}} expected-note{{previous case defined here}}
205   case 1 : return x;  // expected-error{{duplicate case value '1'}}
206   }
207 }
208 
209 void pr19022_5(int x) {
210   switch(x) {
211   case 1: case // expected-error{{expected ':' after 'case'}}
212   }  // expected-error{{expected expression}} \
213      // expected-warning {{label at end of compound statement is a C++23 extension}}
214 }
215 
216 namespace pr19022 {
217 int baz5() {}
218 bool bar0() {
219   switch (int foo0)  //expected-error{{variable declaration in condition must have an initializer}}
220   case bar5: ;  // expected-error{{use of undeclared identifier 'bar5'}}
221 }
222 }
223 
224 namespace pr21841 {
225 void fn1() {
226   switch (0)
227     switch (0  // expected-note{{to match this '('}}
228     {  // expected-error{{expected ')'}}
229     }
230 } // expected-error{{expected statement}}
231 }
232