@@ -10369,20 +10369,16 @@ static bool allowAmbiguity(ASTContext &Context, const FunctionDecl *F1,
10369
10369
/// [over.match.best.general]p2.6
10370
10370
/// F1 and F2 are non-template functions with the same
10371
10371
/// 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);
10381
10377
if (Fn1->isVariadic() != Fn2->isVariadic())
10382
10378
return false;
10383
10379
10384
- if (!S.FunctionNonObjectParamTypesAreEqual(
10385
- Fn1, Fn2, nullptr, Cand1.isReversed() ^ Cand2.isReversed() ))
10380
+ if (!S.FunctionNonObjectParamTypesAreEqual(Fn1, Fn2, nullptr,
10381
+ IsFn1Reversed ^ IsFn2Reversed ))
10386
10382
return false;
10387
10383
10388
10384
auto *Mem1 = dyn_cast<CXXMethodDecl>(Fn1);
@@ -10403,6 +10399,30 @@ static bool sameFunctionParameterTypeLists(Sema &S,
10403
10399
return true;
10404
10400
}
10405
10401
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
+
10406
10426
/// isBetterOverloadCandidate - Determines whether the first overload
10407
10427
/// candidate is a better candidate than the second (C++ 13.3.3p1).
10408
10428
bool clang::isBetterOverloadCandidate(
@@ -10649,12 +10669,12 @@ bool clang::isBetterOverloadCandidate(
10649
10669
}
10650
10670
}
10651
10671
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)
10658
10678
return true;
10659
10679
10660
10680
// -- F1 is a constructor for a class D, F2 is a constructor for a base
@@ -12999,9 +13019,10 @@ class AddressOfFunctionResolver {
12999
13019
// C++ [over.over]p4:
13000
13020
// If more than one function is selected, [...]
13001
13021
if (Matches.size() > 1 && !eliminiateSuboptimalOverloadCandidates()) {
13002
- if (FoundNonTemplateFunction)
13022
+ if (FoundNonTemplateFunction) {
13003
13023
EliminateAllTemplateMatches();
13004
- else
13024
+ EliminateLessPartialOrderingConstrainedMatches();
13025
+ } else
13005
13026
EliminateAllExceptMostSpecializedTemplate();
13006
13027
}
13007
13028
}
@@ -13252,6 +13273,33 @@ class AddressOfFunctionResolver {
13252
13273
}
13253
13274
}
13254
13275
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
+
13255
13303
void EliminateSuboptimalCudaMatches() {
13256
13304
S.CUDA().EraseUnwantedMatches(S.getCurFunctionDecl(/*AllowLambda=*/true),
13257
13305
Matches);
@@ -13408,8 +13456,8 @@ Sema::resolveAddressOfSingleOverloadCandidate(Expr *E, DeclAccessPair &Pair) {
13408
13456
Result = FD;
13409
13457
};
13410
13458
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.
13413
13461
if (Result) {
13414
13462
// Check CUDA preference first. If the candidates have differennt CUDA
13415
13463
// preference, choose the one with higher CUDA preference. Otherwise,
@@ -13424,9 +13472,17 @@ Sema::resolveAddressOfSingleOverloadCandidate(Expr *E, DeclAccessPair &Pair) {
13424
13472
continue;
13425
13473
}
13426
13474
}
13427
- // FD has the same CUDA prefernece than Result. Continue check
13475
+ // FD has the same CUDA preference than Result. Continue to check
13428
13476
// 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);
13430
13486
if (MoreConstrained != FD) {
13431
13487
if (!MoreConstrained) {
13432
13488
IsResultAmbiguous = true;
@@ -13443,7 +13499,6 @@ Sema::resolveAddressOfSingleOverloadCandidate(Expr *E, DeclAccessPair &Pair) {
13443
13499
return nullptr;
13444
13500
13445
13501
if (Result) {
13446
- SmallVector<const Expr *, 1> ResultAC;
13447
13502
// We skipped over some ambiguous declarations which might be ambiguous with
13448
13503
// the selected result.
13449
13504
for (FunctionDecl *Skipped : AmbiguousDecls) {
@@ -13489,7 +13544,7 @@ bool Sema::resolveAndFixAddressOfSingleOverloadCandidate(
13489
13544
13490
13545
FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(
13491
13546
OverloadExpr *ovl, bool Complain, DeclAccessPair *FoundResult,
13492
- TemplateSpecCandidateSet *FailedTSC) {
13547
+ TemplateSpecCandidateSet *FailedTSC, bool ForTypeDeduction ) {
13493
13548
// C++ [over.over]p1:
13494
13549
// [...] [Note: any redundant set of parentheses surrounding the
13495
13550
// overloaded function name is ignored (5.1). ]
@@ -13540,8 +13595,16 @@ FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(
13540
13595
13541
13596
assert(Specialization && "no specialization and no error?");
13542
13597
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.
13544
13602
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.
13545
13608
if (Complain) {
13546
13609
Diag(ovl->getExprLoc(), diag::err_addr_ovl_ambiguous)
13547
13610
<< ovl->getName();
0 commit comments