235 lines
6.1 KiB
C
235 lines
6.1 KiB
C
|
// 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() {
|
||
|
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() {
|
||
|
// 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}}
|
||
|
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 == ({
|
||
|
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';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// rdar://9024687
|
||
|
int test16(int [sizeof &&z]); // expected-error {{use of address-of-label extension outside of a function body}}
|