1 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fcxx-exceptions %s -Wno-unreachable-code
2 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fcxx-exceptions -std=gnu++11 %s -Wno-unreachable-code
3
4 namespace test0 {
5 struct D { ~D(); };
6
f(bool b)7 int f(bool b) {
8 if (b) {
9 D d;
10 goto end;
11 }
12
13 end:
14 return 1;
15 }
16 }
17
18 namespace test1 {
19 struct C { C(); };
20
f(bool b)21 int f(bool b) {
22 if (b)
23 goto foo; // expected-error {{goto into protected scope}}
24 C c; // expected-note {{jump bypasses variable initialization}}
25 foo:
26 return 1;
27 }
28 }
29
30 namespace test2 {
31 struct C { C(); };
32
f(void ** ip)33 int f(void **ip) {
34 static void *ips[] = { &&lbl1, &&lbl2 };
35
36 C c;
37 goto *ip;
38 lbl1:
39 return 0;
40 lbl2:
41 return 1;
42 }
43 }
44
45 namespace test3 {
46 struct C { C(); };
47
f(void ** ip)48 int f(void **ip) {
49 static void *ips[] = { &&lbl1, &&lbl2 };
50
51 goto *ip;
52 lbl1: {
53 C c;
54 return 0;
55 }
56 lbl2:
57 return 1;
58 }
59 }
60
61 namespace test4 {
62 struct C { C(); };
63 struct D { ~D(); };
64
f(void ** ip)65 int f(void **ip) {
66 static void *ips[] = { &&lbl1, &&lbl2 };
67
68 C c0;
69
70 goto *ip; // expected-error {{indirect goto might cross protected scopes}}
71 C c1; // expected-note {{jump bypasses variable initialization}}
72 lbl1: // expected-note {{possible target of indirect goto}}
73 return 0;
74 lbl2:
75 return 1;
76 }
77 }
78
79 namespace test5 {
80 struct C { C(); };
81 struct D { ~D(); };
82
f(void ** ip)83 int f(void **ip) {
84 static void *ips[] = { &&lbl1, &&lbl2 };
85 C c0;
86
87 goto *ip;
88 lbl1: // expected-note {{possible target of indirect goto}}
89 return 0;
90 lbl2:
91 if (ip[1]) {
92 D d; // expected-note {{jump exits scope of variable with non-trivial destructor}}
93 ip += 2;
94 goto *ip; // expected-error {{indirect goto might cross protected scopes}}
95 }
96 return 1;
97 }
98 }
99
100 namespace test6 {
101 struct C { C(); };
102
f(unsigned s0,unsigned s1,void ** ip)103 unsigned f(unsigned s0, unsigned s1, void **ip) {
104 static void *ips[] = { &&lbl1, &&lbl2, &&lbl3, &&lbl4 };
105 C c0;
106
107 goto *ip;
108 lbl1:
109 s0++;
110 goto *++ip;
111 lbl2:
112 s0 -= s1;
113 goto *++ip;
114 lbl3: {
115 unsigned tmp = s0;
116 s0 = s1;
117 s1 = tmp;
118 goto *++ip;
119 }
120 lbl4:
121 return s0;
122 }
123 }
124
125 // C++0x says it's okay to skip non-trivial initializers on static
126 // locals, and we implement that in '03 as well.
127 namespace test7 {
128 struct C { C(); };
129
test()130 void test() {
131 goto foo;
132 static C c;
133 foo:
134 return;
135 }
136 }
137
138 // PR7789
139 namespace test8 {
test1(int c)140 void test1(int c) {
141 switch (c) {
142 case 0:
143 int x = 56; // expected-note {{jump bypasses variable initialization}}
144 case 1: // expected-error {{switch case is in protected scope}}
145 x = 10;
146 }
147 }
148
test2()149 void test2() {
150 goto l2; // expected-error {{goto into protected scope}}
151 l1: int x = 5; // expected-note {{jump bypasses variable initialization}}
152 l2: x++;
153 }
154 }
155
156 namespace test9 {
157 struct S { int i; };
test1()158 void test1() {
159 goto foo;
160 S s;
161 foo:
162 return;
163 }
test2(unsigned x,unsigned y)164 unsigned test2(unsigned x, unsigned y) {
165 switch (x) {
166 case 2:
167 S s;
168 if (y > 42) return x + y;
169 default:
170 return x - 2;
171 }
172 }
173 }
174
175 // http://llvm.org/PR10462
176 namespace PR10462 {
177 enum MyEnum {
178 something_valid,
179 something_invalid
180 };
181
recurse()182 bool recurse() {
183 MyEnum K;
184 switch (K) { // expected-warning {{enumeration value 'something_invalid' not handled in switch}}
185 case something_valid:
186 case what_am_i_thinking: // expected-error {{use of undeclared identifier}}
187 int *X = 0;
188 if (recurse()) {
189 }
190
191 break;
192 }
193 }
194 }
195
196 namespace test10 {
test()197 int test() {
198 static void *ps[] = { &&a0 };
199 goto *&&a0; // expected-error {{goto into protected scope}}
200 int a = 3; // expected-note {{jump bypasses variable initialization}}
201 a0:
202 return 0;
203 }
204 }
205
206 // pr13812
207 namespace test11 {
208 struct C {
209 C(int x);
210 ~C();
211 };
f(void ** ip)212 void f(void **ip) {
213 static void *ips[] = { &&l0 };
214 l0: // expected-note {{possible target of indirect goto}}
215 C c0 = 42; // expected-note {{jump exits scope of variable with non-trivial destructor}}
216 goto *ip; // expected-error {{indirect goto might cross protected scopes}}
217 }
218 }
219
220 namespace test12 {
221 struct C {
222 C(int x);
223 ~C();
224 };
f(void ** ip)225 void f(void **ip) {
226 static void *ips[] = { &&l0 };
227 const C c0 = 17;
228 l0: // expected-note {{possible target of indirect goto}}
229 const C &c1 = 42; // expected-note {{jump exits scope of variable with non-trivial destructor}}
230 const C &c2 = c0;
231 goto *ip; // expected-error {{indirect goto might cross protected scopes}}
232 }
233 }
234
235 namespace test13 {
236 struct C {
237 C(int x);
238 ~C();
239 int i;
240 };
f(void ** ip)241 void f(void **ip) {
242 static void *ips[] = { &&l0 };
243 l0: // expected-note {{possible target of indirect goto}}
244 const int &c1 = C(1).i; // expected-note {{jump exits scope of variable with non-trivial destructor}}
245 goto *ip; // expected-error {{indirect goto might cross protected scopes}}
246 }
247 }
248
249 namespace test14 {
250 struct C {
251 C(int x);
252 ~C();
253 operator int&() const;
254 };
f(void ** ip)255 void f(void **ip) {
256 static void *ips[] = { &&l0 };
257 l0:
258 // no warning since the C temporary is destructed before the goto.
259 const int &c1 = C(1);
260 goto *ip;
261 }
262 }
263
264 // PR14225
265 namespace test15 {
f1()266 void f1() try {
267 goto x; // expected-error {{goto into protected scope}}
268 } catch(...) { // expected-note {{jump bypasses initialization of catch block}}
269 x: ;
270 }
f2()271 void f2() try { // expected-note {{jump bypasses initialization of try block}}
272 x: ;
273 } catch(...) {
274 goto x; // expected-error {{goto into protected scope}}
275 }
276 }
277
278 namespace test16 {
279 Invalid inv; // expected-error {{unknown type name}}
280 // Make sure this doesn't assert.
fn()281 void fn()
282 {
283 int c = 0;
284 if (inv)
285 Here: ;
286 goto Here;
287 }
288 }
289