@@ -10505,13 +10505,34 @@ class Sema final : public SemaBase {
10505
10505
OverloadCandidateParamOrder PO = {},
10506
10506
bool AggregateCandidateDeduction = false);
10507
10507
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
+
10508
10528
/// Check that implicit conversion sequences can be formed for each argument
10509
10529
/// whose corresponding parameter has a non-dependent type, per DR1391's
10510
10530
/// [temp.deduct.call]p10.
10511
10531
bool CheckNonDependentConversions(
10512
10532
FunctionTemplateDecl *FunctionTemplate, ArrayRef<QualType> ParamTypes,
10513
10533
ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet,
10514
- ConversionSequenceList &Conversions, bool SuppressUserConversions,
10534
+ ConversionSequenceList &Conversions,
10535
+ CheckNonDependentConversionsFlag UserConversionFlag,
10515
10536
CXXRecordDecl *ActingContext = nullptr, QualType ObjectType = QualType(),
10516
10537
Expr::Classification ObjectClassification = {},
10517
10538
OverloadCandidateParamOrder PO = {});
@@ -12555,14 +12576,22 @@ class Sema final : public SemaBase {
12555
12576
///
12556
12577
/// \param OriginalCallArgs If non-NULL, the original call arguments against
12557
12578
/// 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.
12558
12584
TemplateDeductionResult FinishTemplateArgumentDeduction(
12559
12585
FunctionTemplateDecl *FunctionTemplate,
12560
12586
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
12561
12587
unsigned NumExplicitlySpecified, FunctionDecl *&Specialization,
12562
12588
sema::TemplateDeductionInfo &Info,
12563
12589
SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs,
12564
12590
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
+ });
12566
12595
12567
12596
/// Perform template argument deduction from a function call
12568
12597
/// (C++ [temp.deduct.call]).
@@ -12598,7 +12627,7 @@ class Sema final : public SemaBase {
12598
12627
bool PartialOrdering, QualType ObjectType,
12599
12628
Expr::Classification ObjectClassification,
12600
12629
bool ForOverloadSetAddressResolution,
12601
- llvm::function_ref<bool(ArrayRef<QualType>)> CheckNonDependent);
12630
+ llvm::function_ref<bool(ArrayRef<QualType>, bool )> CheckNonDependent);
12602
12631
12603
12632
/// Deduce template arguments when taking the address of a function
12604
12633
/// template (C++ [temp.deduct.funcaddr]) or matching a specialization to
@@ -13074,6 +13103,9 @@ class Sema final : public SemaBase {
13074
13103
/// Was the enclosing context a non-instantiation SFINAE context?
13075
13104
bool SavedInNonInstantiationSFINAEContext;
13076
13105
13106
+ /// Whether we're substituting into constraints.
13107
+ bool InConstraintSubstitution;
13108
+
13077
13109
/// The point of instantiation or synthesis within the source code.
13078
13110
SourceLocation PointOfInstantiation;
13079
13111
@@ -13123,9 +13155,9 @@ class Sema final : public SemaBase {
13123
13155
13124
13156
CodeSynthesisContext()
13125
13157
: 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) {}
13129
13161
13130
13162
/// Determines whether this template is an actual instantiation
13131
13163
/// that should be counted toward the maximum instantiation depth.
@@ -13369,9 +13401,22 @@ class Sema final : public SemaBase {
13369
13401
///
13370
13402
/// \param SkipForSpecialization when specified, any template specializations
13371
13403
/// in a traversal would be ignored.
13404
+ ///
13372
13405
/// \param ForDefaultArgumentSubstitution indicates we should continue looking
13373
13406
/// when encountering a specialized member function template, rather than
13374
13407
/// 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.
13375
13420
MultiLevelTemplateArgumentList getTemplateInstantiationArgs(
13376
13421
const NamedDecl *D, const DeclContext *DC = nullptr, bool Final = false,
13377
13422
std::optional<ArrayRef<TemplateArgument>> Innermost = std::nullopt,
@@ -13644,7 +13689,7 @@ class Sema final : public SemaBase {
13644
13689
ExprResult
13645
13690
SubstConstraintExpr(Expr *E,
13646
13691
const MultiLevelTemplateArgumentList &TemplateArgs);
13647
- // Unlike the above, this does not evaluates constraints.
13692
+ // Unlike the above, this does not evaluate constraints.
13648
13693
ExprResult SubstConstraintExprWithoutSatisfaction(
13649
13694
Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs);
13650
13695
@@ -13794,6 +13839,12 @@ class Sema final : public SemaBase {
13794
13839
return CodeSynthesisContexts.size() > NonInstantiationEntries;
13795
13840
}
13796
13841
13842
+ /// Determine whether we are currently performing constraint substitution.
13843
+ bool inConstraintSubstitution() const {
13844
+ return !CodeSynthesisContexts.empty() &&
13845
+ CodeSynthesisContexts.back().InConstraintSubstitution;
13846
+ }
13847
+
13797
13848
using EntityPrinter = llvm::function_ref<void(llvm::raw_ostream &)>;
13798
13849
13799
13850
/// \brief create a Requirement::SubstitutionDiagnostic with only a
@@ -14786,10 +14837,10 @@ class Sema final : public SemaBase {
14786
14837
const MultiLevelTemplateArgumentList &TemplateArgs,
14787
14838
SourceRange TemplateIDRange);
14788
14839
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);
14793
14844
14794
14845
/// \brief Emit diagnostics explaining why a constraint expression was deemed
14795
14846
/// unsatisfied.
0 commit comments