[clang] Reapply "[Clang] Improve diagnostics for expansion length mismatch" (PR #121044)

via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 13 01:59:02 PDT 2025


================
@@ -749,132 +759,124 @@ ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
     PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions);
 }
 
+static bool IsUnexpandedPackExpansion(const TemplateArgument &TA) {
+  if (!TA.isPackExpansion())
+    return false;
+
+  if (TA.getKind() == TemplateArgument::Type)
+    return !TA.getAsType()->getAs<PackExpansionType>()->getNumExpansions();
+
+  if (TA.getKind() == TemplateArgument::Expression)
+    return !cast<PackExpansionExpr>(TA.getAsExpr())->getNumExpansions();
+
+  return !TA.getNumTemplateExpansions();
+}
+
 bool Sema::CheckParameterPacksForExpansion(
     SourceLocation EllipsisLoc, SourceRange PatternRange,
     ArrayRef<UnexpandedParameterPack> Unexpanded,
     const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand,
     bool &RetainExpansion, std::optional<unsigned> &NumExpansions) {
   ShouldExpand = true;
   RetainExpansion = false;
-  std::pair<IdentifierInfo *, SourceLocation> FirstPack;
-  bool HaveFirstPack = false;
-  std::optional<unsigned> NumPartialExpansions;
-  SourceLocation PartiallySubstitutedPackLoc;
-  typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
+  std::pair<const IdentifierInfo *, SourceLocation> FirstPack;
+  std::optional<std::pair<unsigned, SourceLocation>> PartialExpansion;
+  std::optional<unsigned> CurNumExpansions, CurMaximumOfLeastExpansions;
 
-  for (UnexpandedParameterPack ParmPack : Unexpanded) {
+  for (auto [P, Loc] : Unexpanded) {
     // Compute the depth and index for this parameter pack.
-    unsigned Depth = 0, Index = 0;
-    IdentifierInfo *Name;
-    bool IsVarDeclPack = false;
-    FunctionParmPackExpr *BindingPack = nullptr;
-
-    if (const TemplateTypeParmType *TTP =
-            ParmPack.first.dyn_cast<const TemplateTypeParmType *>()) {
-      Depth = TTP->getDepth();
-      Index = TTP->getIndex();
-      Name = TTP->getIdentifier();
-    } else {
-      NamedDecl *ND = cast<NamedDecl *>(ParmPack.first);
-      if (isa<VarDecl>(ND))
-        IsVarDeclPack = true;
-      else if (isa<BindingDecl>(ND)) {
+    std::optional<std::pair<unsigned, unsigned>> Pos;
+    unsigned NewPackSize, PendingPackExpansionSize = 0;
+    const auto *ND = dyn_cast_if_present<const NamedDecl *>(P);
+    if (ND) {
+      if (isa<VarDecl>(ND)) {
+        auto *DAP = dyn_cast<LocalInstantiationScope::DeclArgumentPack *>(
+            *CurrentInstantiationScope->findInstantiationOf(ND));
+        if (!DAP) {
+          // We can't expand this function parameter pack, so we can't expand
+          // the pack expansion.
+          ShouldExpand = false;
+          continue;
+        }
+        NewPackSize = DAP->size();
+      } else if (isa<BindingDecl>(ND)) {
         // Find the instantiated BindingDecl and check it for a resolved pack.
-        llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation =
-            CurrentInstantiationScope->findInstantiationOf(ND);
+        llvm::PointerUnion<Decl *, LocalInstantiationScope::DeclArgumentPack *>
+            *Instantiation = CurrentInstantiationScope->findInstantiationOf(ND);
----------------
cor3ntin wrote:

Pre-existing but do we need an assert here? Can it be null?

https://github.com/llvm/llvm-project/pull/121044


More information about the cfe-commits mailing list