зеркало из https://github.com/microsoft/clang.git
174 строки
3.0 KiB
C++
174 строки
3.0 KiB
C++
// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-unreachable-code
|
|
// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu++0x %s -Wno-unreachable-code
|
|
|
|
namespace test0 {
|
|
struct D { ~D(); };
|
|
|
|
int f(bool b) {
|
|
if (b) {
|
|
D d;
|
|
goto end;
|
|
}
|
|
|
|
end:
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
namespace test1 {
|
|
struct C { C(); };
|
|
|
|
int f(bool b) {
|
|
if (b)
|
|
goto foo; // expected-error {{illegal goto into protected scope}}
|
|
C c; // expected-note {{jump bypasses variable initialization}}
|
|
foo:
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
namespace test2 {
|
|
struct C { C(); };
|
|
|
|
int f(void **ip) {
|
|
static void *ips[] = { &&lbl1, &&lbl2 };
|
|
|
|
C c;
|
|
goto *ip;
|
|
lbl1:
|
|
return 0;
|
|
lbl2:
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
namespace test3 {
|
|
struct C { C(); };
|
|
|
|
int f(void **ip) {
|
|
static void *ips[] = { &&lbl1, &&lbl2 };
|
|
|
|
goto *ip;
|
|
lbl1: {
|
|
C c;
|
|
return 0;
|
|
}
|
|
lbl2:
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
namespace test4 {
|
|
struct C { C(); };
|
|
struct D { ~D(); };
|
|
|
|
int f(void **ip) {
|
|
static void *ips[] = { &&lbl1, &&lbl2 };
|
|
|
|
C c0;
|
|
|
|
goto *ip; // expected-error {{indirect goto might cross protected scopes}}
|
|
C c1; // expected-note {{jump bypasses variable initialization}}
|
|
lbl1: // expected-note {{possible target of indirect goto}}
|
|
return 0;
|
|
lbl2:
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
namespace test5 {
|
|
struct C { C(); };
|
|
struct D { ~D(); };
|
|
|
|
int f(void **ip) {
|
|
static void *ips[] = { &&lbl1, &&lbl2 };
|
|
C c0;
|
|
|
|
goto *ip;
|
|
lbl1: // expected-note {{possible target of indirect goto}}
|
|
return 0;
|
|
lbl2:
|
|
if (ip[1]) {
|
|
D d; // expected-note {{jump exits scope of variable with non-trivial destructor}}
|
|
ip += 2;
|
|
goto *ip; // expected-error {{indirect goto might cross protected scopes}}
|
|
}
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
namespace test6 {
|
|
struct C { C(); };
|
|
|
|
unsigned f(unsigned s0, unsigned s1, void **ip) {
|
|
static void *ips[] = { &&lbl1, &&lbl2, &&lbl3, &&lbl4 };
|
|
C c0;
|
|
|
|
goto *ip;
|
|
lbl1:
|
|
s0++;
|
|
goto *++ip;
|
|
lbl2:
|
|
s0 -= s1;
|
|
goto *++ip;
|
|
lbl3: {
|
|
unsigned tmp = s0;
|
|
s0 = s1;
|
|
s1 = tmp;
|
|
goto *++ip;
|
|
}
|
|
lbl4:
|
|
return s0;
|
|
}
|
|
}
|
|
|
|
// C++0x says it's okay to skip non-trivial initializers on static
|
|
// locals, and we implement that in '03 as well.
|
|
namespace test7 {
|
|
struct C { C(); };
|
|
|
|
void test() {
|
|
goto foo;
|
|
static C c;
|
|
foo:
|
|
return;
|
|
}
|
|
}
|
|
|
|
// PR7789
|
|
namespace test8 {
|
|
void test1(int c) {
|
|
switch (c) {
|
|
case 0:
|
|
int x = 56; // expected-note {{jump bypasses variable initialization}}
|
|
case 1: // expected-error {{switch case is in protected scope}}
|
|
x = 10;
|
|
}
|
|
}
|
|
|
|
void test2() {
|
|
goto l2; // expected-error {{goto into protected scope}}
|
|
l1: int x = 5; // expected-note {{jump bypasses variable initialization}}
|
|
l2: x++;
|
|
}
|
|
}
|
|
|
|
namespace test9 {
|
|
struct S { int i; };
|
|
void test1() {
|
|
goto foo;
|
|
S s;
|
|
foo:
|
|
return;
|
|
}
|
|
unsigned test2(unsigned x, unsigned y) {
|
|
switch (x) {
|
|
case 2:
|
|
S s;
|
|
if (y > 42) return x + y;
|
|
default:
|
|
return x - 2;
|
|
}
|
|
}
|
|
}
|