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
