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

via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 3 23:03:08 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Fan Mo (w007878)

<details>
<summary>Changes</summary>

fixes #<!-- -->201490 

In the code here https://github.com/llvm/llvm-project/blob/b29352f7ea1d46fa7d90900d7a279851b6de9f74/clang/lib/Sema/SemaTemplate.cpp#L2196-L2206

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/201506.diff


2 Files Affected:

- (modified) clang/lib/Sema/SemaTemplate.cpp (+3-2) 
- (added) clang/test/SemaTemplate/GH201490.cpp (+10) 


``````````diff
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 8c94a1ad39208..23d47249dfd88 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2247,9 +2247,10 @@ DeclResult Sema::CheckClassTemplate(
     NewTemplate->setModulePrivate();
 
   if (IsMemberSpecialization) {
-    assert(PrevClassTemplate &&
+    assert((PrevClassTemplate || Invalid) &&
            "Member specialization without a primary template?");
-    NewTemplate->setMemberSpecialization();
+    if (PrevClassTemplate)
+      NewTemplate->setMemberSpecialization();
   }
 
   // Set the access specifier.
diff --git a/clang/test/SemaTemplate/GH201490.cpp b/clang/test/SemaTemplate/GH201490.cpp
new file mode 100644
index 0000000000000..13f05a56f41ab
--- /dev/null
+++ b/clang/test/SemaTemplate/GH201490.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// regression test for https://github.com/llvm/llvm-project/issues/201490
+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 'A<int>'}}
+
+// A legitimate member class template explicit specialization
+template<class T> struct C { template<class U> struct D; };
+  template<> template<class U> struct C<int>::D {};

``````````

</details>


https://github.com/llvm/llvm-project/pull/201506


More information about the cfe-commits mailing list