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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to