rewrite the goto scope checking code to be more efficient, simpler,
produce better diagnostics, and be more correct in ObjC cases (fixing
rdar://6803963).

An example is that we now diagnose:

int test1(int x) {
  goto L;
  int a[x];
  int b[x];
  L:
  return sizeof a;
}

with:

scope-check.c:15:3: error: illegal goto into protected scope
  goto L;
  ^
scope-check.c:17:7: note: scope created by variable length array
  int b[x];
      ^
scope-check.c:16:7: note: scope created by variable length array
  int a[x];
      ^

instead of just saying "invalid jump".  An ObjC example is:

void test1() {
  goto L;
  @try {
L: ;
  } @finally {
  }
}

t.m:6:3: error: illegal goto into protected scope
  goto L;
  ^
t.m:7:3: note: scope created by @try block
  @try {
  ^

There are a whole ton of fixme's for stuff to do, but I believe that this
is a monotonic improvement over what we had.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69437 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Sema/scope-check.c b/test/Sema/scope-check.c
index 1d068a2..21908fc 100644
--- a/test/Sema/scope-check.c
+++ b/test/Sema/scope-check.c
@@ -1,15 +1,27 @@
 // RUN: clang-cc -fsyntax-only -verify %s
 
+/*
+"/tmp/bug.c", line 2: error: transfer of control bypasses initialization of:
+   variable length array "a" (declared at line 3)
+   variable length array "b" (declared at line 3)
+     goto L; 
+     ^
+"/tmp/bug.c", line 3: warning: variable "b" was declared but never referenced
+     int a[x], b[x];
+               ^
+*/
+
 int test1(int x) {
-  goto L; // expected-error{{illegal jump}}
-  int a[x];
+  goto L;    // expected-error{{illegal goto into protected scope}}
+  int a[x];  // expected-note {{scope created by variable length array}}
+  int b[x];  // expected-note {{scope created by variable length array}}
   L:
   return sizeof a;
 }
 
 int test2(int x) {
-  goto L; // expected-error{{illegal jump}}
-  typedef int a[x];
+  goto L;            // expected-error{{illegal goto into protected scope}}
+  typedef int a[x];  // expected-note {{scope created by VLA typedef}}
   L:
   return sizeof(a);
 }
@@ -17,15 +29,15 @@
 void test3clean(int*);
 
 int test3() {
-  goto L; // expected-error{{illegal jump}}
-int a __attribute((cleanup(test3clean)));
+  goto L;            // expected-error{{illegal goto into protected scope}}
+int a __attribute((cleanup(test3clean))); // expected-note {{scope created by declaration with __attribute__((cleanup))}}
 L:
   return a;
 }
 
 int test4(int x) {
-  goto L; // expected-error{{illegal jump}}
-int a[x];
+  goto L;       // expected-error{{illegal goto into protected scope}}
+int a[x];       // expected-note {{scope created by variable length array}}
   test4(x);
 L:
   return sizeof a;
@@ -40,5 +52,10 @@
   return sizeof a;
 }
 
+int test6() { 
+  // just plain invalid.
+  goto x;  // expected-error {{use of undeclared label 'x'}}
+}
+
 
 // FIXME: Switch cases etc.