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