fix PR6034, a crash on invalid where the switch stack would get

unbalanced.

llvm-svn: 94347
This commit is contained in:
Chris Lattner 2010-01-24 01:50:29 +00:00
parent 11092645da
commit 8fd2d01118
5 changed files with 33 additions and 8 deletions

View File

@ -808,6 +808,11 @@ public:
return StmtEmpty();
}
/// ActOnSwitchBodyError - This is called if there is an error parsing the
/// body of the switch stmt instead of ActOnFinishSwitchStmt.
virtual void ActOnSwitchBodyError(SourceLocation SwitchLoc, StmtArg Switch,
StmtArg Body) {}
virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
StmtArg Switch, StmtArg Body) {
return StmtEmpty();

View File

@ -741,19 +741,19 @@ Parser::OwningStmtResult Parser::ParseSwitchStatement(AttributeList *Attr) {
// Read the body statement.
OwningStmtResult Body(ParseStatement());
// Pop the body scope if needed.
// Pop the scopes.
InnerScope.Exit();
if (Body.isInvalid()) {
Body = Actions.ActOnNullStmt(Tok.getLocation());
// FIXME: Remove the case statement list from the Switch statement.
}
SwitchScope.Exit();
if (Cond.isInvalid() && !CondVar.get())
if (Cond.isInvalid() && !CondVar.get()) {
Actions.ActOnSwitchBodyError(SwitchLoc, move(Switch), move(Body));
return StmtError();
}
if (Body.isInvalid())
// FIXME: Remove the case statement list from the Switch statement.
Body = Actions.ActOnNullStmt(Tok.getLocation());
return Actions.ActOnFinishSwitchStmt(SwitchLoc, move(Switch), move(Body));
}

View File

@ -1373,6 +1373,8 @@ public:
SourceLocation ElseLoc, StmtArg ElseVal);
virtual OwningStmtResult ActOnStartOfSwitchStmt(FullExprArg Cond,
DeclPtrTy CondVar);
virtual void ActOnSwitchBodyError(SourceLocation SwitchLoc, StmtArg Switch,
StmtArg Body);
virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
StmtArg Switch, StmtArg Body);
virtual OwningStmtResult ActOnWhileStmt(SourceLocation WhileLoc,

View File

@ -482,6 +482,16 @@ static bool CheckCXXSwitchCondition(Sema &S, SourceLocation SwitchLoc,
return false;
}
/// ActOnSwitchBodyError - This is called if there is an error parsing the
/// body of the switch stmt instead of ActOnFinishSwitchStmt.
void Sema::ActOnSwitchBodyError(SourceLocation SwitchLoc, StmtArg Switch,
StmtArg Body) {
// Keep the switch stack balanced.
assert(getSwitchStack().back() == (SwitchStmt*)Switch.get() &&
"switch stack missing push/pop!");
getSwitchStack().pop_back();
}
Action::OwningStmtResult
Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch,
StmtArg Body) {

View File

@ -33,3 +33,11 @@ void *test10() {
bar:
return &&bar; // expected-warning {{returning address of label, which is local}}
}
// PR6034
void test11(int bit) {
switch (bit)
switch (env->fpscr) // expected-error {{use of undeclared identifier 'env'}}
{
}
}