Mordante updated this revision to Diff 218256.
Mordante added a comment.

Changed the approach to use `addInstantiatedParametersToScope` as suggested by 
@rsmith. Since the function was `static` in another file I made it a member of 
`LocalInstantiationScope` and adjusted all callers.

Minor changes:

- Unit test remove link to Bugzilla
- MutiLevelArgList -> Mu__l__tiLevelArgList


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D65694/new/

https://reviews.llvm.org/D65694

Files:
  clang/include/clang/Sema/Template.h
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/SemaTemplate/default-arguments-cxx0x.cpp

Index: clang/test/SemaTemplate/default-arguments-cxx0x.cpp
===================================================================
--- clang/test/SemaTemplate/default-arguments-cxx0x.cpp
+++ clang/test/SemaTemplate/default-arguments-cxx0x.cpp
@@ -114,3 +114,33 @@
     S<int> _a{};
   };
 }
+
+// Failure to resolve the decltype part during instantiation caused an
+// assertion failure
+namespace PR28500 {
+namespace original {
+template <class T>
+void bar(T t = [](decltype(t) i) { return 0; }(0)) {}
+void foo() {
+  bar<int>();
+}
+} // namespace original
+
+namespace cast {
+template <class T>
+void bar(T t = decltype(t)(0)) {}
+void foo() {
+  bar<int>();
+  bar<double>();
+}
+} // namespace cast
+
+namespace value {
+template <class T>
+void bar(T t = decltype(t)()) {}
+void foo() {
+  bar<int>();
+  bar<double>();
+}
+} // namespace value
+} // namespace PR28500
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3823,70 +3823,6 @@
   return NewTInfo;
 }
 
-/// Introduce the instantiated function parameters into the local
-/// instantiation scope, and set the parameter names to those used
-/// in the template.
-static bool addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function,
-                                             const FunctionDecl *PatternDecl,
-                                             LocalInstantiationScope &Scope,
-                           const MultiLevelTemplateArgumentList &TemplateArgs) {
-  unsigned FParamIdx = 0;
-  for (unsigned I = 0, N = PatternDecl->getNumParams(); I != N; ++I) {
-    const ParmVarDecl *PatternParam = PatternDecl->getParamDecl(I);
-    if (!PatternParam->isParameterPack()) {
-      // Simple case: not a parameter pack.
-      assert(FParamIdx < Function->getNumParams());
-      ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx);
-      FunctionParam->setDeclName(PatternParam->getDeclName());
-      // If the parameter's type is not dependent, update it to match the type
-      // in the pattern. They can differ in top-level cv-qualifiers, and we want
-      // the pattern's type here. If the type is dependent, they can't differ,
-      // per core issue 1668. Substitute into the type from the pattern, in case
-      // it's instantiation-dependent.
-      // FIXME: Updating the type to work around this is at best fragile.
-      if (!PatternDecl->getType()->isDependentType()) {
-        QualType T = S.SubstType(PatternParam->getType(), TemplateArgs,
-                                 FunctionParam->getLocation(),
-                                 FunctionParam->getDeclName());
-        if (T.isNull())
-          return true;
-        FunctionParam->setType(T);
-      }
-
-      Scope.InstantiatedLocal(PatternParam, FunctionParam);
-      ++FParamIdx;
-      continue;
-    }
-
-    // Expand the parameter pack.
-    Scope.MakeInstantiatedLocalArgPack(PatternParam);
-    Optional<unsigned> NumArgumentsInExpansion
-      = S.getNumArgumentsInExpansion(PatternParam->getType(), TemplateArgs);
-    if (NumArgumentsInExpansion) {
-      QualType PatternType =
-          PatternParam->getType()->castAs<PackExpansionType>()->getPattern();
-      for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg) {
-        ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx);
-        FunctionParam->setDeclName(PatternParam->getDeclName());
-        if (!PatternDecl->getType()->isDependentType()) {
-          Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(S, Arg);
-          QualType T = S.SubstType(PatternType, TemplateArgs,
-                                   FunctionParam->getLocation(),
-                                   FunctionParam->getDeclName());
-          if (T.isNull())
-            return true;
-          FunctionParam->setType(T);
-        }
-
-        Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam);
-        ++FParamIdx;
-      }
-    }
-  }
-
-  return false;
-}
-
 void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation,
                                     FunctionDecl *Decl) {
   const FunctionProtoType *Proto = Decl->getType()->castAs<FunctionProtoType>();
@@ -3918,8 +3854,7 @@
     getTemplateInstantiationArgs(Decl, nullptr, /*RelativeToPrimary*/true);
 
   FunctionDecl *Template = Proto->getExceptionSpecTemplate();
-  if (addInstantiatedParametersToScope(*this, Decl, Template, Scope,
-                                       TemplateArgs)) {
+  if (Scope.addInstantiatedParameters(Decl, Template, TemplateArgs)) {
     UpdateExceptionSpec(Decl, EST_None);
     return;
   }
@@ -4270,8 +4205,7 @@
     // PushDeclContext because we don't have a scope.
     Sema::ContextRAII savedContext(*this, Function);
 
-    if (addInstantiatedParametersToScope(*this, Function, PatternDecl, Scope,
-                                         TemplateArgs))
+    if (Scope.addInstantiatedParameters(Function, PatternDecl, TemplateArgs))
       return;
 
     StmtResult Body;
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -3063,3 +3063,64 @@
 
   return nullptr;
 }
+
+bool LocalInstantiationScope::addInstantiatedParameters(
+    FunctionDecl *Function, const FunctionDecl *PatternDecl,
+    const MultiLevelTemplateArgumentList &TemplateArgs) {
+  unsigned FParamIdx = 0;
+  for (unsigned I = 0, N = PatternDecl->getNumParams(); I != N; ++I) {
+    const ParmVarDecl *PatternParam = PatternDecl->getParamDecl(I);
+    if (!PatternParam->isParameterPack()) {
+      // Simple case: not a parameter pack.
+      assert(FParamIdx < Function->getNumParams());
+      ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx);
+      FunctionParam->setDeclName(PatternParam->getDeclName());
+      // If the parameter's type is not dependent, update it to match the type
+      // in the pattern. They can differ in top-level cv-qualifiers, and we want
+      // the pattern's type here. If the type is dependent, they can't differ,
+      // per core issue 1668. Substitute into the type from the pattern, in case
+      // it's instantiation-dependent.
+      // FIXME: Updating the type to work around this is at best fragile.
+      if (!PatternDecl->getType()->isDependentType()) {
+        QualType T = SemaRef.SubstType(PatternParam->getType(), TemplateArgs,
+                                       FunctionParam->getLocation(),
+                                       FunctionParam->getDeclName());
+        if (T.isNull())
+          return true;
+        FunctionParam->setType(T);
+      }
+
+      InstantiatedLocal(PatternParam, FunctionParam);
+      ++FParamIdx;
+      continue;
+    }
+
+    // Expand the parameter pack.
+    MakeInstantiatedLocalArgPack(PatternParam);
+    Optional<unsigned> NumArgumentsInExpansion =
+        SemaRef.getNumArgumentsInExpansion(PatternParam->getType(),
+                                           TemplateArgs);
+    if (NumArgumentsInExpansion) {
+      QualType PatternType =
+          PatternParam->getType()->castAs<PackExpansionType>()->getPattern();
+      for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg) {
+        ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx);
+        FunctionParam->setDeclName(PatternParam->getDeclName());
+        if (!PatternDecl->getType()->isDependentType()) {
+          Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, Arg);
+          QualType T = SemaRef.SubstType(PatternType, TemplateArgs,
+                                   FunctionParam->getLocation(),
+                                   FunctionParam->getDeclName());
+          if (T.isNull())
+            return true;
+          FunctionParam->setType(T);
+        }
+
+        InstantiatedLocalPackArg(PatternParam, FunctionParam);
+        ++FParamIdx;
+      }
+    }
+  }
+
+  return false;
+}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -4811,11 +4811,11 @@
     //
     // template<typename T>
     // A<T> Foo(int a = A<T>::FooImpl());
-    MultiLevelTemplateArgumentList MutiLevelArgList
+    MultiLevelTemplateArgumentList MultiLevelArgList
       = getTemplateInstantiationArgs(FD, nullptr, /*RelativeToPrimary=*/true);
 
     InstantiatingTemplate Inst(*this, CallLoc, Param,
-                               MutiLevelArgList.getInnermost());
+                               MultiLevelArgList.getInnermost());
     if (Inst.isInvalid())
       return true;
     if (Inst.isAlreadyInstantiating()) {
@@ -4832,7 +4832,13 @@
       //   default argument expression appears.
       ContextRAII SavedContext(*this, FD);
       LocalInstantiationScope Local(*this);
-      Result = SubstInitializer(UninstExpr, MutiLevelArgList,
+
+      const FunctionDecl *PatternDecl = FD->getTemplateInstantiationPattern();
+      if (!PatternDecl)
+        PatternDecl = FD;
+
+      Local.addInstantiatedParameters(FD, PatternDecl, MultiLevelArgList);
+      Result = SubstInitializer(UninstExpr, MultiLevelArgList,
                                 /*DirectInit*/false);
     }
     if (Result.isInvalid())
Index: clang/include/clang/Sema/Template.h
===================================================================
--- clang/include/clang/Sema/Template.h
+++ clang/include/clang/Sema/Template.h
@@ -412,6 +412,13 @@
     NamedDecl *
     getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr,
                                 unsigned *NumExplicitArgs = nullptr) const;
+
+    /// Introduce the instantiated function parameters into the local
+    /// instantiation scope, and set the parameter names to those used
+    /// in the template.
+    bool addInstantiatedParameters(
+        FunctionDecl *Function, const FunctionDecl *PatternDecl,
+        const MultiLevelTemplateArgumentList &TemplateArgs);
   };
 
   class TemplateDeclInstantiator
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D65694: P... Nicholas Allegra via Phabricator via cfe-commits
    • [PATCH] D656... Richard Smith - zygoloid via Phabricator via cfe-commits
    • [PATCH] D656... Mark de Wever via Phabricator via cfe-commits
    • [PATCH] D656... Nicholas Allegra via Phabricator via cfe-commits

Reply via email to