[clang] c6d86b6 - Properly collect template arguments from a class-scope function template
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 10 15:55:32 PST 2020
Author: Richard Smith
Date: 2020-11-10T15:55:19-08:00
New Revision: c6d86b6b45a8e40457286c78321a4680b459e800
URL: https://github.com/llvm/llvm-project/commit/c6d86b6b45a8e40457286c78321a4680b459e800
DIFF: https://github.com/llvm/llvm-project/commit/c6d86b6b45a8e40457286c78321a4680b459e800.diff
LOG: 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).
Added:
clang/test/SemaTemplate/instantiate-member-specialization.cpp
Modified:
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaTemplateInstantiate.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 28883955660c..99a3e77e3cfc 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -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);
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 03670e2145c1..0b7fe0ca0672 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -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);
diff --git a/clang/test/SemaTemplate/instantiate-member-specialization.cpp b/clang/test/SemaTemplate/instantiate-member-specialization.cpp
new file mode 100644
index 000000000000..b9bc243985a8
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-member-specialization.cpp
@@ -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);
+}
More information about the cfe-commits
mailing list