https://github.com/TPPPP72 created 
https://github.com/llvm/llvm-project/pull/200214

When the TST is in a struct and fails to close successfully, roll back the 
global state to avoid incorrectly resolving the new struct declaration.

fix #118061 

>From fbeb300131183e951bb1342097f78012f4f0c211 Mon Sep 17 00:00:00 2001
From: TPPPP <[email protected]>
Date: Fri, 29 May 2026 00:01:27 +0800
Subject: [PATCH] [Clang] Fixed an assertion failure in constant evaluation/AST
 parsing when encountering malformed struct and enum declarations with missing
 closing braces

---
 clang/docs/ReleaseNotes.rst    |  1 +
 clang/lib/Parse/ParseExpr.cpp  | 12 +++++++++++-
 clang/test/Parser/gh118061.cpp | 16 ++++++++++++++++
 3 files changed, 28 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Parser/gh118061.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 11cce36a0906c..74f4fcd3ca63d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -648,6 +648,7 @@ Bug Fixes in This Version
   an array via an element-at-a-time copy loop (#GH192026)
 - Fixed an issue where certain designated initializers would be rejected for 
constexpr variables. (#GH193373)
 - Fixed a crash when ``#embed`` is used with C++ modules (#GH195350)
+- Fixed an assertion failure in constant evaluation/AST parsing when 
encountering malformed struct and enum declarations with missing closing 
braces. (#GH118061)
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index e38481f05da63..631c74204e85f 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -2807,6 +2807,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, 
bool StopIfCastExpr,
       return res;
     }
 
+    TentativeParsingAction TPA(*this);
     // Parse the type declarator.
     DeclSpec DS(AttrFactory);
     ParseSpecifierQualifierList(DS);
@@ -2820,6 +2821,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, 
bool StopIfCastExpr,
     if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) &&
         !InMessageExpression && getLangOpts().ObjC &&
         (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) {
+      TPA.Commit();
       TypeResult Ty;
       {
         InMessageExpressionRAIIObject InMessage(*this, false);
@@ -2830,9 +2832,17 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, 
bool StopIfCastExpr,
                                               Ty.get(), nullptr);
     } else {
       // Match the ')'.
-      T.consumeClose();
+      bool MissingCloseParen = T.consumeClose();
       ColonProtection.restore();
       RParenLoc = T.getCloseLocation();
+
+      if (MissingCloseParen && DS.getTypeSpecType() == DeclSpec::TST_struct) {
+        TPA.Revert();
+        return ExprError();
+      }
+
+      TPA.Commit();
+
       if (ParenBehavior == ParenExprKind::Unknown && Tok.is(tok::l_brace)) {
         ExprType = ParenParseOption::CompoundLiteral;
         TypeResult Ty;
diff --git a/clang/test/Parser/gh118061.cpp b/clang/test/Parser/gh118061.cpp
new file mode 100644
index 0000000000000..a753a64ff453b
--- /dev/null
+++ b/clang/test/Parser/gh118061.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// expected-warning@+2 {{declaration does not declare anything}}
+// expected-error@+1 {{anonymous structs and classes must be class members}}
+struct {
+    // expected-error@+1 {{types cannot be declared in an anonymous struct}}
+    enum b {
+        c = (struct d
+    // expected-error@-1 {{expected ';' after struct}}
+    // expected-note@-2 {{to match this '('}}
+};
+// expected-error@-1 {{expected ')'}}
+// expected-error@-2 {{expected ';' after enum}}
+
+struct d {
+};

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to