[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