diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ddeb1186d65ac..46f4b82b89e48 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -702,6 +702,9 @@ Bug Fixes in This Version - Fix assertion failure when initializing union containing struct with flexible array member using empty initializer list. Fixes (`#77085 `_) +- Fix assertion crash due to failed scope restoring caused by too-early VarDecl + invalidation by invalid initializer Expr. + Fixes (`#30908 `_) Bug Fixes to Compiler Builtins diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index b60ae293ef8c2..ed684c5d57b1e 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -2661,7 +2661,12 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( // ProduceConstructorSignatureHelp only on VarDecls. ExpressionStarts = SetPreferredType; } - if (ParseExpressionList(Exprs, ExpressionStarts)) { + + bool SawError = ParseExpressionList(Exprs, ExpressionStarts); + + InitScope.pop(); + + if (SawError) { if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) { Actions.ProduceConstructorSignatureHelp( ThisVarDecl->getType()->getCanonicalTypeInternal(), @@ -2674,7 +2679,6 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( } else { // Match the ')'. T.consumeClose(); - InitScope.pop(); ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(), T.getCloseLocation(), diff --git a/clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init-1.cpp b/clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init-1.cpp new file mode 100644 index 0000000000000..1a692fe8ff1e7 --- /dev/null +++ b/clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init-1.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -ferror-limit 2 -fsyntax-only -verify %s + +// expected-error@* {{too many errors emitted}} + +namespace llvm { +namespace Hexagon {} +} +void set() { + Hexagon::NoRegister; + // expected-error@-1 {{use of undeclared identifier}} + // expected-note@-5 {{declared here}} + // expected-error@-3 {{no member named 'NoRegister' in namespace}} +} +template struct pair { pair(int, int); }; +struct HexagonMCChecker { + static pair Unconditional; + void checkRegisters(); +}; +pair HexagonMCChecker::Unconditional(Hexagon::NoRegister, 0); +void HexagonMCChecker::checkRegisters() {} diff --git a/clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init-2.cpp b/clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init-2.cpp new file mode 100644 index 0000000000000..02200ce4f34a7 --- /dev/null +++ b/clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init-2.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#include // expected-error {{file not found}} + +class S {}; + +template +class E { +public: + E(S* scope) {} + S &getS(); +}; + +class Z { + private: + static E e; + static S& s(); +}; + +E Z::e(&__UNKNOWN_ID__); + +S& Z::s() { return Z::e.getS(); }