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

In addition to the existing conflict detection in `DeclSpec`, the state of 
`TypeScope` has been cleared to prevent erroneous data from leaking downstream.
close #187664 

>From ce74cc60402e532c8086973d3b1969a6684b6670 Mon Sep 17 00:00:00 2001
From: TPPPP72 <[email protected]>
Date: Sun, 12 Apr 2026 15:09:48 +0800
Subject: [PATCH] [Clang] Fix crash when type-name is combined with class
 specifier in template argument

---
 clang/docs/ReleaseNotes.rst          |  1 +
 clang/lib/Sema/DeclSpec.cpp          |  7 +++++++
 clang/test/SemaTemplate/gh187664.cpp | 14 ++++++++++++++
 3 files changed, 22 insertions(+)
 create mode 100644 clang/test/SemaTemplate/gh187664.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index fd58d7847717c..1d138c85f051f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -456,6 +456,7 @@ Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 - Fixed a bug where explicit nullability property attributes were not stored 
in AST nodes in Objective-C. (#GH179703)
 - Fixed a crash when parsing Doxygen ``@param`` commands attached to invalid 
declarations or non-function entities. (#GH182737)
+- Fixed a crash when a type-name is incorrectly combined with a class 
specifier within a template default argument. (#GH187664)
 
 Miscellaneous Bug Fixes
 ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index 660b1805c450e..e988c804eec25 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -761,6 +761,7 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation 
TagKwLoc,
   if (TypeSpecType != TST_unspecified) {
     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
     DiagID = diag::err_invalid_decl_spec_combination;
+    TypeScope.clear();
     return true;
   }
   TypeSpecType = T;
@@ -792,6 +793,7 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
   if (TypeSpecType != TST_unspecified) {
     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
     DiagID = diag::err_invalid_decl_spec_combination;
+    TypeScope.clear();
     return true;
   }
   TypeSpecType = T;
@@ -824,6 +826,7 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation 
TagKwLoc,
   if (TypeSpecType != TST_unspecified) {
     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
     DiagID = diag::err_invalid_decl_spec_combination;
+    TypeScope.clear();
     return true;
   }
   TypeSpecType = T;
@@ -854,6 +857,7 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
   if (TypeSpecType != TST_unspecified) {
     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
     DiagID = diag::err_invalid_decl_spec_combination;
+    TypeScope.clear();
     return true;
   }
   TSTLoc = Loc;
@@ -888,6 +892,7 @@ bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, 
SourceLocation Loc,
   if (TypeSpecType != TST_unspecified) {
     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
     DiagID = diag::err_invalid_vector_decl_spec_combination;
+    TypeScope.clear();
     return true;
   }
   TypeAltiVecVector = isAltiVecVector;
@@ -903,6 +908,7 @@ bool DeclSpec::SetTypePipe(bool isPipe, SourceLocation Loc,
   if (TypeSpecType != TST_unspecified) {
     PrevSpec = DeclSpec::getSpecifierName((TST)TypeSpecType, Policy);
     DiagID = diag::err_invalid_decl_spec_combination;
+    TypeScope.clear();
     return true;
   }
 
@@ -964,6 +970,7 @@ bool DeclSpec::SetBitIntType(SourceLocation KWLoc, Expr 
*BitsExpr,
   if (TypeSpecType != TST_unspecified) {
     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
     DiagID = diag::err_invalid_decl_spec_combination;
+    TypeScope.clear();
     return true;
   }
 
diff --git a/clang/test/SemaTemplate/gh187664.cpp 
b/clang/test/SemaTemplate/gh187664.cpp
new file mode 100644
index 0000000000000..441671c543f7e
--- /dev/null
+++ b/clang/test/SemaTemplate/gh187664.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fblocks -fsyntax-only -verify %s
+
+class A {
+public:
+    class B {};
+};
+
+using X = A::B;
+
+class C {
+    template <typename T = X class A::B> void f();
+    // expected-error@-1 {{cannot combine with previous 'type-name' 
declaration specifier}}
+    // expected-error@-2 {{expected ',' or '>' in template-parameter-list}}
+};

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

Reply via email to