1 // RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify -fblocks -fcxx-exceptions -fms-extensions %s -Wno-unreachable-code
2 // RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify -fblocks -fcxx-exceptions -fms-extensions -std=gnu++11 %s -Wno-unreachable-code
3
4 namespace testInvalid {
5 Invalid inv; // expected-error {{unknown type name}}
6 // Make sure this doesn't assert.
fn()7 void fn()
8 {
9 int c = 0;
10 if (inv)
11 Here: ;
12 goto Here;
13 }
14 }
15
16 namespace test0 {
17 struct D { ~D(); };
18
f(bool b)19 int f(bool b) {
20 if (b) {
21 D d;
22 goto end;
23 }
24
25 end:
26 return 1;
27 }
28 }
29
30 namespace test1 {
31 struct C { C(); };
32
f(bool b)33 int f(bool b) {
34 if (b)
35 goto foo; // expected-error {{cannot jump}}
36 C c; // expected-note {{jump bypasses variable initialization}}
37 foo:
38 return 1;
39 }
40 }
41
42 namespace test2 {
43 struct C { C(); };
44
f(void ** ip)45 int f(void **ip) {
46 static void *ips[] = { &&lbl1, &&lbl2 };
47
48 C c;
49 goto *ip;
50 lbl1:
51 return 0;
52 lbl2:
53 return 1;
54 }
55 }
56
57 namespace test3 {
58 struct C { C(); };
59
f(void ** ip)60 int f(void **ip) {
61 static void *ips[] = { &&lbl1, &&lbl2 };
62
63 goto *ip;
64 lbl1: {
65 C c;
66 return 0;
67 }
68 lbl2:
69 return 1;
70 }
71 }
72
73 namespace test4 {
74 struct C { C(); };
75 struct D { ~D(); };
76
f(void ** ip)77 int f(void **ip) {
78 static void *ips[] = { &&lbl1, &&lbl2 };
79
80 C c0;
81
82 goto *ip; // expected-error {{cannot jump}}
83 C c1; // expected-note {{jump bypasses variable initialization}}
84 lbl1: // expected-note {{possible target of indirect goto}}
85 return 0;
86 lbl2:
87 return 1;
88 }
89 }
90
91 namespace test5 {
92 struct C { C(); };
93 struct D { ~D(); };
94
f(void ** ip)95 int f(void **ip) {
96 static void *ips[] = { &&lbl1, &&lbl2 };
97 C c0;
98
99 goto *ip;
100 lbl1: // expected-note {{possible target of indirect goto}}
101 return 0;
102 lbl2:
103 if (ip[1]) {
104 D d; // expected-note {{jump exits scope of variable with non-trivial destructor}}
105 ip += 2;
106 goto *ip; // expected-error {{cannot jump}}
107 }
108 return 1;
109 }
110 }
111
112 namespace test6 {
113 struct C { C(); };
114
f(unsigned s0,unsigned s1,void ** ip)115 unsigned f(unsigned s0, unsigned s1, void **ip) {
116 static void *ips[] = { &&lbl1, &&lbl2, &&lbl3, &&lbl4 };
117 C c0;
118
119 goto *ip;
120 lbl1:
121 s0++;
122 goto *++ip;
123 lbl2:
124 s0 -= s1;
125 goto *++ip;
126 lbl3: {
127 unsigned tmp = s0;
128 s0 = s1;
129 s1 = tmp;
130 goto *++ip;
131 }
132 lbl4:
133 return s0;
134 }
135 }
136
137 // C++0x says it's okay to skip non-trivial initializers on static
138 // locals, and we implement that in '03 as well.
139 namespace test7 {
140 struct C { C(); };
141
test()142 void test() {
143 goto foo;
144 static C c;
145 foo:
146 return;
147 }
148 }
149
150 // PR7789
151 namespace test8 {
test1(int c)152 void test1(int c) {
153 switch (c) {
154 case 0:
155 int x = 56; // expected-note {{jump bypasses variable initialization}}
156 case 1: // expected-error {{cannot jump}}
157 x = 10;
158 }
159 }
160
test2()161 void test2() {
162 goto l2; // expected-error {{cannot jump}}
163 l1: int x = 5; // expected-note {{jump bypasses variable initialization}}
164 l2: x++;
165 }
166 }
167
168 namespace test9 {
169 struct S { int i; };
test1()170 void test1() {
171 goto foo;
172 S s;
173 foo:
174 return;
175 }
test2(unsigned x,unsigned y)176 unsigned test2(unsigned x, unsigned y) {
177 switch (x) {
178 case 2:
179 S s;
180 if (y > 42) return x + y;
181 default:
182 return x - 2;
183 }
184 }
185 }
186
187 // http://llvm.org/PR10462
188 namespace PR10462 {
189 enum MyEnum {
190 something_valid,
191 something_invalid
192 };
193
recurse()194 bool recurse() {
195 MyEnum K;
196 switch (K) { // expected-warning {{enumeration value 'something_invalid' not handled in switch}}
197 case something_valid:
198 case what_am_i_thinking: // expected-error {{use of undeclared identifier}}
199 int *X = 0;
200 if (recurse()) {
201 }
202
203 break;
204 }
205 }
206 }
207
208 namespace test10 {
test()209 int test() {
210 static void *ps[] = { &&a0 };
211 goto *&&a0; // expected-error {{cannot jump}}
212 int a = 3; // expected-note {{jump bypasses variable initialization}}
213 a0:
214 return 0;
215 }
216 }
217
218 // pr13812
219 namespace test11 {
220 struct C {
221 C(int x);
222 ~C();
223 };
f(void ** ip)224 void f(void **ip) {
225 static void *ips[] = { &&l0 };
226 l0: // expected-note {{possible target of indirect goto}}
227 C c0 = 42; // expected-note {{jump exits scope of variable with non-trivial destructor}}
228 goto *ip; // expected-error {{cannot jump}}
229 }
230 }
231
232 namespace test12 {
233 struct C {
234 C(int x);
235 ~C();
236 };
f(void ** ip)237 void f(void **ip) {
238 static void *ips[] = { &&l0 };
239 const C c0 = 17;
240 l0: // expected-note {{possible target of indirect goto}}
241 const C &c1 = 42; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
242 const C &c2 = c0;
243 goto *ip; // expected-error {{cannot jump}}
244 }
245 }
246
247 namespace test13 {
248 struct C {
249 C(int x);
250 ~C();
251 int i;
252 };
f(void ** ip)253 void f(void **ip) {
254 static void *ips[] = { &&l0 };
255 l0: // expected-note {{possible target of indirect goto}}
256 const int &c1 = C(1).i; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
257 goto *ip; // expected-error {{cannot jump}}
258 }
259 }
260
261 namespace test14 {
262 struct C {
263 C(int x);
264 ~C();
265 operator int&() const;
266 };
f(void ** ip)267 void f(void **ip) {
268 static void *ips[] = { &&l0 };
269 l0:
270 // no warning since the C temporary is destructed before the goto.
271 const int &c1 = C(1);
272 goto *ip;
273 }
274 }
275
276 // PR14225
277 namespace test15 {
f1()278 void f1() try {
279 goto x; // expected-error {{cannot jump}}
280 } catch(...) { // expected-note {{jump bypasses initialization of catch block}}
281 x: ;
282 }
f2()283 void f2() try { // expected-note {{jump bypasses initialization of try block}}
284 x: ;
285 } catch(...) {
286 goto x; // expected-error {{cannot jump}}
287 }
288 }
289
290 namespace test16 {
291 struct S { int n; };
f()292 int f() {
293 goto x; // expected-error {{cannot jump}}
294 const S &s = S(); // expected-note {{jump bypasses variable initialization}}
295 x: return s.n;
296 }
297 }
298
299 #if __cplusplus >= 201103L
300 namespace test17 {
301 struct S { int get(); private: int n; };
f()302 int f() {
303 goto x; // expected-error {{cannot jump}}
304 S s = {}; // expected-note {{jump bypasses variable initialization}}
305 x: return s.get();
306 }
307 }
308 #endif
309
310 namespace test18 {
311 struct A { ~A(); };
312 struct B { const int &r; const A &a; };
f()313 int f() {
314 void *p = &&x;
315 const A a = A();
316 x:
317 B b = { 0, a }; // ok
318 goto *p;
319 }
g()320 int g() {
321 void *p = &&x;
322 x: // expected-note {{possible target of indirect goto}}
323 B b = { 0, A() }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
324 goto *p; // expected-error {{cannot jump}}
325 }
326 }
327
328 #if __cplusplus >= 201103L
329 namespace std {
330 typedef decltype(sizeof(int)) size_t;
331 template<typename T> struct initializer_list {
332 const T *begin;
333 size_t size;
334 initializer_list(const T *, size_t);
335 };
336 }
337 namespace test19 {
338 struct A { ~A(); };
339
f()340 int f() {
341 void *p = &&x;
342 A a;
343 x: // expected-note {{possible target of indirect goto}}
344 std::initializer_list<A> il = { a }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
345 goto *p; // expected-error {{cannot jump}}
346 }
347 }
348
349 namespace test20 {
350 struct A { ~A(); };
351 struct B {
352 const A &a;
353 };
354
f()355 int f() {
356 void *p = &&x;
357 A a;
358 x:
359 std::initializer_list<B> il = {
360 a,
361 a
362 };
363 goto *p;
364 }
g()365 int g() {
366 void *p = &&x;
367 A a;
368 x: // expected-note {{possible target of indirect goto}}
369 std::initializer_list<B> il = {
370 a,
371 { A() } // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
372 };
373 goto *p; // expected-error {{cannot jump}}
374 }
375 }
376 #endif
377
378 namespace test21 {
f()379 template<typename T> void f() {
380 goto x; // expected-error {{cannot jump}}
381 T t; // expected-note {{bypasses}}
382 x: return;
383 }
384
385 template void f<int>();
386 struct X { ~X(); };
387 template void f<X>(); // expected-note {{instantiation of}}
388 }
389
390 namespace PR18217 {
391 typedef int *X;
392
393 template <typename T>
394 class MyCl {
395 T mem;
396 };
397
398 class Source {
399 MyCl<X> m;
400 public:
401 int getKind() const;
402 };
403
404 bool b;
405 template<typename TT>
foo(const Source & SF,MyCl<TT * > Source::* m)406 static void foo(const Source &SF, MyCl<TT *> Source::*m) {
407 switch (SF.getKind()) {
408 case 1: return;
409 case 2: break;
410 case 3:
411 case 4: return;
412 };
413 if (b) {
414 auto &y = const_cast<MyCl<TT *> &>(SF.*m); // expected-warning 0-1{{extension}}
415 }
416 }
417
getKind() const418 int Source::getKind() const {
419 foo(*this, &Source::m);
420 return 0;
421 }
422 }
423
424 namespace test_recovery {
425 // Test that jump scope checking recovers when there are unspecified errors
426 // in the function declaration or body.
427
test(nexist,int c)428 void test(nexist, int c) { // expected-error {{}}
429 nexist_fn(); // expected-error {{}}
430 goto nexist_label; // expected-error {{use of undeclared label}}
431 goto a0; // expected-error {{cannot jump}}
432 int a = 0; // expected-note {{jump bypasses variable initialization}}
433 a0:;
434
435 switch (c) {
436 case $: // expected-error {{}}
437 case 0:
438 int x = 56; // expected-note {{jump bypasses variable initialization}}
439 case 1: // expected-error {{cannot jump}}
440 x = 10;
441 }
442 }
443 }
444
445 namespace seh {
446
447 // Jumping into SEH try blocks is not permitted.
448
jump_into_except()449 void jump_into_except() {
450 goto into_try_except_try; // expected-error {{cannot jump from this goto statement to its label}}
451 __try { // expected-note {{jump bypasses initialization of __try block}}
452 into_try_except_try:
453 ;
454 } __except(0) {
455 }
456
457 goto into_try_except_except; // expected-error {{cannot jump from this goto statement to its label}}
458 __try {
459 } __except(0) { // expected-note {{jump bypasses initialization of __except block}}
460 into_try_except_except:
461 ;
462 }
463 }
464
jump_into_finally()465 void jump_into_finally() {
466 goto into_try_except_try; // expected-error {{cannot jump from this goto statement to its label}}
467 __try { // expected-note {{jump bypasses initialization of __try block}}
468 into_try_except_try:
469 ;
470 } __finally {
471 }
472
473 goto into_try_except_finally; // expected-error {{cannot jump from this goto statement to its label}}
474 __try {
475 } __finally { // expected-note {{jump bypasses initialization of __finally block}}
476 into_try_except_finally:
477 ;
478 }
479 }
480
481 // Jumping out of SEH try blocks ok in general. (Jumping out of a __finally
482 // has undefined behavior.)
483
jump_out_of_except()484 void jump_out_of_except() {
485 __try {
486 goto out_of_except_try;
487 } __except(0) {
488 }
489 out_of_except_try:
490 ;
491
492 __try {
493 } __except(0) {
494 goto out_of_except_except;
495 }
496 out_of_except_except:
497 ;
498 }
499
jump_out_of_finally()500 void jump_out_of_finally() {
501 __try {
502 goto out_of_finally_try;
503 } __finally {
504 }
505 out_of_finally_try:
506 ;
507
508 __try {
509 } __finally {
510 goto out_of_finally_finally; // expected-warning {{jump out of __finally block has undefined behavior}}
511 }
512
513 __try {
514 } __finally {
515 goto *&&out_of_finally_finally; // expected-warning {{jump out of __finally block has undefined behavior}}
516 }
517 out_of_finally_finally:
518 ;
519 }
520
521 // Jumping between protected scope and handler is not permitted.
522
jump_try_except()523 void jump_try_except() {
524 __try {
525 goto from_try_to_except; // expected-error {{cannot jump from this goto statement to its label}}
526 } __except(0) { // expected-note {{jump bypasses initialization of __except block}}
527 from_try_to_except:
528 ;
529 }
530
531 __try { // expected-note {{jump bypasses initialization of __try block}}
532 from_except_to_try:
533 ;
534 } __except(0) {
535 goto from_except_to_try; // expected-error {{cannot jump from this goto statement to its label}}
536 }
537 }
538
jump_try_finally()539 void jump_try_finally() {
540 __try {
541 goto from_try_to_finally; // expected-error {{cannot jump from this goto statement to its label}}
542 } __finally { // expected-note {{jump bypasses initialization of __finally block}}
543 from_try_to_finally:
544 ;
545 }
546
547 __try { // expected-note {{jump bypasses initialization of __try block}}
548 from_finally_to_try:
549 ;
550 } __finally {
551 goto from_finally_to_try; // expected-error {{cannot jump from this goto statement to its label}} expected-warning {{jump out of __finally block has undefined behavior}}
552 }
553 }
554
nested()555 void nested() {
556 // These are not permitted.
557 __try {
558 __try {
559 } __finally {
560 goto outer_except; // expected-error {{cannot jump from this goto statement to its label}}
561 }
562 } __except(0) { // expected-note {{jump bypasses initialization of __except bloc}}
563 outer_except:
564 ;
565 }
566
567 __try {
568 __try{
569 } __except(0) {
570 goto outer_finally; // expected-error {{cannot jump from this goto statement to its label}}
571 }
572 } __finally { // expected-note {{jump bypasses initialization of __finally bloc}}
573 outer_finally:
574 ;
575 }
576
577 // These are permitted.
578 __try {
579 __try {
580 } __finally {
581 goto after_outer_except; // expected-warning {{jump out of __finally block has undefined behavior}}
582 }
583 } __except(0) {
584 }
585 after_outer_except:
586 ;
587
588 __try {
589 __try{
590 } __except(0) {
591 goto after_outer_finally;
592 }
593 } __finally {
594 }
595 after_outer_finally:
596 ;
597 }
598
599 // This section is academic, as MSVC doesn't support indirect gotos.
600
indirect_jumps(void ** ip)601 void indirect_jumps(void **ip) {
602 static void *ips[] = { &&l };
603
604 __try { // expected-note {{jump exits __try block}}
605 // FIXME: Should this be allowed? Jumping out of the guarded section of a
606 // __try/__except doesn't require unwinding.
607 goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
608 } __except(0) {
609 }
610
611 __try {
612 } __except(0) { // expected-note {{jump exits __except block}}
613 // FIXME: What about here?
614 goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
615 }
616
617 __try { // expected-note {{jump exits __try block}}
618 goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
619 } __finally {
620 }
621
622 __try {
623 } __finally { // expected-note {{jump exits __finally block}}
624 goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
625 }
626 l: // expected-note 4 {{possible target of indirect goto statement}}
627 ;
628 }
629
630 } // namespace seh
631