[clang] [clang][Parser] Pop scope prior VarDecl invalidating by invalid init (PR #77434)

Ding Fei via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 9 09:25:15 PST 2024


https://github.com/danix800 updated https://github.com/llvm/llvm-project/pull/77434

>From 2f9e45458d21952f9e81cd54297f538d1d04b9f9 Mon Sep 17 00:00:00 2001
From: dingfei <fding at feysh.com>
Date: Tue, 9 Jan 2024 16:40:23 +0800
Subject: [PATCH] [clang][Parser] Pop scope prior VarDecl invalidating by
 invalid direct Init

Invalid (direct) initializer would invalid VarDecl so InitializerScopeRAII
cannot restore scope stack balance.

As with other kind of initializers, InitializerScopeRAII::pop() is moved up
before Sema::ActOnInitializerError() which invalidates the VarDecl, so
scope can be balanced and current DeclContext can be restored.

Fixes #30908
---
 clang/docs/ReleaseNotes.rst                   |  3 +++
 clang/lib/Parse/ParseDecl.cpp                 |  8 +++++--
 ...e-balance-on-invalid-var-direct-init-1.cpp | 20 +++++++++++++++++
 ...e-balance-on-invalid-var-direct-init-2.cpp | 22 +++++++++++++++++++
 4 files changed, 51 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init-1.cpp
 create mode 100644 clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init-2.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ddeb1186d65ac8..46f4b82b89e488 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 <https://github.com/llvm/llvm-project/issues/77085>`_)
+- Fix assertion crash due to failed scope restoring caused by too-early VarDecl
+  invalidation by invalid initializer Expr.
+  Fixes (`#30908 <https://github.com/llvm/llvm-project/issues/30908>`_)
 
 
 Bug Fixes to Compiler Builtins
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index b60ae293ef8c20..ed684c5d57b1ee 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 00000000000000..1a692fe8ff1e72
--- /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 at -1 {{use of undeclared identifier}}
+  // expected-note at -5 {{declared here}}
+  // expected-error at -3 {{no member named 'NoRegister' in namespace}}
+}
+template <class> struct pair { pair(int, int); };
+struct HexagonMCChecker {
+  static pair<int> Unconditional;
+  void checkRegisters();
+};
+pair<int> 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 00000000000000..02200ce4f34a75
--- /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 <non-exist-header> // expected-error {{file not found}}
+
+class S {};
+
+template <typename T>
+class E {
+public:
+  E(S* scope) {}
+  S &getS();
+};
+
+class Z {
+ private:
+  static E<Z> e;
+  static S& s();
+};
+
+E<Z> Z::e(&__UNKNOWN_ID__);
+
+S& Z::s() { return Z::e.getS(); }



More information about the cfe-commits mailing list