[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