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
