diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 380c3b956e6d..59ca525d1f5f 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -1015,7 +1015,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return SwitchLoc; } SourceLocation getLocEnd() const LLVM_READONLY { - return SubExprs[BODY]->getLocEnd(); + return SubExprs[BODY] ? SubExprs[BODY]->getLocEnd() : SubExprs[COND]->getLocEnd(); } // Iterators diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 8f6c5c6fe349..0c3bfd50acf1 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -730,9 +730,10 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, assert(SS == getCurFunction()->SwitchStack.back() && "switch stack missing push/pop!"); + getCurFunction()->SwitchStack.pop_back(); + if (!BodyStmt) return StmtError(); SS->setBody(BodyStmt, SwitchLoc); - getCurFunction()->SwitchStack.pop_back(); Expr *CondExpr = SS->getCond(); if (!CondExpr) return StmtError(); diff --git a/clang/test/Parser/switch-recovery.cpp b/clang/test/Parser/switch-recovery.cpp index 534517018267..4b06d55ba594 100644 --- a/clang/test/Parser/switch-recovery.cpp +++ b/clang/test/Parser/switch-recovery.cpp @@ -220,3 +220,12 @@ bool bar0() { case bar5: ; // expected-error{{use of undeclared identifier 'bar5'}} } } + +namespace pr21841 { +void fn1() { + switch (0) + switch (0 // expected-note{{to match this '('}} + { // expected-error{{expected ')'}} + } +} // expected-error{{expected statement}} +}