John McCall | ddb0b4d | 2010-05-12 00:58:13 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-unreachable-code |
Richard Smith | 762bb9d | 2011-10-13 22:29:44 +0000 | [diff] [blame] | 2 | // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu++11 %s -Wno-unreachable-code |
John McCall | ddb0b4d | 2010-05-12 00:58:13 +0000 | [diff] [blame] | 3 | |
| 4 | namespace 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 | |
| 18 | namespace test1 { |
| 19 | struct C { C(); }; |
| 20 | |
| 21 | int f(bool b) { |
| 22 | if (b) |
Richard Trieu | 2fe9b7f | 2011-12-15 00:38:15 +0000 | [diff] [blame] | 23 | goto foo; // expected-error {{goto into protected scope}} |
John McCall | ddb0b4d | 2010-05-12 00:58:13 +0000 | [diff] [blame] | 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 | |
| 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 | |
| 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 | |
| 65 | int f(void **ip) { |
| 66 | static void *ips[] = { &&lbl1, &&lbl2 }; |
| 67 | |
| 68 | C c0; |
| 69 | |
John McCall | 95c225d | 2010-10-28 08:53:48 +0000 | [diff] [blame] | 70 | goto *ip; // expected-error {{indirect goto might cross protected scopes}} |
John McCall | ddb0b4d | 2010-05-12 00:58:13 +0000 | [diff] [blame] | 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 | |
| 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; |
John McCall | 95c225d | 2010-10-28 08:53:48 +0000 | [diff] [blame] | 94 | goto *ip; // expected-error {{indirect goto might cross protected scopes}} |
John McCall | ddb0b4d | 2010-05-12 00:58:13 +0000 | [diff] [blame] | 95 | } |
| 96 | return 1; |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | namespace 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 | |
John McCall | e46f62c | 2010-08-01 01:24:59 +0000 | [diff] [blame] | 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 | |
| 130 | void test() { |
| 131 | goto foo; |
| 132 | static C c; |
| 133 | foo: |
| 134 | return; |
| 135 | } |
| 136 | } |
John McCall | 97ba481 | 2010-08-02 23:33:14 +0000 | [diff] [blame] | 137 | |
| 138 | // PR7789 |
| 139 | namespace 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 | } |
Chandler Carruth | cfe38c4 | 2011-04-22 19:01:39 +0000 | [diff] [blame] | 155 | |
| 156 | namespace 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 | } |
Argyrios Kyrtzidis | c0a575f | 2011-07-29 01:25:44 +0000 | [diff] [blame] | 174 | |
| 175 | // http://llvm.org/PR10462 |
| 176 | namespace PR10462 { |
| 177 | enum MyEnum { |
| 178 | something_valid, |
| 179 | something_invalid |
| 180 | }; |
| 181 | |
| 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 | } |
Francois Pichet | 2e96511 | 2011-09-16 23:15:32 +0000 | [diff] [blame] | 194 | |
| 195 | |
| 196 | namespace test10 { |
| 197 |
|
| 198 | int 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;
|
Argyrios Kyrtzidis | c0a575f | 2011-07-29 01:25:44 +0000 | [diff] [blame] | 204 | } |
Francois Pichet | 2e96511 | 2011-09-16 23:15:32 +0000 | [diff] [blame] | 205 | |
| 206 | } |
| 207 | |
| 208 | } |
| 209 | |