Author: Fan Mo
Date: 2026-06-22T11:58:59+08:00
New Revision: 72b891b75f85cd8be4ac125f36f1bc9a97c8e185

URL: 
https://github.com/llvm/llvm-project/commit/72b891b75f85cd8be4ac125f36f1bc9a97c8e185
DIFF: 
https://github.com/llvm/llvm-project/commit/72b891b75f85cd8be4ac125f36f1bc9a97c8e185.diff

LOG: [clang] Avoid assertion on invalid member template specialization (#201506)

fixes #201490 

It would be possible to have `PrevClassTemplate == false` when `SS` was
invalid.

Since it is already invalid, it would be safe to skip
`setMemberSpecialization` for `NewTemplate`. When the qualified scope
specifier is invalid, Sema may have already diagnosed the declaration
and marked it invalid. In that case there may be no previous class
template declaration, so the assertion is too strong. Avoid marking the
new declaration as a member specialization unless the previous class
template exists.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaTemplate.cpp
    clang/test/SemaTemplate/instantiate-member-template.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 69687db1bbedd..37428df0974f4 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -846,6 +846,7 @@ Miscellaneous Clang Crashes Fixed
 - Fixed an assertion failure in ``isAtEndOfMacroExpansion`` on macro 
expansions crossing the boundary of two fileIDs. (#GH115007), (#GH21755)
 - Fixed an assertion failure when ``__builtin_dump_struct`` is used with an
   immediate-escalated callable. (#GH192846)
+- Fixed a crash when diagnosing an invalid out-of-line definition of a member 
class template. (#GH201490)
 
 OpenACC Specific Changes
 ------------------------

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 8c94a1ad39208..556fa716d61e7 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2246,7 +2246,7 @@ DeclResult Sema::CheckClassTemplate(
   if (ModulePrivateLoc.isValid())
     NewTemplate->setModulePrivate();
 
-  if (IsMemberSpecialization) {
+  if (!Invalid && IsMemberSpecialization) {
     assert(PrevClassTemplate &&
            "Member specialization without a primary template?");
     NewTemplate->setMemberSpecialization();

diff  --git a/clang/test/SemaTemplate/instantiate-member-template.cpp 
b/clang/test/SemaTemplate/instantiate-member-template.cpp
index 4c74f5fb938b6..3e1b9d16202b4 100644
--- a/clang/test/SemaTemplate/instantiate-member-template.cpp
+++ b/clang/test/SemaTemplate/instantiate-member-template.cpp
@@ -259,3 +259,9 @@ namespace rdar8986308 {
   }
 
 }
+
+namespace GH201490 {
+  template<class T> struct A {};
+  template<class T> struct B : A<T> {};
+  template<> template<class T> class A<int>::B {}; // 
expected-error{{out-of-line definition of 'B' does not match any declaration in 
'GH201490::A<int>'}}
+}


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

Reply via email to