[llvm-branch-commits] [clang] 9a6f0c2 - Revert two patches to fix GH58452 regression

Tom Stellard via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Mar 9 20:39:09 PST 2023


Author: Erich Keane
Date: 2023-03-09T20:37:39-08:00
New Revision: 9a6f0c20fd2294830acdde714e6cddb2793c504b

URL: https://github.com/llvm/llvm-project/commit/9a6f0c20fd2294830acdde714e6cddb2793c504b
DIFF: https://github.com/llvm/llvm-project/commit/9a6f0c20fd2294830acdde714e6cddb2793c504b.diff

LOG: Revert two patches to fix GH58452 regression

GH58452 is a regression in the 16.0 release branch caused by both:
b8a1b698afb2fc84819c7596090aabf4d826b436 and
3a0309c53674be56b5cfce038d78a0c2c6e2a98c

This patch reverts both of those to make the 'valid' code stop
diagnosing
at the expense of crashes on invalid + unclear diagnostics.

This patch also adds the tests from GH58452 to prevent any
re-application from breaking this again.

Revert "[clang] Improve diagnostics for expansion length mismatch"
This reverts commit 3a0309c53674be56b5cfce038d78a0c2c6e2a98c.
Revert "[clang] fix missing initialization of original number of expansions"
This reverts commit b8a1b698afb2fc84819c7596090aabf4d826b436.

Differential Revision: https://reviews.llvm.org/D145605

(cherry picked from commit acecf68c8b7c3c625cfa00f00f8ddc8f15baae44)

Added: 
    

Modified: 
    clang/include/clang/Sema/Sema.h
    clang/include/clang/Sema/SemaInternal.h
    clang/lib/Sema/SemaTemplateDeduction.cpp
    clang/lib/Sema/SemaTemplateVariadic.cpp
    clang/lib/Sema/TreeTransform.h
    clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
    clang/test/SemaTemplate/cxx1z-fold-expressions.cpp
    clang/test/SemaTemplate/pack-deduction.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 66b018d8fba1a..d40dacb5aa0f8 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -238,11 +238,9 @@ namespace threadSafety {
 
 // FIXME: No way to easily map from TemplateTypeParmTypes to
 // TemplateTypeParmDecls, so we have this horrible PointerUnion.
-using UnexpandedParameterPack = std::pair<
-    llvm::PointerUnion<
-        const TemplateTypeParmType *, const SubstTemplateTypeParmPackType *,
-        const SubstNonTypeTemplateParmPackExpr *, const NamedDecl *>,
-    SourceLocation>;
+typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType *, NamedDecl *>,
+                  SourceLocation>
+    UnexpandedParameterPack;
 
 /// Describes whether we've seen any nullability information for the given
 /// file.

diff  --git a/clang/include/clang/Sema/SemaInternal.h b/clang/include/clang/Sema/SemaInternal.h
index 4eca50919dc7e..842eec099540c 100644
--- a/clang/include/clang/Sema/SemaInternal.h
+++ b/clang/include/clang/Sema/SemaInternal.h
@@ -62,7 +62,7 @@ inline InheritableAttr *getDLLAttr(Decl *D) {
 }
 
 /// Retrieve the depth and index of a template parameter.
-inline std::pair<unsigned, unsigned> getDepthAndIndex(const NamedDecl *ND) {
+inline std::pair<unsigned, unsigned> getDepthAndIndex(NamedDecl *ND) {
   if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(ND))
     return std::make_pair(TTP->getDepth(), TTP->getIndex());
 
@@ -79,7 +79,7 @@ getDepthAndIndex(UnexpandedParameterPack UPP) {
   if (const auto *TTP = UPP.first.dyn_cast<const TemplateTypeParmType *>())
     return std::make_pair(TTP->getDepth(), TTP->getIndex());
 
-  return getDepthAndIndex(UPP.first.get<const NamedDecl *>());
+  return getDepthAndIndex(UPP.first.get<NamedDecl *>());
 }
 
 class TypoCorrectionConsumer : public VisibleDeclConsumer {

diff  --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 9e48a2a35a344..1fe2d3fac6859 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -756,11 +756,8 @@ class PackDeductionScope {
       SmallVector<UnexpandedParameterPack, 2> Unexpanded;
       S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
       for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
-        UnexpandedParameterPack U = Unexpanded[I];
-        if (U.first.is<const SubstTemplateTypeParmPackType *>() ||
-            U.first.is<const SubstNonTypeTemplateParmPackExpr *>())
-          continue;
-        auto [Depth, Index] = getDepthAndIndex(U);
+        unsigned Depth, Index;
+        std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
         if (Depth == Info.getDeducedDepth())
           AddPack(Index);
       }

diff  --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 01a435668d883..86268b504cbb3 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -89,23 +89,6 @@ namespace {
       return true;
     }
 
-    bool
-    VisitSubstTemplateTypeParmPackTypeLoc(SubstTemplateTypeParmPackTypeLoc TL) {
-      Unexpanded.push_back({TL.getTypePtr(), TL.getNameLoc()});
-      return true;
-    }
-
-    bool VisitSubstTemplateTypeParmPackType(SubstTemplateTypeParmPackType *T) {
-      Unexpanded.push_back({T, SourceLocation()});
-      return true;
-    }
-
-    bool
-    VisitSubstNonTypeTemplateParmPackExpr(SubstNonTypeTemplateParmPackExpr *E) {
-      Unexpanded.push_back({E, E->getParameterPackLocation()});
-      return true;
-    }
-
     /// Record occurrences of function and non-type template
     /// parameter packs in an expression.
     bool VisitDeclRefExpr(DeclRefExpr *E) {
@@ -324,8 +307,7 @@ Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
           auto *TTPD = dyn_cast<TemplateTypeParmDecl>(LocalPack);
           return TTPD && TTPD->getTypeForDecl() == TTPT;
         }
-        return declaresSameEntity(Pack.first.get<const NamedDecl *>(),
-                                  LocalPack);
+        return declaresSameEntity(Pack.first.get<NamedDecl *>(), LocalPack);
       };
       if (llvm::any_of(LSI->LocalPacks, DeclaresThisPack))
         LambdaParamPackReferences.push_back(Pack);
@@ -377,7 +359,7 @@ Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
           = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
       Name = TTP->getIdentifier();
     else
-      Name = Unexpanded[I].first.get<const NamedDecl *>()->getIdentifier();
+      Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
 
     if (Name && NamesKnown.insert(Name).second)
       Names.push_back(Name);
@@ -440,7 +422,7 @@ bool Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE) {
   llvm::SmallPtrSet<NamedDecl*, 8> ParmSet(Parms.begin(), Parms.end());
   SmallVector<UnexpandedParameterPack, 2> UnexpandedParms;
   for (auto Parm : Unexpanded)
-    if (ParmSet.contains(Parm.first.dyn_cast<const NamedDecl *>()))
+    if (ParmSet.contains(Parm.first.dyn_cast<NamedDecl *>()))
       UnexpandedParms.push_back(Parm);
   if (UnexpandedParms.empty())
     return false;
@@ -692,95 +674,109 @@ bool Sema::CheckParameterPacksForExpansion(
     bool &RetainExpansion, std::optional<unsigned> &NumExpansions) {
   ShouldExpand = true;
   RetainExpansion = false;
-  std::pair<const IdentifierInfo *, SourceLocation> FirstPack;
-  std::optional<std::pair<unsigned, SourceLocation>> PartialExpansion;
-  std::optional<unsigned> CurNumExpansions;
+  std::pair<IdentifierInfo *, SourceLocation> FirstPack;
+  bool HaveFirstPack = false;
+  std::optional<unsigned> NumPartialExpansions;
+  SourceLocation PartiallySubstitutedPackLoc;
 
-  for (auto [P, Loc] : Unexpanded) {
+  for (UnexpandedParameterPack ParmPack : Unexpanded) {
     // Compute the depth and index for this parameter pack.
-    std::optional<std::pair<unsigned, unsigned>> Pos;
+    unsigned Depth = 0, Index = 0;
+    IdentifierInfo *Name;
+    bool IsVarDeclPack = false;
+
+    if (const TemplateTypeParmType *TTP =
+            ParmPack.first.dyn_cast<const TemplateTypeParmType *>()) {
+      Depth = TTP->getDepth();
+      Index = TTP->getIndex();
+      Name = TTP->getIdentifier();
+    } else {
+      NamedDecl *ND = ParmPack.first.get<NamedDecl *>();
+      if (isa<VarDecl>(ND))
+        IsVarDeclPack = true;
+      else
+        std::tie(Depth, Index) = getDepthAndIndex(ND);
+
+      Name = ND->getIdentifier();
+    }
+
+    // Determine the size of this argument pack.
     unsigned NewPackSize;
-    const auto *ND = P.dyn_cast<const NamedDecl *>();
-    if (ND && isa<VarDecl>(ND)) {
-      const auto *DAP =
-          CurrentInstantiationScope->findInstantiationOf(ND)
-              ->dyn_cast<LocalInstantiationScope::DeclArgumentPack *>();
-      if (!DAP) {
+    if (IsVarDeclPack) {
+      // Figure out whether we're instantiating to an argument pack or not.
+      typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
+
+      llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation =
+          CurrentInstantiationScope->findInstantiationOf(
+              ParmPack.first.get<NamedDecl *>());
+      if (Instantiation->is<DeclArgumentPack *>()) {
+        // We could expand this function parameter pack.
+        NewPackSize = Instantiation->get<DeclArgumentPack *>()->size();
+      } else {
         // We can't expand this function parameter pack, so we can't expand
         // the pack expansion.
         ShouldExpand = false;
         continue;
       }
-      NewPackSize = DAP->size();
-    } else if (ND) {
-      Pos = getDepthAndIndex(ND);
-    } else if (const auto *TTP = P.dyn_cast<const TemplateTypeParmType *>()) {
-      Pos = {TTP->getDepth(), TTP->getIndex()};
-      ND = TTP->getDecl();
-      // FIXME: We either should have some fallback for canonical TTP, or
-      //        never have canonical TTP here.
-    } else if (const auto *STP =
-                   P.dyn_cast<const SubstTemplateTypeParmPackType *>()) {
-      NewPackSize = STP->getNumArgs();
-      ND = STP->getReplacedParameter();
     } else {
-      const auto *SEP = P.get<const SubstNonTypeTemplateParmPackExpr *>();
-      NewPackSize = SEP->getArgumentPack().pack_size();
-      ND = SEP->getParameterPack();
-    }
-
-    if (Pos) {
       // If we don't have a template argument at this depth/index, then we
       // cannot expand the pack expansion. Make a note of this, but we still
       // want to check any parameter packs we *do* have arguments for.
-      if (Pos->first >= TemplateArgs.getNumLevels() ||
-          !TemplateArgs.hasTemplateArgument(Pos->first, Pos->second)) {
+      if (Depth >= TemplateArgs.getNumLevels() ||
+          !TemplateArgs.hasTemplateArgument(Depth, Index)) {
         ShouldExpand = false;
         continue;
       }
+
       // Determine the size of the argument pack.
-      NewPackSize = TemplateArgs(Pos->first, Pos->second).pack_size();
-      // C++0x [temp.arg.explicit]p9:
-      //   Template argument deduction can extend the sequence of template
-      //   arguments corresponding to a template parameter pack, even when the
-      //   sequence contains explicitly specified template arguments.
-      if (CurrentInstantiationScope)
-        if (const NamedDecl *PartialPack =
-                CurrentInstantiationScope->getPartiallySubstitutedPack();
-            PartialPack && getDepthAndIndex(PartialPack) == *Pos) {
+      NewPackSize = TemplateArgs(Depth, Index).pack_size();
+    }
+
+    // C++0x [temp.arg.explicit]p9:
+    //   Template argument deduction can extend the sequence of template
+    //   arguments corresponding to a template parameter pack, even when the
+    //   sequence contains explicitly specified template arguments.
+    if (!IsVarDeclPack && CurrentInstantiationScope) {
+      if (NamedDecl *PartialPack =
+              CurrentInstantiationScope->getPartiallySubstitutedPack()) {
+        unsigned PartialDepth, PartialIndex;
+        std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack);
+        if (PartialDepth == Depth && PartialIndex == Index) {
           RetainExpansion = true;
           // We don't actually know the new pack size yet.
-          PartialExpansion = {NewPackSize, Loc};
+          NumPartialExpansions = NewPackSize;
+          PartiallySubstitutedPackLoc = ParmPack.second;
           continue;
         }
+      }
     }
 
-    // FIXME: Workaround for Canonical TTP.
-    const IdentifierInfo *Name = ND ? ND->getIdentifier() : nullptr;
-    if (!CurNumExpansions) {
+    if (!NumExpansions) {
       // The is the first pack we've seen for which we have an argument.
       // Record it.
-      CurNumExpansions = NewPackSize;
-      FirstPack = {Name, Loc};
-    } else if (NewPackSize != *CurNumExpansions) {
+      NumExpansions = NewPackSize;
+      FirstPack.first = Name;
+      FirstPack.second = ParmPack.second;
+      HaveFirstPack = true;
+      continue;
+    }
+
+    if (NewPackSize != *NumExpansions) {
       // C++0x [temp.variadic]p5:
       //   All of the parameter packs expanded by a pack expansion shall have
       //   the same number of arguments specified.
-      Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
-          << FirstPack.first << Name << *CurNumExpansions << NewPackSize
-          << SourceRange(FirstPack.second) << SourceRange(Loc);
+      if (HaveFirstPack)
+        Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
+            << FirstPack.first << Name << *NumExpansions << NewPackSize
+            << SourceRange(FirstPack.second) << SourceRange(ParmPack.second);
+      else
+        Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)
+            << Name << *NumExpansions << NewPackSize
+            << SourceRange(ParmPack.second);
       return true;
     }
   }
 
-  if (NumExpansions && CurNumExpansions &&
-      *NumExpansions != *CurNumExpansions) {
-    Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)
-        << FirstPack.first << *CurNumExpansions << *NumExpansions
-        << SourceRange(FirstPack.second);
-    return true;
-  }
-
   // If we're performing a partial expansion but we also have a full expansion,
   // expand to the number of common arguments. For example, given:
   //
@@ -790,18 +786,17 @@ bool Sema::CheckParameterPacksForExpansion(
   //
   // ... a call to 'A<int, int>().f<int>' should expand the pack once and
   // retain an expansion.
-  if (PartialExpansion) {
-    if (CurNumExpansions && *CurNumExpansions < PartialExpansion->first) {
+  if (NumPartialExpansions) {
+    if (NumExpansions && *NumExpansions < *NumPartialExpansions) {
       NamedDecl *PartialPack =
           CurrentInstantiationScope->getPartiallySubstitutedPack();
       Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_partial)
-          << PartialPack << PartialExpansion->first << *CurNumExpansions
-          << SourceRange(PartialExpansion->second);
+          << PartialPack << *NumPartialExpansions << *NumExpansions
+          << SourceRange(PartiallySubstitutedPackLoc);
       return true;
     }
-    NumExpansions = PartialExpansion->first;
-  } else {
-    NumExpansions = CurNumExpansions;
+
+    NumExpansions = NumPartialExpansions;
   }
 
   return false;
@@ -814,48 +809,47 @@ std::optional<unsigned> Sema::getNumArgumentsInExpansion(
   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern);
 
   std::optional<unsigned> Result;
-  auto setResultSz = [&Result](unsigned Size) {
-    assert((!Result || *Result == Size) && "inconsistent pack sizes");
-    Result = Size;
-  };
-  auto setResultPos = [&](const std::pair<unsigned, unsigned> &Pos) -> bool {
-    unsigned Depth = Pos.first, Index = Pos.second;
-    if (Depth >= TemplateArgs.getNumLevels() ||
-        !TemplateArgs.hasTemplateArgument(Depth, Index))
-      // The pattern refers to an unknown template argument. We're not ready to
-      // expand this pack yet.
-      return true;
-    // Determine the size of the argument pack.
-    setResultSz(TemplateArgs(Depth, Index).pack_size());
-    return false;
-  };
+  for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
+    // Compute the depth and index for this parameter pack.
+    unsigned Depth;
+    unsigned Index;
 
-  for (auto [I, _] : Unexpanded) {
-    if (const auto *TTP = I.dyn_cast<const TemplateTypeParmType *>()) {
-      if (setResultPos({TTP->getDepth(), TTP->getIndex()}))
-        return std::nullopt;
-    } else if (const auto *STP =
-                   I.dyn_cast<const SubstTemplateTypeParmPackType *>()) {
-      setResultSz(STP->getNumArgs());
-    } else if (const auto *SEP =
-                   I.dyn_cast<const SubstNonTypeTemplateParmPackExpr *>()) {
-      setResultSz(SEP->getArgumentPack().pack_size());
+    if (const TemplateTypeParmType *TTP =
+            Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
+      Depth = TTP->getDepth();
+      Index = TTP->getIndex();
     } else {
-      const auto *ND = I.get<const NamedDecl *>();
-      // Function parameter pack or init-capture pack.
+      NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
       if (isa<VarDecl>(ND)) {
-        const auto *DAP =
-            CurrentInstantiationScope->findInstantiationOf(ND)
-                ->dyn_cast<LocalInstantiationScope::DeclArgumentPack *>();
-        if (!DAP)
+        // Function parameter pack or init-capture pack.
+        typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
+
+        llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation =
+            CurrentInstantiationScope->findInstantiationOf(
+                Unexpanded[I].first.get<NamedDecl *>());
+        if (Instantiation->is<Decl *>())
           // The pattern refers to an unexpanded pack. We're not ready to expand
           // this pack yet.
           return std::nullopt;
-        setResultSz(DAP->size());
-      } else if (setResultPos(getDepthAndIndex(ND))) {
-        return std::nullopt;
+
+        unsigned Size = Instantiation->get<DeclArgumentPack *>()->size();
+        assert((!Result || *Result == Size) && "inconsistent pack sizes");
+        Result = Size;
+        continue;
       }
+
+      std::tie(Depth, Index) = getDepthAndIndex(ND);
     }
+    if (Depth >= TemplateArgs.getNumLevels() ||
+        !TemplateArgs.hasTemplateArgument(Depth, Index))
+      // The pattern refers to an unknown template argument. We're not ready to
+      // expand this pack yet.
+      return std::nullopt;
+
+    // Determine the size of the argument pack.
+    unsigned Size = TemplateArgs(Depth, Index).pack_size();
+    assert((!Result || *Result == Size) && "inconsistent pack sizes");
+    Result = Size;
   }
 
   return Result;

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 9d4c7b01aa5c6..48bb28b56cd3a 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -5897,7 +5897,6 @@ bool TreeTransform<Derived>::TransformFunctionTypeParams(
                                        = dyn_cast<PackExpansionType>(OldType)) {
       // We have a function parameter pack that may need to be expanded.
       QualType Pattern = Expansion->getPattern();
-      NumExpansions = Expansion->getNumExpansions();
       SmallVector<UnexpandedParameterPack, 2> Unexpanded;
       getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
 

diff  --git a/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
index 2d82a4f26b147..7542186c22c71 100644
--- a/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
@@ -473,51 +473,45 @@ int fn() {
 }
 }
 
-namespace pr56094 {
-template <typename... T> struct D {
-  template <typename... U> using B = int(int (*...p)(T, U));
-  // expected-error at -1 {{pack expansion contains parameter packs 'T' and 'U' that have 
diff erent lengths (1 vs. 2)}}
-  template <typename U1, typename U2> D(B<U1, U2> *);
-  // expected-note at -1 {{in instantiation of template type alias 'B' requested here}}
+namespace GH58452 {
+template <typename... As> struct A {
+  template <typename... Bs> using B = void(As...(Bs));
 };
-using t1 = D<float>::B<int>;
-// expected-note at -1 {{in instantiation of template class 'pr56094::D<float>' requested here}}
-
-template <bool...> struct F {};
-template <class...> struct G {};
-template <bool... I> struct E {
-  template <bool... U> using B = G<F<I, U>...>;
-  // expected-error at -1 {{pack expansion contains parameter packs 'I' and 'U' that have 
diff erent lengths (1 vs. 2)}}
-  template <bool U1, bool U2> E(B<U1, U2> *);
-  // expected-note at -1 {{in instantiation of template type alias 'B' requested here}}
+
+template <typename... Cs> struct C {
+    template <typename... Ds> using D = typename A<Cs...>::template B<Ds...>;
 };
-using t2 = E<true>::B<false>;
-// expected-note at -1 {{in instantiation of template class 'pr56094::E<true>' requested here}}
-} // namespace pr56094
-
-namespace GH56094 {
-#if __cplusplus >= 201402L
-template <class> struct A; // expected-note {{template is declared here}}
-template <class> using B = char;
-template <class ...Cs> int C{ A<B<Cs>>{}... }; // expected-error {{implicit instantiation of undefined template}}
-#endif
-} // namespace GH56094
 
-namespace GH58679 {
-#if __cplusplus >= 201402L
-template <class> constexpr int A = 1;
+using t1 = C<int, int>::template D<float, float>;
 
-template <int> struct B;
-template <> struct B<1> { using b1 = void; };
+template <typename A, typename B>
+using ConditionalRewrite = B;
 
-template <class> using C = char;
+template <typename T>
+using SignatureType = int;
 
-template <class... Ds> int D{ B<A<C<Ds>>>{}... };
+template <typename... Args>
+struct Type1 {
+    template <typename... Params>
+        using Return = SignatureType<int(ConditionalRewrite<Args, Params>...)>;
 
-struct E {
-  template <class E1, class = typename B<A<E1>>::b1> E(E1);
 };
 
-template <typename... Es> int F{ E(C<Es>{})... };
-#endif
-} // namespace GH58679
+template <typename... Args>
+struct Type2 {
+    using T1 = Type1<Args...>;
+
+      template <typename... Params>
+          using Return = typename T1::template Return<Params...>;
+
+};
+
+template <typename T>
+typename T::template Return<int, int> InvokeMethod() {
+    return 3;
+}
+
+int Function1() {
+    return InvokeMethod<Type2<int, int>>();
+}
+}

diff  --git a/clang/test/SemaTemplate/cxx1z-fold-expressions.cpp b/clang/test/SemaTemplate/cxx1z-fold-expressions.cpp
index 98876baf1f3ec..518eaf0e05239 100644
--- a/clang/test/SemaTemplate/cxx1z-fold-expressions.cpp
+++ b/clang/test/SemaTemplate/cxx1z-fold-expressions.cpp
@@ -97,7 +97,7 @@ namespace PR41845 {
   template <int I> struct Constant {};
 
   template <int... Is> struct Sum {
-    template <int... Js> using type = Constant<((Is + Js) + ... + 0)>; // expected-error {{pack expansion contains parameter packs 'Is' and 'Js' that have 
diff erent lengths (1 vs. 2)}}
+    template <int... Js> using type = Constant<((Is + Js) + ... + 0)>; // expected-error {{pack expansion contains parameter pack 'Js' that has a 
diff erent length (1 vs. 2) from outer parameter packs}}
   };
 
   Sum<1>::type<1, 2> x; // expected-note {{instantiation of}}

diff  --git a/clang/test/SemaTemplate/pack-deduction.cpp b/clang/test/SemaTemplate/pack-deduction.cpp
index f07bafdf86bca..e42709820e9cf 100644
--- a/clang/test/SemaTemplate/pack-deduction.cpp
+++ b/clang/test/SemaTemplate/pack-deduction.cpp
@@ -134,14 +134,14 @@ namespace partial_full_mix {
   template<typename ...T> struct tuple {};
   template<typename ...T> struct A {
     template<typename ...U> static pair<tuple<T...>, tuple<U...>> f(pair<T, U> ...p);
-    // expected-note at -1 {{[with U = <char, double, long>]: pack expansion contains parameter packs 'T' and 'U' that have 
diff erent lengths (2 vs. 3)}}
+    // expected-note at -1 {{[with U = <char, double, long>]: pack expansion contains parameter pack 'U' that has a 
diff erent length (2 vs. 3) from outer parameter packs}}
     // expected-note at -2 {{[with U = <char, double, void>]: pack expansion contains parameter pack 'U' that has a 
diff erent length (at least 3 vs. 2) from outer parameter packs}}
 
     template<typename ...U> static pair<tuple<T...>, tuple<U...>> g(pair<T, U> ...p, ...);
-    // expected-note at -1 {{[with U = <char, double, long>]: pack expansion contains parameter packs 'T' and 'U' that have 
diff erent lengths (2 vs. 3)}}
+    // expected-note at -1 {{[with U = <char, double, long>]: pack expansion contains parameter pack 'U' that has a 
diff erent length (2 vs. 3) from outer parameter packs}}
 
     template<typename ...U> static tuple<U...> h(tuple<pair<T, U>..., pair<int, int>>);
-    // expected-note at -1 {{[with U = <int[2]>]: pack expansion contains parameter packs 'T' and 'U' that have 
diff erent lengths (2 vs. 1)}}
+    // expected-note at -1 {{[with U = <int[2]>]: pack expansion contains parameter pack 'U' that has a 
diff erent length (2 vs. 1) from outer parameter packs}}
   };
 
   pair<tuple<int, float>, tuple<char, double>> k1 = A<int, float>().f<char>(pair<int, char>(), pair<float, double>());


        


More information about the llvm-branch-commits mailing list