https://github.com/Cons-Cat updated https://github.com/llvm/llvm-project/pull/198948
>From 4519ce28f10eb48f0fe600a1b4f6ed1778acd53f Mon Sep 17 00:00:00 2001 From: Lilian Gooch <[email protected]> Date: Wed, 20 May 2026 17:08:30 -0700 Subject: [PATCH] [clang] Accept __typeof_unqual in block scope in C++ The C++ tentative parser and simple-type-specifier paths enumerated tok::kw_typeof but not tok::kw_typeof_unqual, so block-scope uses of __typeof_unqual / __typeof_unqual__ failed to disambiguate as a declaration: __typeof_unqual(int) x = 0; // worked at file scope int main() { __typeof_unqual(int) x = 0; // rejected } Treat both tokens the same way in those paths, for symmetry with __typeof__. Assisted-by: Cursor/Claude Opus --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Parse/ParseExpr.cpp | 1 + clang/lib/Parse/ParseExprCXX.cpp | 1 + clang/lib/Parse/ParseTentative.cpp | 8 ++++++-- clang/test/SemaCXX/typeof.cpp | 8 ++++++++ 5 files changed, 17 insertions(+), 2 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index cf16e40d026c3..048cfffada200 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -605,6 +605,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 issue where ``__typeof_unqual`` and ``__typeof_unqual__`` were rejected as a declaration specifier in block scope in C++. Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index e38481f05da63..2987d32d6e0d2 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1343,6 +1343,7 @@ Parser::ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand, case tok::kw_auto: case tok::kw_typename: case tok::kw_typeof: + case tok::kw_typeof_unqual: case tok::kw___vector: case tok::kw__Accum: case tok::kw__Fract: diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 5646597622832..ae49fc20e36f2 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -2173,6 +2173,7 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { // GNU typeof support. case tok::kw_typeof: + case tok::kw_typeof_unqual: ParseTypeofSpecifier(DS); DS.Finish(Actions, Policy); return; diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index f77b1001332fe..1477fc38bcc6d 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -171,6 +171,7 @@ Parser::TPResult Parser::TryConsumeDeclarationSpecifier() { } [[fallthrough]]; case tok::kw_typeof: + case tok::kw_typeof_unqual: case tok::kw___attribute: #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: #include "clang/Basic/TransformTypeTraits.def" @@ -1525,7 +1526,8 @@ Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename, return TPResult::True; // GNU typeof support. - case tok::kw_typeof: { + case tok::kw_typeof: + case tok::kw_typeof_unqual: { if (NextToken().isNot(tok::l_paren)) return TPResult::True; @@ -1590,6 +1592,7 @@ bool Parser::isCXXDeclarationSpecifierAType() { case tok::annot_template_id: case tok::annot_typename: case tok::kw_typeof: + case tok::kw_typeof_unqual: #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: #include "clang/Basic/TransformTypeTraits.def" return true; @@ -1650,7 +1653,8 @@ bool Parser::isCXXDeclarationSpecifierAType() { } Parser::TPResult Parser::TryParseTypeofSpecifier() { - assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!"); + assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) && + "Expected 'typeof' or 'typeof_unqual'!"); ConsumeToken(); assert(Tok.is(tok::l_paren) && "Expected '('"); diff --git a/clang/test/SemaCXX/typeof.cpp b/clang/test/SemaCXX/typeof.cpp index 421cfc59f5311..4db803564309b 100644 --- a/clang/test/SemaCXX/typeof.cpp +++ b/clang/test/SemaCXX/typeof.cpp @@ -11,3 +11,11 @@ namespace GH97646 { !x; } } + +// Ensure that __typeof_unqual / __typeof_unqual__ parse as a declaration +// specifier in block scope, for symmetry with __typeof__. +void block_scope_typeof_unqual() { + __typeof_unqual(int) a = 0; + __typeof_unqual__(int) b = 0; + (void)a; (void)b; +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
