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

Reply via email to