// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu99 %s -Wno-unreachable-code
int test1(int x) {
goto L; // expected-error{{cannot jump from this goto statement to its label}}
int a[x]; // expected-note {{jump bypasses initialization of variable length array}}
int b[x]; // expected-note {{jump bypasses initialization of variable length array}}
L:
return sizeof a;
}
int test2(int x) {
goto L; // expected-error{{cannot jump from this goto statement to its label}}
typedef int a[x]; // expected-note {{jump bypasses initialization of VLA typedef}}
L:
return sizeof(a);
}
void test3clean(int*);
int test3(void) {
goto L; // expected-error{{cannot jump from this goto statement to its label}}
int a __attribute((cleanup(test3clean))); // expected-note {{jump bypasses initialization of variable with __attribute__((cleanup))}}
L:
return a;
}
int test4(int x) {
goto L; // expected-error{{cannot jump from this goto statement to its label}}
int a[x]; // expected-note {{jump bypasses initialization of variable length array}}
test4(x);
L:
return sizeof a;
}
int test5(int x) {
int a[x];
test5(x);
goto L; // Ok.
L:
goto L; // Ok.
return sizeof a;
}
int test6(void) {
// just plain invalid.
goto x; // expected-error {{use of undeclared label 'x'}}
}
void test7(int x) {
switch (x) {
case 1: ;
int a[x]; // expected-note {{jump bypasses initialization of variable length array}}
case 2: // expected-error {{cannot jump from switch statement to this case label}}
a[1] = 2;
break;
}
}
int test8(int x) {
// For statement.
goto L2; // expected-error {{cannot jump from this goto statement to its label}}
for (int arr[x]; // expected-note {{jump bypasses initialization of variable length array}}
; ++x)
L2:;
// Statement expressions.
goto L3; // expected-error {{cannot jump from this goto statement to its label}}
int Y = ({ int a[x]; // expected-note {{jump bypasses initialization of variable length array}} \
// expected-note {{jump enters a statement expression}}
L3: 4; });
goto L4; // expected-error {{cannot jump from this goto statement to its label}}
{
int A[x], // expected-note {{jump bypasses initialization of variable length array}}
B[x]; // expected-note {{jump bypasses initialization of variable length array}}
L4: ;
}
{
L5: ;// ok
int A[x], B = ({ if (x)
goto L5;
else
goto L6;
4; });
L6:; // ok.
if (x) goto L6; // ok
}
{
L7: ;// ok
int A[x], B = ({ if (x)
goto L7;
else
goto L8; // expected-error {{cannot jump from this goto statement to its label}}
4; }),
C[x]; // expected-note {{jump bypasses initialization of variable length array}}
L8:; // bad
}
{
L9: ;// ok
int A[({ if (x)
goto L9;
else
// FIXME:
goto L10; // fixme-error {{cannot jump from this goto statement to its label}}
4; })];
L10:; // bad
}
{
// FIXME: Crashes goto checker.
//goto L11;// ok
//int A[({ L11: 4; })];
}
{
goto L12;
int y = 4; // fixme-warn: skips initializer.
L12:
;
}
// Statement expressions 2.
goto L1; // expected-error {{cannot jump from this goto statement to its label}}
return x == ({ // expected-note {{jump enters a statement expression}}
int a[x]; // expected-note {{jump bypasses initialization of variable length array}}
L1:
42; });
}
void test9(int n, void *P) {
int Y;
int Z = 4;
goto *P; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
L2: ;
int a[n]; // expected-note {{jump bypasses initialization of variable length array}}
L3: // expected-note {{possible target of indirect goto}}
L4:
goto *P;
goto L3; // ok
goto L4; // ok
void *Ptrs[] = {
&&L2,
&&L3
};
}
void test10(int n, void *P) {
goto L0; // expected-error {{cannot jump from this goto statement to its label}}
typedef int A[n]; // expected-note {{jump bypasses initialization of VLA typedef}}
L0:
goto L1; // expected-error {{cannot jump from this goto statement to its label}}
A b, c[10]; // expected-note 2 {{jump bypasses initialization of variable length array}}
L1:
goto L2; // expected-error {{cannot jump from this goto statement to its label}}
A d[n]; // expected-note {{jump bypasses initialization of variable length array}}
L2:
return;
}
void test11(int n) {
void *P = ^{
switch (n) {
case 1:;
case 2:
case 3:;
int Arr[n]; // expected-note {{jump bypasses initialization of variable length array}}
case 4: // expected-error {{cannot jump from switch statement to this case label}}
return;
}
};
}
// TODO: When and if gotos are allowed in blocks, this should work.
void test12(int n) {
void *P = ^{
goto L1;
L1:
goto L2;
L2:
goto L3; // expected-error {{cannot jump from this goto statement to its label}}
int Arr[n]; // expected-note {{jump bypasses initialization of variable length array}}
L3:
goto L4;
L4: return;
};
}
void test13(int n, void *p) {
int vla[n];
goto *p;
a0: ;
static void *ps[] = { &&a0 };
}
int test14(int n) {
static void *ps[] = { &&a0, &&a1 };
if (n < 0)
goto *&&a0;
if (n > 0) {
int vla[n];
a1:
vla[n-1] = 0;
}
a0:
return 0;
}
// PR8473: IR gen can't deal with indirect gotos past VLA
// initialization, so that really needs to be a hard error.
void test15(int n, void *pc) {
static const void *addrs[] = { &&L1, &&L2 };
goto *pc; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
L1:
{
char vla[n]; // expected-note {{jump bypasses initialization}}
L2: // expected-note {{possible target}}
vla[0] = 'a';
}
}
int test16(int [sizeof &&z]); // expected-error {{use of address-of-label extension outside of a function body}}
void GH63682() {
{
goto L; // expected-error {{cannot jump from this goto statement to its label}}
(void)sizeof (int){({ L:; 1; })}; // expected-note {{jump enters a statement expression}}
}
{
goto M; // expected-error {{cannot jump from this goto statement to its label}}
(void)({ M:; 1; }); // expected-note {{jump enters a statement expression}}
}
{
(void)({ goto N; 1; }); // ok
N: ;
}
{
(void)sizeof (int){({ goto O; 1; })}; // ok (not evaluated)
O: ;
}
{
(void)sizeof(({goto P;}), 0); // expected-error {{cannot jump from this goto statement to its label}}
return;
(void)({P:1;}); // expected-note {{jump enters a statement expression}}
}
}