@@ -10369,20 +10369,16 @@ static bool allowAmbiguity(ASTContext &Context, const FunctionDecl *F1,
1036910369/// [over.match.best.general]p2.6
1037010370/// F1 and F2 are non-template functions with the same
1037110371/// non-object-parameter-type-lists, and F1 is more constrained than F2 [...]
10372- static bool sameFunctionParameterTypeLists(Sema &S,
10373- const OverloadCandidate &Cand1,
10374- const OverloadCandidate &Cand2) {
10375- if (!Cand1.Function || !Cand2.Function)
10376- return false;
10377-
10378- FunctionDecl *Fn1 = Cand1.Function;
10379- FunctionDecl *Fn2 = Cand2.Function;
10380-
10372+ static bool sameFunctionParameterTypeLists(Sema &S, FunctionDecl *Fn1,
10373+ FunctionDecl *Fn2,
10374+ bool IsFn1Reversed,
10375+ bool IsFn2Reversed) {
10376+ assert(Fn1 && Fn2);
1038110377 if (Fn1->isVariadic() != Fn2->isVariadic())
1038210378 return false;
1038310379
10384- if (!S.FunctionNonObjectParamTypesAreEqual(
10385- Fn1, Fn2, nullptr, Cand1.isReversed() ^ Cand2.isReversed() ))
10380+ if (!S.FunctionNonObjectParamTypesAreEqual(Fn1, Fn2, nullptr,
10381+ IsFn1Reversed ^ IsFn2Reversed ))
1038610382 return false;
1038710383
1038810384 auto *Mem1 = dyn_cast<CXXMethodDecl>(Fn1);
@@ -10403,6 +10399,30 @@ static bool sameFunctionParameterTypeLists(Sema &S,
1040310399 return true;
1040410400}
1040510401
10402+ static FunctionDecl *
10403+ getMorePartialOrderingConstrained(Sema &S, FunctionDecl *Fn1, FunctionDecl *Fn2,
10404+ bool IsFn1Reversed, bool IsFn2Reversed) {
10405+ if (!Fn1 || !Fn2)
10406+ return nullptr;
10407+
10408+ // C++ [temp.constr.order]:
10409+ // A non-template function F1 is more partial-ordering-constrained than a
10410+ // non-template function F2 if:
10411+ bool Cand1IsSpecialization = Fn1->getPrimaryTemplate();
10412+ bool Cand2IsSpecialization = Fn2->getPrimaryTemplate();
10413+
10414+ if (Cand1IsSpecialization || Cand2IsSpecialization)
10415+ return nullptr;
10416+
10417+ // - they have the same non-object-parameter-type-lists, and [...]
10418+ if (!sameFunctionParameterTypeLists(S, Fn1, Fn2, IsFn1Reversed,
10419+ IsFn2Reversed))
10420+ return nullptr;
10421+
10422+ // - the declaration of F1 is more constrained than the declaration of F2.
10423+ return S.getMoreConstrainedFunction(Fn1, Fn2);
10424+ }
10425+
1040610426/// isBetterOverloadCandidate - Determines whether the first overload
1040710427/// candidate is a better candidate than the second (C++ 13.3.3p1).
1040810428bool clang::isBetterOverloadCandidate(
@@ -10649,12 +10669,12 @@ bool clang::isBetterOverloadCandidate(
1064910669 }
1065010670 }
1065110671
10652- // -— F1 and F2 are non-template functions with the same
10653- // parameter-type-lists, and F1 is more constrained than F2 [...],
10654- if (!Cand1IsSpecialization && !Cand2IsSpecialization &&
10655- sameFunctionParameterTypeLists( S, Cand1, Cand2) &&
10656- S.getMoreConstrainedFunction(Cand1.Function, Cand2.Function) ==
10657- Cand1.Function)
10672+ // -— F1 and F2 are non-template functions and F1 is more
10673+ // partial-ordering- constrained than F2 [...],
10674+ if (FunctionDecl *F = getMorePartialOrderingConstrained(
10675+ S, Cand1.Function , Cand2.Function, Cand1.isReversed(),
10676+ Cand2.isReversed());
10677+ F && F == Cand1.Function)
1065810678 return true;
1065910679
1066010680 // -- F1 is a constructor for a class D, F2 is a constructor for a base
@@ -12999,9 +13019,10 @@ class AddressOfFunctionResolver {
1299913019 // C++ [over.over]p4:
1300013020 // If more than one function is selected, [...]
1300113021 if (Matches.size() > 1 && !eliminiateSuboptimalOverloadCandidates()) {
13002- if (FoundNonTemplateFunction)
13022+ if (FoundNonTemplateFunction) {
1300313023 EliminateAllTemplateMatches();
13004- else
13024+ EliminateLessPartialOrderingConstrainedMatches();
13025+ } else
1300513026 EliminateAllExceptMostSpecializedTemplate();
1300613027 }
1300713028 }
@@ -13252,6 +13273,33 @@ class AddressOfFunctionResolver {
1325213273 }
1325313274 }
1325413275
13276+ void EliminateLessPartialOrderingConstrainedMatches() {
13277+ // C++ [over.over]p5:
13278+ // [...] Any given non-template function F0 is eliminated if the set
13279+ // contains a second non-template function that is more
13280+ // partial-ordering-constrained than F0. [...]
13281+ assert(Matches[0].second->getPrimaryTemplate() == nullptr &&
13282+ "Call EliminateAllTemplateMatches() first");
13283+ SmallVector<std::pair<DeclAccessPair, FunctionDecl *>, 4> Results;
13284+ Results.push_back(Matches[0]);
13285+ for (unsigned I = 1, N = Matches.size(); I < N; ++I) {
13286+ assert(Matches[I].second->getPrimaryTemplate() == nullptr);
13287+ FunctionDecl *F = getMorePartialOrderingConstrained(
13288+ S, Matches[I].second, Results[0].second,
13289+ /*IsFn1Reversed=*/false,
13290+ /*IsFn2Reversed=*/false);
13291+ if (!F) {
13292+ Results.push_back(Matches[I]);
13293+ continue;
13294+ }
13295+ if (F == Matches[I].second) {
13296+ Results.clear();
13297+ Results.push_back(Matches[I]);
13298+ }
13299+ }
13300+ std::swap(Matches, Results);
13301+ }
13302+
1325513303 void EliminateSuboptimalCudaMatches() {
1325613304 S.CUDA().EraseUnwantedMatches(S.getCurFunctionDecl(/*AllowLambda=*/true),
1325713305 Matches);
@@ -13408,8 +13456,8 @@ Sema::resolveAddressOfSingleOverloadCandidate(Expr *E, DeclAccessPair &Pair) {
1340813456 Result = FD;
1340913457 };
1341013458
13411- // We have more than one result - see if it is more constrained than the
13412- // previous one.
13459+ // We have more than one result - see if it is more
13460+ // partial-ordering-constrained than the previous one.
1341313461 if (Result) {
1341413462 // Check CUDA preference first. If the candidates have differennt CUDA
1341513463 // preference, choose the one with higher CUDA preference. Otherwise,
@@ -13424,9 +13472,17 @@ Sema::resolveAddressOfSingleOverloadCandidate(Expr *E, DeclAccessPair &Pair) {
1342413472 continue;
1342513473 }
1342613474 }
13427- // FD has the same CUDA prefernece than Result. Continue check
13475+ // FD has the same CUDA preference than Result. Continue to check
1342813476 // constraints.
13429- FunctionDecl *MoreConstrained = getMoreConstrainedFunction(FD, Result);
13477+
13478+ // C++ [over.over]p5:
13479+ // [...] Any given non-template function F0 is eliminated if the set
13480+ // contains a second non-template function that is more
13481+ // partial-ordering-constrained than F0 [...]
13482+ FunctionDecl *MoreConstrained =
13483+ getMorePartialOrderingConstrained(*this, FD, Result,
13484+ /*IsFn1Reversed=*/false,
13485+ /*IsFn2Reversed=*/false);
1343013486 if (MoreConstrained != FD) {
1343113487 if (!MoreConstrained) {
1343213488 IsResultAmbiguous = true;
@@ -13443,7 +13499,6 @@ Sema::resolveAddressOfSingleOverloadCandidate(Expr *E, DeclAccessPair &Pair) {
1344313499 return nullptr;
1344413500
1344513501 if (Result) {
13446- SmallVector<const Expr *, 1> ResultAC;
1344713502 // We skipped over some ambiguous declarations which might be ambiguous with
1344813503 // the selected result.
1344913504 for (FunctionDecl *Skipped : AmbiguousDecls) {
@@ -13489,7 +13544,7 @@ bool Sema::resolveAndFixAddressOfSingleOverloadCandidate(
1348913544
1349013545FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(
1349113546 OverloadExpr *ovl, bool Complain, DeclAccessPair *FoundResult,
13492- TemplateSpecCandidateSet *FailedTSC) {
13547+ TemplateSpecCandidateSet *FailedTSC, bool ForTypeDeduction ) {
1349313548 // C++ [over.over]p1:
1349413549 // [...] [Note: any redundant set of parentheses surrounding the
1349513550 // overloaded function name is ignored (5.1). ]
@@ -13540,8 +13595,16 @@ FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(
1354013595
1354113596 assert(Specialization && "no specialization and no error?");
1354213597
13543- // Multiple matches; we can't resolve to a single declaration.
13598+ // C++ [temp.deduct.call]p6:
13599+ // [...] If all successful deductions yield the same deduced A, that
13600+ // deduced A is the result of deduction; otherwise, the parameter is
13601+ // treated as a non-deduced context.
1354413602 if (Matched) {
13603+ if (ForTypeDeduction &&
13604+ isSameOrCompatibleFunctionType(Matched->getType(),
13605+ Specialization->getType()))
13606+ continue;
13607+ // Multiple matches; we can't resolve to a single declaration.
1354513608 if (Complain) {
1354613609 Diag(ovl->getExprLoc(), diag::err_addr_ovl_ambiguous)
1354713610 << ovl->getName();
0 commit comments