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 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) 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 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 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 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; 94 goto *ip; // expected-error {{indirect goto might cross protected scopes}} 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 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 } 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 } 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 } 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 } 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; 204 } 205 206 } 207 208 } 209 210