]> granicus.if.org Git - clang/commitdiff
second half of indirect jump checking: make sure that any
authorChris Lattner <sabre@nondot.org>
Sun, 19 Apr 2009 01:16:06 +0000 (01:16 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 19 Apr 2009 01:16:06 +0000 (01:16 +0000)
address taken labels are in function scope

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69499 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 9b9b2a1d3940bbb8b0ec181e260c25e96644edea..8ee940310b50d8912b392a39da1313cb3aab7cdf 100644 (file)
@@ -836,6 +836,9 @@ 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 err_addr_of_label_in_protected_scope : Error<
+  "address taken of label in protected scope, jump to it would have "
+  "unknown effect on scope">;
 def note_protected_by_vla_typedef : Note<
   "jump bypasses initialization of VLA typedef">;
 def note_protected_by_vla : Note<
index 2aaa1bc940c9192d0da92b1d3fee930089ed70f7..3a1217a839346678d97273b238a5ad20078bd5fd 100644 (file)
@@ -2988,7 +2988,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
   if (isa<LabelStmt>(S) || isa<DefaultStmt>(S) || isa<CaseStmt>(S)) {
     LabelAndGotoScopes[S] = ParentScope;
   } else if (isa<GotoStmt>(S) || isa<SwitchStmt>(S) ||
-             isa<IndirectGotoStmt>(S)) {
+             isa<IndirectGotoStmt>(S) || isa<AddrLabelExpr>(S)) {
     // Remember both what scope a goto is in as well as the fact that we have
     // it.  This makes the second scan not have to walk the AST again.
     LabelAndGotoScopes[S] = ParentScope;
@@ -3082,19 +3082,41 @@ void JumpScopeChecker::VerifyJumps() {
     }
     
     
+    unsigned DiagnosticScope;
+    
     // 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);
+    if (IndirectGotoStmt *IG = dyn_cast<IndirectGotoStmt>(Jump)) {
+      assert(LabelAndGotoScopes.count(Jump) &&
+             "Jump didn't get added to scopes?");
+      unsigned GotoScope = LabelAndGotoScopes[IG];
+      if (GotoScope == 0) continue;  // indirect jump is ok.
+      S.Diag(IG->getGotoLoc(), diag::err_indirect_goto_in_protected_scope);
+      DiagnosticScope = GotoScope;
+    } else {
+      // We model &&Label as a jump for purposes of scope tracking.  We actually
+      // don't care *where* the address of label is, but we require the *label
+      // itself* to be in scope 0.  If it is nested inside of a VLA scope, then
+      // it is possible for an indirect goto to illegally enter the VLA scope by
+      // indirectly jumping to the label.
+      assert(isa<AddrLabelExpr>(Jump) && "Unknown jump type");
+      LabelStmt *TheLabel = cast<AddrLabelExpr>(Jump)->getLabel();
+    
+      assert(LabelAndGotoScopes.count(TheLabel) &&
+             "Referenced label didn't get added to scopes?");
+      unsigned LabelScope = LabelAndGotoScopes[TheLabel];
+      if (LabelScope == 0) continue; // Addr of label is ok.
     
-    while (GotoScope != 0) {
-      S.Diag(Scopes[GotoScope].Loc, Scopes[GotoScope].Diag);
-      GotoScope = Scopes[GotoScope].ParentScope;
+      S.Diag(Jump->getLocStart(), diag::err_addr_of_label_in_protected_scope);
+      DiagnosticScope = LabelScope;
+    }
+
+    // Report all the things that would be skipped over by this &&label or
+    // indirect goto.
+    while (DiagnosticScope != 0) {
+      S.Diag(Scopes[DiagnosticScope].Loc, Scopes[DiagnosticScope].Diag);
+      DiagnosticScope = Scopes[DiagnosticScope].ParentScope;
     }
-    continue;
   }
 }
 
index 4605e02b88062338810f20205c1cf535d6332ca1..83b84777a932bc7d5a8ad85781934c818b96bd8f 100644 (file)
@@ -136,14 +136,17 @@ void test9(int n, void *P) {
   goto *P;  // ok.
 
 L2: ;
-  int a[n];  // expected-note {{jump bypasses initialization of variable length array}}
+  int a[n]; // expected-note 2 {{jump bypasses initialization of variable length array}}
 
 L3:
+L4:  
   goto *P;  // expected-error {{illegal indirect goto in protected scope, unknown effect on scopes}}
+  goto L3;  // ok
+  goto L4;  // ok
   
   void *Ptrs[] = {
-    &&L2,
-    &&L3   // FIXME: Not Ok.
+    &&L2,   // Ok.
+    &&L3   // expected-error {{address taken of label in protected scope, jump to it would have unknown effect on scope}}
   };
 }