]> granicus.if.org Git - clang/commitdiff
First half of jump scope checking for indirect goto.
authorChris Lattner <sabre@nondot.org>
Sun, 19 Apr 2009 01:05:26 +0000 (01:05 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 19 Apr 2009 01:05:26 +0000 (01:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69498 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
test/Sema/scope-check.c

index 8330a02b2a6cc0cb140dff22b78351fd57454ad8..9b9b2a1d3940bbb8b0ec181e260c25e96644edea 100644 (file)
@@ -834,6 +834,8 @@ def err_undeclared_label_use : Error<"use of undeclared label '%0'">;
 def err_goto_into_protected_scope : Error<"illegal goto into protected scope">;
 def err_switch_into_protected_scope : Error<
   "illegal switch case into protected scope">;
+def err_indirect_goto_in_protected_scope : Error<
+  "illegal indirect goto in protected scope, unknown effect on scopes">;
 def note_protected_by_vla_typedef : Note<
   "jump bypasses initialization of VLA typedef">;
 def note_protected_by_vla : Note<
index ac9741363434daab110de2bd8ababdc836777f33..2aaa1bc940c9192d0da92b1d3fee930089ed70f7 100644 (file)
@@ -3001,7 +3001,8 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
     if (SubStmt == 0) continue;
     
     // FIXME: diagnose jumps past initialization: required in C++, warning in C.
-    //     { int X = 4;   L: } goto L;
+    //   goto L; int X = 4;   L: ;
+    // FIXME: what about jumps into C++ catch blocks, what are the rules?
 
     // If this is a declstmt with a VLA definition, it defines a scope from here
     // to the end of the containing context.
@@ -3054,7 +3055,6 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
       
       continue;
     }
-    // FIXME: what about jumps into C++ catch blocks, what are the rules?
     
     // Recursively walk the AST.
     BuildScopeInformation(SubStmt, ParentScope);
@@ -3068,7 +3068,10 @@ void JumpScopeChecker::VerifyJumps() {
     if (GotoStmt *GS = dyn_cast<GotoStmt>(Jump)) {
       CheckJump(GS, GS->getLabel(), GS->getGotoLoc(),
                 diag::err_goto_into_protected_scope);
-    } else if (SwitchStmt *SS = dyn_cast<SwitchStmt>(Jump)) {
+      continue;
+    }
+    
+    if (SwitchStmt *SS = dyn_cast<SwitchStmt>(Jump)) {
       for (SwitchCase *SC = SS->getSwitchCaseList(); SC;
            SC = SC->getNextSwitchCase()) {
         assert(LabelAndGotoScopes.count(SC) && "Case not visited?");
@@ -3076,11 +3079,22 @@ void JumpScopeChecker::VerifyJumps() {
                   diag::err_switch_into_protected_scope);
       }
       continue;
-    } else {
-      assert(isa<IndirectGotoStmt>(Jump));
-      // FIXME: Emit an error on indirect gotos when not in scope 0.
-      continue;
     }
+    
+    
+    // We don't know where an indirect goto goes, require that it be at the
+    // top level of scoping.
+    assert(isa<IndirectGotoStmt>(Jump));
+    assert(LabelAndGotoScopes.count(Jump) &&"Jump didn't get added to scopes?");
+    unsigned GotoScope = LabelAndGotoScopes[Jump];
+    if (GotoScope == 0) continue;
+    S.Diag(Jump->getLocStart(), diag::err_indirect_goto_in_protected_scope);
+    
+    while (GotoScope != 0) {
+      S.Diag(Scopes[GotoScope].Loc, Scopes[GotoScope].Diag);
+      GotoScope = Scopes[GotoScope].ParentScope;
+    }
+    continue;
   }
 }
 
index 98662be621bcabae47c6ea9dc272759725ced3bb..4605e02b88062338810f20205c1cf535d6332ca1 100644 (file)
@@ -83,6 +83,7 @@ int test8(int x) {
                        goto L6;
                    4; }); 
   L6:; // ok.
+    if (x) goto L6; // ok
   }
   
   {
@@ -113,6 +114,13 @@ int test8(int x) {
     //int A[({   L11: 4; })];
   }
   
+  {
+    goto L12;
+    
+    int y = 4;   // fixme-warn: skips initializer.
+  L12:
+    ;
+  }
   
   // Statement expressions 2.
   goto L1;     // expected-error {{illegal goto into protected scope}}
@@ -121,3 +129,21 @@ int test8(int x) {
                L1:
                  42; });
 }
+
+void test9(int n, void *P) {
+  int Y;
+  int Z = 4;
+  goto *P;  // ok.
+
+L2: ;
+  int a[n];  // expected-note {{jump bypasses initialization of variable length array}}
+
+L3:
+  goto *P;  // expected-error {{illegal indirect goto in protected scope, unknown effect on scopes}}
+  
+  void *Ptrs[] = {
+    &&L2,
+    &&L3   // FIXME: Not Ok.
+  };
+}
+