1// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-unreachable-code
2// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu++11 %s -Wno-unreachable-code
3
4namespace test0 {
5  struct D { ~D(); };
6
7  int f(bool b) {
8    if (b) {
9      D d;
10      goto end;
11    }
12
13  end:
14    return 1;
15  }
16}
17
18namespace test1 {
19  struct C { C(); };
20
21  int f(bool b) {
22    if (b)
23      goto foo; // expected-error {{illegal goto into protected scope}}
24    C c; // expected-note {{jump bypasses variable initialization}}
25  foo:
26    return 1;
27  }
28}
29
30namespace test2 {
31  struct C { C(); };
32
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
45namespace test3 {
46  struct C { C(); };
47
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
61namespace test4 {
62  struct C { C(); };
63  struct D { ~D(); };
64
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
79namespace test5 {
80  struct C { C(); };
81  struct D { ~D(); };
82
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
100namespace test6 {
101  struct C { C(); };
102
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.
127namespace test7 {
128  struct C { C(); };
129
130  void test() {
131    goto foo;
132    static C c;
133  foo:
134    return;
135  }
136}
137
138// PR7789
139namespace test8 {
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
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
156namespace test9 {
157  struct S { int i; };
158  void test1() {
159    goto foo;
160    S s;
161  foo:
162    return;
163  }
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
176namespace PR10462 {
177enum MyEnum {
178  something_valid,
179  something_invalid
180};
181
182bool 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
196namespace test10 {
197
198int test() {
199  static void *ps[] = { &&a0 };
200  goto *&&a0; // expected-error {{goto into protected scope}}
201  int a = 3; // expected-note {{jump bypasses variable initialization}}
202 a0:
203  return 0;
204}
205
206}
207
208}
209
210