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) { // do not warn that 'something_invalid' is not listed;
197 // 'what_am_i_thinking' might have been intended to be that case.
198 case something_valid:
199 case what_am_i_thinking: // expected-error {{use of undeclared identifier}}
200 int *X = 0;
201 if (recurse()) {
202 }
203
204 break;
205 }
206 }
207 }
208
209 namespace test10 {
test()210 int test() {
211 static void *ps[] = { &&a0 };
212 goto *&&a0; // expected-error {{cannot jump}}
213 int a = 3; // expected-note {{jump bypasses variable initialization}}
214 a0:
215 return 0;
216 }
217 }
218
219 // pr13812
220 namespace test11 {
221 struct C {
222 C(int x);
223 ~C();
224 };
f(void ** ip)225 void f(void **ip) {
226 static void *ips[] = { &&l0 };
227 l0: // expected-note {{possible target of indirect goto}}
228 C c0 = 42; // expected-note {{jump exits scope of variable with non-trivial destructor}}
229 goto *ip; // expected-error {{cannot jump}}
230 }
231 }
232
233 namespace test12 {
234 struct C {
235 C(int x);
236 ~C();
237 };
f(void ** ip)238 void f(void **ip) {
239 static void *ips[] = { &&l0 };
240 const C c0 = 17;
241 l0: // expected-note {{possible target of indirect goto}}
242 const C &c1 = 42; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
243 const C &c2 = c0;
244 goto *ip; // expected-error {{cannot jump}}
245 }
246 }
247
248 namespace test13 {
249 struct C {
250 C(int x);
251 ~C();
252 int i;
253 };
f(void ** ip)254 void f(void **ip) {
255 static void *ips[] = { &&l0 };
256 l0: // expected-note {{possible target of indirect goto}}
257 const int &c1 = C(1).i; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
258 goto *ip; // expected-error {{cannot jump}}
259 }
260 }
261
262 namespace test14 {
263 struct C {
264 C(int x);
265 ~C();
266 operator int&() const;
267 };
f(void ** ip)268 void f(void **ip) {
269 static void *ips[] = { &&l0 };
270 l0:
271 // no warning since the C temporary is destructed before the goto.
272 const int &c1 = C(1);
273 goto *ip;
274 }
275 }
276
277 // PR14225
278 namespace test15 {
f1()279 void f1() try {
280 goto x; // expected-error {{cannot jump}}
281 } catch(...) { // expected-note {{jump bypasses initialization of catch block}}
282 x: ;
283 }
f2()284 void f2() try { // expected-note {{jump bypasses initialization of try block}}
285 x: ;
286 } catch(...) {
287 goto x; // expected-error {{cannot jump}}
288 }
289 }
290
291 namespace test16 {
292 struct S { int n; };
f()293 int f() {
294 goto x; // expected-error {{cannot jump}}
295 const S &s = S(); // expected-note {{jump bypasses variable initialization}}
296 x: return s.n;
297 }
298 }
299
300 #if __cplusplus >= 201103L
301 namespace test17 {
302 struct S { int get(); private: int n; };
f()303 int f() {
304 goto x; // expected-error {{cannot jump}}
305 S s = {}; // expected-note {{jump bypasses variable initialization}}
306 x: return s.get();
307 }
308 }
309 #endif
310
311 namespace test18 {
312 struct A { ~A(); };
313 struct B { const int &r; const A &a; };
f()314 int f() {
315 void *p = &&x;
316 const A a = A();
317 x:
318 B b = { 0, a }; // ok
319 goto *p;
320 }
g()321 int g() {
322 void *p = &&x;
323 x: // expected-note {{possible target of indirect goto}}
324 B b = { 0, A() }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
325 goto *p; // expected-error {{cannot jump}}
326 }
327 }
328
329 #if __cplusplus >= 201103L
330 namespace std {
331 typedef decltype(sizeof(int)) size_t;
332 template<typename T> struct initializer_list {
333 const T *begin;
334 size_t size;
335 initializer_list(const T *, size_t);
336 };
337 }
338 namespace test19 {
339 struct A { ~A(); };
340
f()341 int f() {
342 void *p = &&x;
343 A a;
344 x: // expected-note {{possible target of indirect goto}}
345 std::initializer_list<A> il = { a }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
346 goto *p; // expected-error {{cannot jump}}
347 }
348 }
349
350 namespace test20 {
351 struct A { ~A(); };
352 struct B {
353 const A &a;
354 };
355
f()356 int f() {
357 void *p = &&x;
358 A a;
359 x:
360 std::initializer_list<B> il = {
361 a,
362 a
363 };
364 goto *p;
365 }
g()366 int g() {
367 void *p = &&x;
368 A a;
369 x: // expected-note {{possible target of indirect goto}}
370 std::initializer_list<B> il = {
371 a,
372 { A() } // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
373 };
374 goto *p; // expected-error {{cannot jump}}
375 }
376 }
377 #endif
378
379 namespace test21 {
f()380 template<typename T> void f() {
381 goto x; // expected-error {{cannot jump}}
382 T t; // expected-note {{bypasses}}
383 x: return;
384 }
385
386 template void f<int>();
387 struct X { ~X(); };
388 template void f<X>(); // expected-note {{instantiation of}}
389 }
390
391 namespace PR18217 {
392 typedef int *X;
393
394 template <typename T>
395 class MyCl {
396 T mem;
397 };
398
399 class Source {
400 MyCl<X> m;
401 public:
402 int getKind() const;
403 };
404
405 bool b;
406 template<typename TT>
foo(const Source & SF,MyCl<TT * > Source::* m)407 static void foo(const Source &SF, MyCl<TT *> Source::*m) {
408 switch (SF.getKind()) {
409 case 1: return;
410 case 2: break;
411 case 3:
412 case 4: return;
413 };
414 if (b) {
415 auto &y = const_cast<MyCl<TT *> &>(SF.*m); // expected-warning 0-1{{extension}}
416 }
417 }
418
getKind() const419 int Source::getKind() const {
420 foo(*this, &Source::m);
421 return 0;
422 }
423 }
424
425 namespace test_recovery {
426 // Test that jump scope checking recovers when there are unspecified errors
427 // in the function declaration or body.
428
test(nexist,int c)429 void test(nexist, int c) { // expected-error {{}}
430 nexist_fn(); // expected-error {{}}
431 goto nexist_label; // expected-error {{use of undeclared label}}
432 goto a0; // expected-error {{cannot jump}}
433 int a = 0; // expected-note {{jump bypasses variable initialization}}
434 a0:;
435
436 switch (c) {
437 case $: // expected-error {{}}
438 case 0:
439 int x = 56; // expected-note {{jump bypasses variable initialization}}
440 case 1: // expected-error {{cannot jump}}
441 x = 10;
442 }
443 }
444 }
445
446 namespace seh {
447
448 // Jumping into SEH try blocks is not permitted.
449
jump_into_except()450 void jump_into_except() {
451 goto into_try_except_try; // expected-error {{cannot jump from this goto statement to its label}}
452 __try { // expected-note {{jump bypasses initialization of __try block}}
453 into_try_except_try:
454 ;
455 } __except(0) {
456 }
457
458 goto into_try_except_except; // expected-error {{cannot jump from this goto statement to its label}}
459 __try {
460 } __except(0) { // expected-note {{jump bypasses initialization of __except block}}
461 into_try_except_except:
462 ;
463 }
464 }
465
jump_into_finally()466 void jump_into_finally() {
467 goto into_try_except_try; // expected-error {{cannot jump from this goto statement to its label}}
468 __try { // expected-note {{jump bypasses initialization of __try block}}
469 into_try_except_try:
470 ;
471 } __finally {
472 }
473
474 goto into_try_except_finally; // expected-error {{cannot jump from this goto statement to its label}}
475 __try {
476 } __finally { // expected-note {{jump bypasses initialization of __finally block}}
477 into_try_except_finally:
478 ;
479 }
480 }
481
482 // Jumping out of SEH try blocks ok in general. (Jumping out of a __finally
483 // has undefined behavior.)
484
jump_out_of_except()485 void jump_out_of_except() {
486 __try {
487 goto out_of_except_try;
488 } __except(0) {
489 }
490 out_of_except_try:
491 ;
492
493 __try {
494 } __except(0) {
495 goto out_of_except_except;
496 }
497 out_of_except_except:
498 ;
499 }
500
jump_out_of_finally()501 void jump_out_of_finally() {
502 __try {
503 goto out_of_finally_try;
504 } __finally {
505 }
506 out_of_finally_try:
507 ;
508
509 __try {
510 } __finally {
511 goto out_of_finally_finally; // expected-warning {{jump out of __finally block has undefined behavior}}
512 }
513
514 __try {
515 } __finally {
516 goto *&&out_of_finally_finally; // expected-warning {{jump out of __finally block has undefined behavior}}
517 }
518 out_of_finally_finally:
519 ;
520 }
521
522 // Jumping between protected scope and handler is not permitted.
523
jump_try_except()524 void jump_try_except() {
525 __try {
526 goto from_try_to_except; // expected-error {{cannot jump from this goto statement to its label}}
527 } __except(0) { // expected-note {{jump bypasses initialization of __except block}}
528 from_try_to_except:
529 ;
530 }
531
532 __try { // expected-note {{jump bypasses initialization of __try block}}
533 from_except_to_try:
534 ;
535 } __except(0) {
536 goto from_except_to_try; // expected-error {{cannot jump from this goto statement to its label}}
537 }
538 }
539
jump_try_finally()540 void jump_try_finally() {
541 __try {
542 goto from_try_to_finally; // expected-error {{cannot jump from this goto statement to its label}}
543 } __finally { // expected-note {{jump bypasses initialization of __finally block}}
544 from_try_to_finally:
545 ;
546 }
547
548 __try { // expected-note {{jump bypasses initialization of __try block}}
549 from_finally_to_try:
550 ;
551 } __finally {
552 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}}
553 }
554 }
555
nested()556 void nested() {
557 // These are not permitted.
558 __try {
559 __try {
560 } __finally {
561 goto outer_except; // expected-error {{cannot jump from this goto statement to its label}}
562 }
563 } __except(0) { // expected-note {{jump bypasses initialization of __except bloc}}
564 outer_except:
565 ;
566 }
567
568 __try {
569 __try{
570 } __except(0) {
571 goto outer_finally; // expected-error {{cannot jump from this goto statement to its label}}
572 }
573 } __finally { // expected-note {{jump bypasses initialization of __finally bloc}}
574 outer_finally:
575 ;
576 }
577
578 // These are permitted.
579 __try {
580 __try {
581 } __finally {
582 goto after_outer_except; // expected-warning {{jump out of __finally block has undefined behavior}}
583 }
584 } __except(0) {
585 }
586 after_outer_except:
587 ;
588
589 __try {
590 __try{
591 } __except(0) {
592 goto after_outer_finally;
593 }
594 } __finally {
595 }
596 after_outer_finally:
597 ;
598 }
599
600 // This section is academic, as MSVC doesn't support indirect gotos.
601
indirect_jumps(void ** ip)602 void indirect_jumps(void **ip) {
603 static void *ips[] = { &&l };
604
605 __try { // expected-note {{jump exits __try block}}
606 // FIXME: Should this be allowed? Jumping out of the guarded section of a
607 // __try/__except doesn't require unwinding.
608 goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
609 } __except(0) {
610 }
611
612 __try {
613 } __except(0) { // expected-note {{jump exits __except block}}
614 // FIXME: What about here?
615 goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
616 }
617
618 __try { // expected-note {{jump exits __try block}}
619 goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
620 } __finally {
621 }
622
623 __try {
624 } __finally { // expected-note {{jump exits __finally block}}
625 goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
626 }
627 l: // expected-note 4 {{possible target of indirect goto statement}}
628 ;
629 }
630
631 } // namespace seh
632