[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