@@ -10505,13 +10505,34 @@ class Sema final : public SemaBase {
1050510505 OverloadCandidateParamOrder PO = {},
1050610506 bool AggregateCandidateDeduction = false);
1050710507
10508+ struct CheckNonDependentConversionsFlag {
10509+ /// Do not consider any user-defined conversions when constructing the
10510+ /// initializing sequence.
10511+ bool SuppressUserConversions;
10512+
10513+ /// Before constructing the initializing sequence, we check whether the
10514+ /// parameter type and argument type contain any user defined conversions.
10515+ /// If so, do not initialize them. This effectively bypasses some undesired
10516+ /// instantiation before checking constaints, which might otherwise result
10517+ /// in non-SFINAE errors e.g. recursive constraints.
10518+ bool OnlyInitializeNonUserDefinedConversions;
10519+
10520+ CheckNonDependentConversionsFlag(
10521+ bool SuppressUserConversions,
10522+ bool OnlyInitializeNonUserDefinedConversions)
10523+ : SuppressUserConversions(SuppressUserConversions),
10524+ OnlyInitializeNonUserDefinedConversions(
10525+ OnlyInitializeNonUserDefinedConversions) {}
10526+ };
10527+
1050810528 /// Check that implicit conversion sequences can be formed for each argument
1050910529 /// whose corresponding parameter has a non-dependent type, per DR1391's
1051010530 /// [temp.deduct.call]p10.
1051110531 bool CheckNonDependentConversions(
1051210532 FunctionTemplateDecl *FunctionTemplate, ArrayRef<QualType> ParamTypes,
1051310533 ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet,
10514- ConversionSequenceList &Conversions, bool SuppressUserConversions,
10534+ ConversionSequenceList &Conversions,
10535+ CheckNonDependentConversionsFlag UserConversionFlag,
1051510536 CXXRecordDecl *ActingContext = nullptr, QualType ObjectType = QualType(),
1051610537 Expr::Classification ObjectClassification = {},
1051710538 OverloadCandidateParamOrder PO = {});
@@ -12555,14 +12576,22 @@ class Sema final : public SemaBase {
1255512576 ///
1255612577 /// \param OriginalCallArgs If non-NULL, the original call arguments against
1255712578 /// which the deduced argument types should be compared.
12579+ /// \param CheckNonDependent Callback before substituting into the declaration
12580+ /// with the deduced template arguments.
12581+ /// \param OnlyInitializeNonUserDefinedConversions is used as a workaround for
12582+ /// some breakages introduced by CWG2369, where non-user-defined conversions
12583+ /// are checked first before the constraints.
1255812584 TemplateDeductionResult FinishTemplateArgumentDeduction(
1255912585 FunctionTemplateDecl *FunctionTemplate,
1256012586 SmallVectorImpl<DeducedTemplateArgument> &Deduced,
1256112587 unsigned NumExplicitlySpecified, FunctionDecl *&Specialization,
1256212588 sema::TemplateDeductionInfo &Info,
1256312589 SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs,
1256412590 bool PartialOverloading, bool PartialOrdering,
12565- llvm::function_ref<bool()> CheckNonDependent = [] { return false; });
12591+ llvm::function_ref<bool(bool)> CheckNonDependent =
12592+ [](bool /*OnlyInitializeNonUserDefinedConversions*/) {
12593+ return false;
12594+ });
1256612595
1256712596 /// Perform template argument deduction from a function call
1256812597 /// (C++ [temp.deduct.call]).
@@ -12598,7 +12627,7 @@ class Sema final : public SemaBase {
1259812627 bool PartialOrdering, QualType ObjectType,
1259912628 Expr::Classification ObjectClassification,
1260012629 bool ForOverloadSetAddressResolution,
12601- llvm::function_ref<bool(ArrayRef<QualType>)> CheckNonDependent);
12630+ llvm::function_ref<bool(ArrayRef<QualType>, bool )> CheckNonDependent);
1260212631
1260312632 /// Deduce template arguments when taking the address of a function
1260412633 /// template (C++ [temp.deduct.funcaddr]) or matching a specialization to
@@ -13074,6 +13103,9 @@ class Sema final : public SemaBase {
1307413103 /// Was the enclosing context a non-instantiation SFINAE context?
1307513104 bool SavedInNonInstantiationSFINAEContext;
1307613105
13106+ /// Whether we're substituting into constraints.
13107+ bool InConstraintSubstitution;
13108+
1307713109 /// The point of instantiation or synthesis within the source code.
1307813110 SourceLocation PointOfInstantiation;
1307913111
@@ -13123,9 +13155,9 @@ class Sema final : public SemaBase {
1312313155
1312413156 CodeSynthesisContext()
1312513157 : Kind(TemplateInstantiation),
13126- SavedInNonInstantiationSFINAEContext(false), Entity(nullptr),
13127- Template(nullptr ), TemplateArgs (nullptr), NumTemplateArgs(0 ),
13128- DeductionInfo(nullptr) {}
13158+ SavedInNonInstantiationSFINAEContext(false),
13159+ InConstraintSubstitution(false ), Entity (nullptr), Template(nullptr ),
13160+ TemplateArgs(nullptr), NumTemplateArgs(0), DeductionInfo(nullptr) {}
1312913161
1313013162 /// Determines whether this template is an actual instantiation
1313113163 /// that should be counted toward the maximum instantiation depth.
@@ -13369,9 +13401,22 @@ class Sema final : public SemaBase {
1336913401 ///
1337013402 /// \param SkipForSpecialization when specified, any template specializations
1337113403 /// in a traversal would be ignored.
13404+ ///
1337213405 /// \param ForDefaultArgumentSubstitution indicates we should continue looking
1337313406 /// when encountering a specialized member function template, rather than
1337413407 /// returning immediately.
13408+ void getTemplateInstantiationArgs(
13409+ MultiLevelTemplateArgumentList &Result, const NamedDecl *D,
13410+ const DeclContext *DC = nullptr, bool Final = false,
13411+ std::optional<ArrayRef<TemplateArgument>> Innermost = std::nullopt,
13412+ bool RelativeToPrimary = false, const FunctionDecl *Pattern = nullptr,
13413+ bool ForConstraintInstantiation = false,
13414+ bool SkipForSpecialization = false,
13415+ bool ForDefaultArgumentSubstitution = false);
13416+
13417+ /// This creates a new \p MultiLevelTemplateArgumentList and invokes the other
13418+ /// overload with it as the first parameter. Prefer this overload in most
13419+ /// situations.
1337513420 MultiLevelTemplateArgumentList getTemplateInstantiationArgs(
1337613421 const NamedDecl *D, const DeclContext *DC = nullptr, bool Final = false,
1337713422 std::optional<ArrayRef<TemplateArgument>> Innermost = std::nullopt,
@@ -13644,7 +13689,7 @@ class Sema final : public SemaBase {
1364413689 ExprResult
1364513690 SubstConstraintExpr(Expr *E,
1364613691 const MultiLevelTemplateArgumentList &TemplateArgs);
13647- // Unlike the above, this does not evaluates constraints.
13692+ // Unlike the above, this does not evaluate constraints.
1364813693 ExprResult SubstConstraintExprWithoutSatisfaction(
1364913694 Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs);
1365013695
@@ -13794,6 +13839,12 @@ class Sema final : public SemaBase {
1379413839 return CodeSynthesisContexts.size() > NonInstantiationEntries;
1379513840 }
1379613841
13842+ /// Determine whether we are currently performing constraint substitution.
13843+ bool inConstraintSubstitution() const {
13844+ return !CodeSynthesisContexts.empty() &&
13845+ CodeSynthesisContexts.back().InConstraintSubstitution;
13846+ }
13847+
1379713848 using EntityPrinter = llvm::function_ref<void(llvm::raw_ostream &)>;
1379813849
1379913850 /// \brief create a Requirement::SubstitutionDiagnostic with only a
@@ -14786,10 +14837,10 @@ class Sema final : public SemaBase {
1478614837 const MultiLevelTemplateArgumentList &TemplateArgs,
1478714838 SourceRange TemplateIDRange);
1478814839
14789- bool CheckInstantiatedFunctionTemplateConstraints(
14790- SourceLocation PointOfInstantiation, FunctionDecl *Decl,
14791- ArrayRef<TemplateArgument> TemplateArgs,
14792- ConstraintSatisfaction &Satisfaction);
14840+ bool CheckFunctionTemplateConstraints(SourceLocation PointOfInstantiation,
14841+ FunctionDecl *Decl,
14842+ ArrayRef<TemplateArgument> TemplateArgs,
14843+ ConstraintSatisfaction &Satisfaction);
1479314844
1479414845 /// \brief Emit diagnostics explaining why a constraint expression was deemed
1479514846 /// unsatisfied.
0 commit comments