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