forked from OSchip/llvm-project
Properly collect template arguments from a class-scope function template
specialization. Fixes a crash-on-valid if further template parameters are introduced within the specialization (by a generic lambda).
This commit is contained in:
parent
c052510c0b
commit
c6d86b6b45
|
@ -16800,7 +16800,11 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
|
|||
bool FirstInstantiation = PointOfInstantiation.isInvalid();
|
||||
if (FirstInstantiation) {
|
||||
PointOfInstantiation = Loc;
|
||||
Func->setTemplateSpecializationKind(TSK, PointOfInstantiation);
|
||||
if (auto *MSI = Func->getMemberSpecializationInfo())
|
||||
MSI->setPointOfInstantiation(Loc);
|
||||
// FIXME: Notify listener.
|
||||
else
|
||||
Func->setTemplateSpecializationKind(TSK, PointOfInstantiation);
|
||||
} else if (TSK != TSK_ImplicitInstantiation) {
|
||||
// Use the point of use as the point of instantiation, instead of the
|
||||
// point of explicit instantiation (which we track as the actual point
|
||||
|
@ -18040,6 +18044,7 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc,
|
|||
PointOfInstantiation = Loc;
|
||||
if (MSI)
|
||||
MSI->setPointOfInstantiation(PointOfInstantiation);
|
||||
// FIXME: Notify listener.
|
||||
else
|
||||
Var->setTemplateSpecializationKind(TSK, PointOfInstantiation);
|
||||
}
|
||||
|
|
|
@ -141,7 +141,12 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D,
|
|||
TSK_ExplicitSpecialization)
|
||||
break;
|
||||
|
||||
if (const TemplateArgumentList *TemplateArgs
|
||||
if (!RelativeToPrimary && Function->getTemplateSpecializationKind() ==
|
||||
TSK_ExplicitSpecialization) {
|
||||
// This is an implicit instantiation of an explicit specialization. We
|
||||
// don't get any template arguments from this function but might get
|
||||
// some from an enclosing template.
|
||||
} else if (const TemplateArgumentList *TemplateArgs
|
||||
= Function->getTemplateSpecializationArgs()) {
|
||||
// Add the template arguments for this specialization.
|
||||
Result.addOuterTemplateArguments(TemplateArgs);
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// RUN: %clang_cc1 -std=c++20 -verify %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
namespace FunctionTemplate {
|
||||
template<typename> struct S {
|
||||
template<int> auto foo();
|
||||
|
||||
// Check that we don't confuse the depth-1 level-0 parameter of the generic
|
||||
// lambda with the depth-1 level-0 parameter of the primary 'foo' template.
|
||||
template<> constexpr auto foo<1>() {
|
||||
return [](auto x) { return x; };
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(S<void>().template foo<1>()(2) == 2);
|
||||
}
|
Loading…
Reference in New Issue