llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-tools-extra

Author: Matheus Izvekov (mizvekov)

<details>
<summary>Changes</summary>

This reverts an earlier attempt (adb0d8ddceb143749c519d14b8b31b481071da77 and 
50e5411e4247421fd606f0a206682fcdf0303ae3) to support these expansions,
which was limited to type arguments and which subverted the purpose
of SubstTemplateTypeParmType.

This propagates the ArgumentPackSubstitutionIndex along with the
AssociatedConstraint, so that the pack expansion works, without
needing any new transforms or otherwise any changes to the template
instanntiation process.

This keeps the tests from the reverted commits, and adds a few more
showing the new solution also works for NTTPs.

This patch is incomplete:
* It is likely missing plumbing the ArgumentPackSubstitutionIndex
  into more places.
* The Normalization cache is not adapted so it indexes on the
  ArgumentPackSubstitutionIndex as well.

One new test is added, which in any case shows an ambiguous call,
but if the normalization cache were corrected, the reason for
ambighuity would change from subsumption both ways, to neither
subsumes the other.

I am not sure if the current language rules would allow
for a test case where the pack index would break an ambiguity,
this is left for future consideration.

---

Patch is 67.36 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/132626.diff


29 Files Affected:

- (modified) clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp 
(+2-2) 
- (modified) clang/docs/ReleaseNotes.rst (+2) 
- (modified) clang/include/clang/AST/ASTConcept.h (+9-2) 
- (modified) clang/include/clang/AST/ASTContext.h (+1-3) 
- (modified) clang/include/clang/AST/Decl.h (+13-2) 
- (modified) clang/include/clang/AST/DeclTemplate.h (+17-9) 
- (modified) clang/include/clang/AST/PropertiesBase.td (-1) 
- (modified) clang/include/clang/AST/Type.h (+3-26) 
- (modified) clang/include/clang/AST/TypeProperties.td (+1-4) 
- (modified) clang/include/clang/Sema/Sema.h (+15-11) 
- (modified) clang/include/clang/Sema/SemaConcept.h (+18-9) 
- (modified) clang/lib/AST/ASTContext.cpp (+3-4) 
- (modified) clang/lib/AST/ASTImporter.cpp (+4-3) 
- (modified) clang/lib/AST/DeclTemplate.cpp (+14-12) 
- (modified) clang/lib/AST/Type.cpp (+1-5) 
- (modified) clang/lib/Sema/SemaCodeComplete.cpp (+5-4) 
- (modified) clang/lib/Sema/SemaConcept.cpp (+103-74) 
- (modified) clang/lib/Sema/SemaDecl.cpp (+5-2) 
- (modified) clang/lib/Sema/SemaExprCXX.cpp (+5-2) 
- (modified) clang/lib/Sema/SemaOverload.cpp (+2-2) 
- (modified) clang/lib/Sema/SemaTemplate.cpp (+10-8) 
- (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+9-7) 
- (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+9-137) 
- (modified) clang/lib/Sema/SemaType.cpp (+2-6) 
- (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+3-1) 
- (modified) clang/lib/Serialization/ASTWriterDecl.cpp (+1) 
- (modified) clang/test/SemaCXX/cxx20-ctad-type-alias.cpp (+1-1) 
- (modified) clang/test/SemaCXX/fold_lambda_with_variadics.cpp (+29) 
- (modified) clang/unittests/AST/SourceLocationTest.cpp (+3-3) 


``````````diff
diff --git a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
index ea4d99586c711..fb82efb4dd211 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
@@ -356,7 +356,7 @@ static std::vector<FixItHint> handleReturnType(const 
FunctionDecl *Function,
   if (!TypeText)
     return {};
 
-  SmallVector<const Expr *, 3> ExistingConstraints;
+  SmallVector<AssociatedConstraint, 3> ExistingConstraints;
   Function->getAssociatedConstraints(ExistingConstraints);
   if (!ExistingConstraints.empty()) {
     // FIXME - Support adding new constraints to existing ones. Do we need to
@@ -404,7 +404,7 @@ handleTrailingTemplateType(const FunctionTemplateDecl 
*FunctionTemplate,
   if (!ConditionText)
     return {};
 
-  SmallVector<const Expr *, 3> ExistingConstraints;
+  SmallVector<AssociatedConstraint, 3> ExistingConstraints;
   Function->getAssociatedConstraints(ExistingConstraints);
   if (!ExistingConstraints.empty()) {
     // FIXME - Support adding new constraints to existing ones. Do we need to
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8182bccdd2da8..954e4a1ed5a97 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -346,6 +346,8 @@ Bug Fixes to C++ Support
 - Clang now uses the parameter location for abbreviated function templates in 
``extern "C"``. (#GH46386)
 - Clang will emit an error instead of crash when use co_await or co_yield in
   C++26 braced-init-list template parameter initialization. (#GH78426)
+- Improved fix for an issue with pack expansions of type constraints, where 
this
+  now also works if the constraint has non-type or template template 
parameters.
 - Fixes matching of nested template template parameters. (#GH130362)
 - Correctly diagnoses template template paramters which have a pack parameter
   not in the last position.
diff --git a/clang/include/clang/AST/ASTConcept.h 
b/clang/include/clang/AST/ASTConcept.h
index 00500e214f4ce..f89899c3ea7b1 100644
--- a/clang/include/clang/AST/ASTConcept.h
+++ b/clang/include/clang/AST/ASTConcept.h
@@ -229,12 +229,15 @@ class TypeConstraint {
   /// type-constraint.
   Expr *ImmediatelyDeclaredConstraint = nullptr;
   ConceptReference *ConceptRef;
+  int ArgumentPackSubstitutionIndex;
 
 public:
   TypeConstraint(ConceptReference *ConceptRef,
-                 Expr *ImmediatelyDeclaredConstraint)
+                 Expr *ImmediatelyDeclaredConstraint,
+                 int ArgumentPackSubstitutionIndex)
       : ImmediatelyDeclaredConstraint(ImmediatelyDeclaredConstraint),
-        ConceptRef(ConceptRef) {}
+        ConceptRef(ConceptRef),
+        ArgumentPackSubstitutionIndex(ArgumentPackSubstitutionIndex) {}
 
   /// \brief Get the immediately-declared constraint expression introduced by
   /// this type-constraint, that is - the constraint expression that is added 
to
@@ -245,6 +248,10 @@ class TypeConstraint {
 
   ConceptReference *getConceptReference() const { return ConceptRef; }
 
+  int getArgumentPackSubstitutionIndex() const {
+    return ArgumentPackSubstitutionIndex;
+  }
+
   // FIXME: Instead of using these concept related functions the callers should
   // directly work with the corresponding ConceptReference.
   ConceptDecl *getNamedConcept() const { return ConceptRef->getNamedConcept(); 
}
diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index af8c49e99a7ce..1f7c75559e1e9 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1798,9 +1798,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
   QualType
   getSubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl,
                                unsigned Index,
-                               std::optional<unsigned> PackIndex,
-                               SubstTemplateTypeParmTypeFlag Flag =
-                                   SubstTemplateTypeParmTypeFlag::None) const;
+                               std::optional<unsigned> PackIndex) const;
   QualType getSubstTemplateTypeParmPackType(Decl *AssociatedDecl,
                                             unsigned Index, bool Final,
                                             const TemplateArgument &ArgPack);
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index efac36e49351e..22efb4f3ec3f9 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -78,6 +78,16 @@ class UnresolvedSetImpl;
 class VarTemplateDecl;
 enum class ImplicitParamKind;
 
+struct AssociatedConstraint {
+  const Expr *ConstraintExpr;
+  int ArgumentPackSubstitutionIndex;
+
+  constexpr AssociatedConstraint(const Expr *ConstraintExpr,
+                                 int ArgumentPackSubstitutionIndex)
+      : ConstraintExpr(ConstraintExpr),
+        ArgumentPackSubstitutionIndex(ArgumentPackSubstitutionIndex) {}
+};
+
 /// The top declaration context.
 class TranslationUnitDecl : public Decl,
                             public DeclContext,
@@ -2631,9 +2641,10 @@ class FunctionDecl : public DeclaratorDecl,
   ///
   /// Use this instead of getTrailingRequiresClause for concepts APIs that
   /// accept an ArrayRef of constraint expressions.
-  void getAssociatedConstraints(SmallVectorImpl<const Expr *> &AC) const {
+  void
+  getAssociatedConstraints(SmallVectorImpl<AssociatedConstraint> &AC) const {
     if (auto *TRC = getTrailingRequiresClause())
-      AC.push_back(TRC);
+      AC.emplace_back(TRC, /*ArgumentPackSubstitutionIndex=*/-1);
   }
 
   /// Get the message that indicates why this function was deleted.
diff --git a/clang/include/clang/AST/DeclTemplate.h 
b/clang/include/clang/AST/DeclTemplate.h
index b27e698236c02..6123273ce5ec1 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -195,7 +195,8 @@ class TemplateParameterList final
   ///
   /// The constraints in the resulting list are to be treated as if in a
   /// conjunction ("and").
-  void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const;
+  void getAssociatedConstraints(
+      llvm::SmallVectorImpl<AssociatedConstraint> &AC) const;
 
   bool hasAssociatedConstraints() const;
 
@@ -422,7 +423,8 @@ class TemplateDecl : public NamedDecl {
   /// including constraint-expressions derived from the requires-clause,
   /// trailing requires-clause (for functions and methods) and constrained
   /// template parameters.
-  void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const;
+  void getAssociatedConstraints(
+      llvm::SmallVectorImpl<AssociatedConstraint> &AC) const;
 
   bool hasAssociatedConstraints() const;
 
@@ -1341,7 +1343,8 @@ class TemplateTypeParmDecl final : public TypeDecl,
   }
 
   void setTypeConstraint(ConceptReference *CR,
-                         Expr *ImmediatelyDeclaredConstraint);
+                         Expr *ImmediatelyDeclaredConstraint,
+                         int ArgumentPackSubstitutionIndex);
 
   /// Determine whether this template parameter has a type-constraint.
   bool hasTypeConstraint() const {
@@ -1353,9 +1356,11 @@ class TemplateTypeParmDecl final : public TypeDecl,
   ///
   /// Use this instead of getTypeConstraint for concepts APIs that
   /// accept an ArrayRef of constraint expressions.
-  void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const 
{
+  void getAssociatedConstraints(
+      llvm::SmallVectorImpl<AssociatedConstraint> &AC) const {
     if (HasTypeConstraint)
-      AC.push_back(getTypeConstraint()->getImmediatelyDeclaredConstraint());
+      AC.emplace_back(getTypeConstraint()->getImmediatelyDeclaredConstraint(),
+                      getTypeConstraint()->getArgumentPackSubstitutionIndex());
   }
 
   SourceRange getSourceRange() const override LLVM_READONLY;
@@ -1574,9 +1579,10 @@ class NonTypeTemplateParmDecl final
   ///
   /// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
   /// concepts APIs that accept an ArrayRef of constraint expressions.
-  void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const 
{
+  void getAssociatedConstraints(
+      llvm::SmallVectorImpl<AssociatedConstraint> &AC) const {
     if (Expr *E = getPlaceholderTypeConstraint())
-      AC.push_back(E);
+      AC.emplace_back(E, /*ArgumentPackSubstitutionIndex=*/-1);
   }
 
   // Implement isa/cast/dyncast/etc.
@@ -2169,7 +2175,8 @@ class ClassTemplatePartialSpecializationDecl
   ///
   /// The constraints in the resulting list are to be treated as if in a
   /// conjunction ("and").
-  void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const 
{
+  void getAssociatedConstraints(
+      llvm::SmallVectorImpl<AssociatedConstraint> &AC) const {
     TemplateParams->getAssociatedConstraints(AC);
   }
 
@@ -2943,7 +2950,8 @@ class VarTemplatePartialSpecializationDecl
   ///
   /// The constraints in the resulting list are to be treated as if in a
   /// conjunction ("and").
-  void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const 
{
+  void getAssociatedConstraints(
+      llvm::SmallVectorImpl<AssociatedConstraint> &AC) const {
     TemplateParams->getAssociatedConstraints(AC);
   }
 
diff --git a/clang/include/clang/AST/PropertiesBase.td 
b/clang/include/clang/AST/PropertiesBase.td
index 42883b6419261..5f3a885832e2e 100644
--- a/clang/include/clang/AST/PropertiesBase.td
+++ b/clang/include/clang/AST/PropertiesBase.td
@@ -137,7 +137,6 @@ def Selector : PropertyType;
 def SourceLocation : PropertyType;
 def StmtRef : RefPropertyType<"Stmt"> { let ConstWhenWriting = 1; }
   def ExprRef : SubclassPropertyType<"Expr", StmtRef>;
-def SubstTemplateTypeParmTypeFlag : EnumPropertyType;
 def TemplateArgument : PropertyType;
 def TemplateArgumentKind : EnumPropertyType<"TemplateArgument::ArgKind">;
 def TemplateName : DefaultValuePropertyType;
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 65756203f2073..3b80f962a3bc6 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1786,15 +1786,6 @@ enum class AutoTypeKeyword {
   GNUAutoType
 };
 
-enum class SubstTemplateTypeParmTypeFlag {
-  None,
-
-  /// Whether to expand the pack using the stored PackIndex in place. This is
-  /// useful for e.g. substituting into an atomic constraint expression, where
-  /// that expression is part of an unexpanded pack.
-  ExpandPacksInPlace,
-};
-
 enum class ArraySizeModifier;
 enum class ElaboratedTypeKeyword;
 enum class VectorKind;
@@ -2164,9 +2155,6 @@ class alignas(TypeAlignment) Type : public 
ExtQualsTypeCommonBase {
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasNonCanonicalUnderlyingType : 1;
 
-    LLVM_PREFERRED_TYPE(SubstTemplateTypeParmTypeFlag)
-    unsigned SubstitutionFlag : 1;
-
     // The index of the template parameter this substitution represents.
     unsigned Index : 15;
 
@@ -6396,8 +6384,7 @@ class SubstTemplateTypeParmType final
   Decl *AssociatedDecl;
 
   SubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl,
-                            unsigned Index, std::optional<unsigned> PackIndex,
-                            SubstTemplateTypeParmTypeFlag Flag);
+                            unsigned Index, std::optional<unsigned> PackIndex);
 
 public:
   /// Gets the type that was substituted for the template
@@ -6426,31 +6413,21 @@ class SubstTemplateTypeParmType final
     return SubstTemplateTypeParmTypeBits.PackIndex - 1;
   }
 
-  SubstTemplateTypeParmTypeFlag getSubstitutionFlag() const {
-    return static_cast<SubstTemplateTypeParmTypeFlag>(
-        SubstTemplateTypeParmTypeBits.SubstitutionFlag);
-  }
-
   bool isSugared() const { return true; }
   QualType desugar() const { return getReplacementType(); }
 
   void Profile(llvm::FoldingSetNodeID &ID) {
     Profile(ID, getReplacementType(), getAssociatedDecl(), getIndex(),
-            getPackIndex(), getSubstitutionFlag());
+            getPackIndex());
   }
 
   static void Profile(llvm::FoldingSetNodeID &ID, QualType Replacement,
                       const Decl *AssociatedDecl, unsigned Index,
-                      std::optional<unsigned> PackIndex,
-                      SubstTemplateTypeParmTypeFlag Flag) {
+                      std::optional<unsigned> PackIndex) {
     Replacement.Profile(ID);
     ID.AddPointer(AssociatedDecl);
     ID.AddInteger(Index);
     ID.AddInteger(PackIndex ? *PackIndex - 1 : 0);
-    ID.AddInteger(llvm::to_underlying(Flag));
-    assert((Flag != SubstTemplateTypeParmTypeFlag::ExpandPacksInPlace ||
-            PackIndex) &&
-           "ExpandPacksInPlace needs a valid PackIndex");
   }
 
   static bool classof(const Type *T) {
diff --git a/clang/include/clang/AST/TypeProperties.td 
b/clang/include/clang/AST/TypeProperties.td
index 27f71bf5cc62f..4d89d8a47396a 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -827,14 +827,11 @@ let Class = SubstTemplateTypeParmType in {
   def : Property<"PackIndex", Optional<UInt32>> {
     let Read = [{ node->getPackIndex() }];
   }
-  def : Property<"SubstitutionFlag", SubstTemplateTypeParmTypeFlag> {
-    let Read = [{ node->getSubstitutionFlag() }];
-  }
 
   // The call to getCanonicalType here existed in ASTReader.cpp, too.
   def : Creator<[{
     return ctx.getSubstTemplateTypeParmType(
-        replacementType, associatedDecl, Index, PackIndex, SubstitutionFlag);
+        replacementType, associatedDecl, Index, PackIndex);
   }]>;
 }
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 066bce61c74c1..c98eea1c05060 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11350,7 +11350,6 @@ class Sema final : public SemaBase {
                             ConceptDecl *NamedConcept, NamedDecl *FoundDecl,
                             const TemplateArgumentListInfo *TemplateArgs,
                             TemplateTypeParmDecl *ConstrainedParameter,
-                            QualType ConstrainedType,
                             SourceLocation EllipsisLoc);
 
   bool AttachTypeConstraint(AutoTypeLoc TL,
@@ -14551,13 +14550,14 @@ class Sema final : public SemaBase {
   /// \returns true if an error occurred and satisfaction could not be checked,
   /// false otherwise.
   bool CheckConstraintSatisfaction(
-      const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
+      const NamedDecl *Template,
+      ArrayRef<AssociatedConstraint> AssociatedConstraints,
       const MultiLevelTemplateArgumentList &TemplateArgLists,
       SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) {
     llvm::SmallVector<Expr *, 4> Converted;
-    return CheckConstraintSatisfaction(Template, ConstraintExprs, Converted,
-                                       TemplateArgLists, TemplateIDRange,
-                                       Satisfaction);
+    return CheckConstraintSatisfaction(Template, AssociatedConstraints,
+                                       Converted, TemplateArgLists,
+                                       TemplateIDRange, Satisfaction);
   }
 
   /// \brief Check whether the given list of constraint expressions are
@@ -14583,7 +14583,8 @@ class Sema final : public SemaBase {
   /// \returns true if an error occurred and satisfaction could not be checked,
   /// false otherwise.
   bool CheckConstraintSatisfaction(
-      const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
+      const NamedDecl *Template,
+      ArrayRef<AssociatedConstraint> AssociatedConstraints,
       llvm::SmallVectorImpl<Expr *> &ConvertedConstraints,
       const MultiLevelTemplateArgumentList &TemplateArgList,
       SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction);
@@ -14660,7 +14661,8 @@ class Sema final : public SemaBase {
                                 bool First = true);
 
   const NormalizedConstraint *getNormalizedAssociatedConstraints(
-      NamedDecl *ConstrainedDecl, ArrayRef<const Expr *> 
AssociatedConstraints);
+      NamedDecl *ConstrainedDecl,
+      ArrayRef<AssociatedConstraint> AssociatedConstraints);
 
   /// \brief Check whether the given declaration's associated constraints are
   /// at least as constrained than another declaration's according to the
@@ -14670,8 +14672,10 @@ class Sema final : public SemaBase {
   /// at least constrained than D2, and false otherwise.
   ///
   /// \returns true if an error occurred, false otherwise.
-  bool IsAtLeastAsConstrained(NamedDecl *D1, MutableArrayRef<const Expr *> AC1,
-                              NamedDecl *D2, MutableArrayRef<const Expr *> AC2,
+  bool IsAtLeastAsConstrained(NamedDecl *D1,
+                              MutableArrayRef<AssociatedConstraint> AC1,
+                              NamedDecl *D2,
+                              MutableArrayRef<AssociatedConstraint> AC2,
                               bool &Result);
 
   /// If D1 was not at least as constrained as D2, but would've been if a pair
@@ -14679,8 +14683,8 @@ class Sema final : public SemaBase {
   /// repeated in two separate places in code.
   /// \returns true if such a diagnostic was emitted, false otherwise.
   bool MaybeEmitAmbiguousAtomicConstraintsDiagnostic(
-      NamedDecl *D1, ArrayRef<const Expr *> AC1, NamedDecl *D2,
-      ArrayRef<const Expr *> AC2);
+      NamedDecl *D1, ArrayRef<AssociatedConstraint> AC1, NamedDecl *D2,
+      ArrayRef<AssociatedConstraint> AC2);
 
 private:
   /// Caches pairs of template-like decls whose associated constraints were
diff --git a/clang/include/clang/Sema/SemaConcept.h 
b/clang/include/clang/Sema/SemaConcept.h
index 5c599a70532f6..fe27a03df4863 100644
--- a/clang/include/clang/Sema/SemaConcept.h
+++ b/clang/include/clang/Sema/SemaConcept.h
@@ -29,12 +29,12 @@ class Sema;
 enum { ConstraintAlignment = 8 };
 
 struct alignas(ConstraintAlignment) AtomicConstraint {
-  const Expr *ConstraintExpr;
+  AssociatedConstraint AC;
   NamedDecl *ConstraintDecl;
   std::optional<ArrayRef<TemplateArgumentLoc>> ParameterMapping;
 
-  AtomicConstraint(const Expr *ConstraintExpr, NamedDecl *ConstraintDecl)
-      : ConstraintExpr(ConstraintExpr), ConstraintDecl(ConstraintDecl) {};
+  AtomicConstraint(const AssociatedConstraint &AC, NamedDecl *ConstraintDecl)
+      : AC(AC), ConstraintDecl(ConstraintDecl) {};
 
   bool hasMatchingParameterMapping(ASTContext &C,
                                    const AtomicConstraint &Other) const {
@@ -70,7 +70,14 @@ struct alignas(ConstraintAlignment) AtomicConstraint {
     // We do not actually substitute the parameter mappings into the
     // constraint expressions, therefore the constraint expressions are
     // the originals, and comparing them will suffice.
-    if (ConstraintExpr != Other.ConstraintExpr)
+    if (AC.ConstraintExpr != Other.AC.ConstraintExpr)
+      return false;
+
+    // FIXME: As the normalization cache doesn't take
+    // ArgumentPackSubstitutionIndex into account,
+    // this won't have an effect.
+    if (AC.ArgumentPackSubstitutionIndex !=
+        Other.AC.ArgumentPackSubstitutionIndex)
       return false;
 
     // Check that the parameter lists are identical
@@ -152,9 +159,11 @@ struct NormalizedConstraint {
 
 private:
   static std::optional<NormalizedConstraint>
-  fromConstraintExprs(Sema &S, NamedDecl *D, ArrayRef<const Expr *> E);
+  fromConstraintAssociatedConstraints(Sema &S, NamedDecl *D,
+                                      ArrayRef<AssociatedConstraint> ACs);
   static std::optional<NormalizedConstraint>
-  fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E);
+  fromConstraintAssociatedConstraint(Sema &S, NamedDecl *D,
+                                     AssociatedConstraint AC);
 };
 
 struct alignas(ConstraintAlignment) NormalizedConstraintPair {
@@ -180,7 +189,7 @@ struct alignas(ConstraintAlignment) FoldExpandedConstraint {
 
 const NormalizedConstraint *getNormalizedAssociatedConstraints(
     Sema &S, NamedDecl *ConstrainedDecl,
-    ArrayRef<const Expr *> AssociatedConstraints);
+    ArrayRef<AssociatedConstraint> AssociatedConstraints);
 
 template <typename AtomicSubsumptionEvaluator>
 bool subsumes(const NormalForm &PDNF, const NormalForm &QCNF,
@@ -226,8 +235,8 @@ bool subsumes(const NormalForm &PDNF, const NormalForm 
&QCNF,
 }
 
 template...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/132626
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to