Implement an indirect-goto optimization for goto *&&lbl and respect this
in the scope checker.  With that done, turn an indirect goto into a
protected scope into a hard error;  otherwise IR generation has to start
worrying about declarations not dominating their scopes, as exemplified
in PR8473.

If this really affects anyone, I can probably adjust this to only hard-error
on possible indirect gotos into VLA scopes rather than arbitrary scopes.
But we'll see how people cope with the aggressive change on the marginal
feature.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117539 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Sema/scope-check.c b/test/Sema/scope-check.c
index 4ccb64c..1a2fc2b 100644
--- a/test/Sema/scope-check.c
+++ b/test/Sema/scope-check.c
@@ -133,7 +133,7 @@
 void test9(int n, void *P) {
   int Y;
   int Z = 4;
-  goto *P;  // expected-warning {{indirect goto might cross protected scopes}}
+  goto *P;  // expected-error {{indirect goto might cross protected scopes}}
 
 L2: ;
   int a[n]; // expected-note {{jump bypasses initialization of variable length array}}
@@ -199,3 +199,33 @@
  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 {{indirect goto might cross protected scope}}
+
+ L1:
+  {
+    char vla[n]; // expected-note {{jump bypasses initialization}}
+   L2: // expected-note {{possible target}}
+    vla[0] = 'a';
+  }
+}
diff --git a/test/SemaCXX/scope-check.cpp b/test/SemaCXX/scope-check.cpp
index cdc3868..d462af0 100644
--- a/test/SemaCXX/scope-check.cpp
+++ b/test/SemaCXX/scope-check.cpp
@@ -66,7 +66,7 @@
 
     C c0;
 
-    goto *ip; // expected-warning {{indirect goto might cross protected scopes}}
+    goto *ip; // expected-error {{indirect goto might cross protected scopes}}
     C c1; // expected-note {{jump bypasses variable initialization}}
   lbl1: // expected-note {{possible target of indirect goto}}
     return 0;
@@ -90,7 +90,7 @@
     if (ip[1]) {
       D d; // expected-note {{jump exits scope of variable with non-trivial destructor}}
       ip += 2;
-      goto *ip; // expected-warning {{indirect goto might cross protected scopes}}
+      goto *ip; // expected-error {{indirect goto might cross protected scopes}}
     }
     return 1;
   }