diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Parse/Action.h | 5 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseStmt.cpp | 16 | ||||
| -rw-r--r-- | clang/lib/Sema/Sema.h | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 10 | ||||
| -rw-r--r-- | clang/test/Sema/statements.c | 8 | 
5 files changed, 33 insertions, 8 deletions
diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index ff33f5039d5..74076c8aef6 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -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(); diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 21e960aa817..88481e8b06c 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -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));  } diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 06e9e3ae9e6..ead9feb48e3 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -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, diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 0c207fa6e87..4653c77c86a 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -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) { diff --git a/clang/test/Sema/statements.c b/clang/test/Sema/statements.c index 3cd2460e79d..6da2daa01ac 100644 --- a/clang/test/Sema/statements.c +++ b/clang/test/Sema/statements.c @@ -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'}} +  { +  } +}  | 

