| // 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}} |