From 90786adade22784a52856a0e8b545ec6710b47f6 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski Date: Wed, 30 Oct 2024 12:50:40 -0600 Subject: [Clang][Sema] Always use latest redeclaration of primary template (#114258) This patch fixes a couple of regressions introduced in #111852. Consider: ``` template struct A { template static constexpr bool f() requires U { return true; } }; template<> template constexpr bool A::f() requires U { return A::f(); } template<> template constexpr bool A::f() requires U { return true; } static_assert(A::f()); // crash here ``` This crashes because when collecting template arguments from the _first_ declaration of `A::f` for constraint checking, we don't add the template arguments from the enclosing class template specialization because there exists another redeclaration that is a member specialization. This also fixes the following example, which happens for a similar reason: ``` // input.cppm export module input; export template constexpr int f(); template struct A { template friend constexpr int f(); }; template struct A<0>; template constexpr int f() { return N; } ``` ``` // input.cpp import input; static_assert(f<1>() == 1); // error: static assertion failed ``` --- clang/lib/Sema/SemaTemplateInstantiate.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'clang/lib/Sema/SemaTemplateInstantiate.cpp') diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index b630638..de0ec01 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -343,7 +343,7 @@ struct TemplateInstantiationArgumentCollecter // If this function was instantiated from a specialized member that is // a function template, we're done. assert(FD->getPrimaryTemplate() && "No function template?"); - if (FD->getPrimaryTemplate()->hasMemberSpecialization()) + if (FD->getPrimaryTemplate()->isMemberSpecialization()) return Done(); // If this function is a generic lambda specialization, we are done. @@ -442,11 +442,11 @@ struct TemplateInstantiationArgumentCollecter Specialized = CTSD->getSpecializedTemplateOrPartial(); if (auto *CTPSD = Specialized.dyn_cast()) { - if (CTPSD->hasMemberSpecialization()) + if (CTPSD->isMemberSpecialization()) return Done(); } else { auto *CTD = Specialized.get(); - if (CTD->hasMemberSpecialization()) + if (CTD->isMemberSpecialization()) return Done(); } return UseNextDecl(CTSD); @@ -478,11 +478,11 @@ struct TemplateInstantiationArgumentCollecter Specialized = VTSD->getSpecializedTemplateOrPartial(); if (auto *VTPSD = Specialized.dyn_cast()) { - if (VTPSD->hasMemberSpecialization()) + if (VTPSD->isMemberSpecialization()) return Done(); } else { auto *VTD = Specialized.get(); - if (VTD->hasMemberSpecialization()) + if (VTD->isMemberSpecialization()) return Done(); } return UseNextDecl(VTSD); @@ -4141,7 +4141,7 @@ getPatternForClassTemplateSpecialization( CXXRecordDecl *Pattern = nullptr; Specialized = ClassTemplateSpec->getSpecializedTemplateOrPartial(); if (auto *CTD = Specialized.dyn_cast()) { - while (!CTD->hasMemberSpecialization()) { + while (!CTD->isMemberSpecialization()) { if (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) CTD = NewCTD; else @@ -4151,7 +4151,7 @@ getPatternForClassTemplateSpecialization( } else if (auto *CTPSD = Specialized .dyn_cast()) { - while (!CTPSD->hasMemberSpecialization()) { + while (!CTPSD->isMemberSpecialization()) { if (auto *NewCTPSD = CTPSD->getInstantiatedFromMemberTemplate()) CTPSD = NewCTPSD; else -- cgit v1.1