[cfe-commits] r69459 - /cfe/trunk/lib/Sema/SemaDecl.cpp

Chris Lattner sabre at nondot.org
Sat Apr 18 12:30:02 PDT 2009


Author: lattner
Date: Sat Apr 18 14:30:02 2009
New Revision: 69459

URL: http://llvm.org/viewvc/llvm-project?rev=69459&view=rev
Log:
fix error recovery in the case of a jump to a label with no definition
to create a well formed AST instead of a dangling pointer.  This resolves
several fixme's.

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=69459&r1=69458&r2=69459&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Apr 18 14:30:02 2009
@@ -3067,10 +3067,6 @@
     Stmt *Jump = Jumps.pop_back_val();
     
     if (GotoStmt *GS = dyn_cast<GotoStmt>(Jump)) {
-      // FIXME: invalid code makes dangling AST, see test6 in scope-check.c.
-      // FIXME: This is a hack.
-      if (!LabelAndGotoScopes.count(GS->getLabel())) return;
-      
       assert(LabelAndGotoScopes.count(GS->getLabel()) && "Label not visited?");
       CheckJump(GS, LabelAndGotoScopes[GS->getLabel()],
                 diag::err_goto_into_protected_scope);
@@ -3155,31 +3151,37 @@
   // Check goto/label use.
   for (llvm::DenseMap<IdentifierInfo*, LabelStmt*>::iterator
        I = LabelMap.begin(), E = LabelMap.end(); I != E; ++I) {
+    LabelStmt *L = I->second;
+    
     // Verify that we have no forward references left.  If so, there was a goto
     // or address of a label taken, but no definition of it.  Label fwd
     // definitions are indicated with a null substmt.
-    if (I->second->getSubStmt() == 0) {
-      LabelStmt *L = I->second;
-      // Emit error.
-      Diag(L->getIdentLoc(), diag::err_undeclared_label_use) << L->getName();
-      
-      // At this point, we have gotos that use the bogus label.  Stitch it into
-      // the function body so that they aren't leaked and that the AST is well
-      // formed.
-      if (Body) {
-#if 0
-        // FIXME: Why do this?  Having a 'push_back' in CompoundStmt is ugly,
-        // and the AST is malformed anyway.  We should just blow away 'L'.
-        L->setSubStmt(new (Context) NullStmt(L->getIdentLoc()));
-        cast<CompoundStmt>(Body)->push_back(L);        
-#else
-        L->Destroy(Context);
-#endif
-      } else {
-        // The whole function wasn't parsed correctly, just delete this.
-        L->Destroy(Context);
-      }
+    if (L->getSubStmt() != 0)
+      continue;
+    
+    // Emit error.
+    Diag(L->getIdentLoc(), diag::err_undeclared_label_use) << L->getName();
+    
+    // At this point, we have gotos that use the bogus label.  Stitch it into
+    // the function body so that they aren't leaked and that the AST is well
+    // formed.
+    if (Body == 0) {
+      // The whole function wasn't parsed correctly, just delete this.
+      L->Destroy(Context);
+      continue;
     }
+    
+    // Otherwise, the body is valid: we want to stitch the label decl into the
+    // function somewhere so that it is properly owned and so that the goto
+    // has a valid target.  Do this by creating a new compound stmt with the
+    // label in it.
+    
+    // Give the label a sub-statement.
+    L->setSubStmt(new (Context) NullStmt(L->getIdentLoc()));
+      
+    std::vector<Stmt*> Elements(Body->body_begin(), Body->body_end());
+    Elements.push_back(L);
+    Body->setStmts(Context, &Elements[0], Elements.size());
   }
   LabelMap.clear();
 





More information about the cfe-commits mailing list