@@ -10312,23 +10312,27 @@ bool Sema::CheckFunctionTemplateSpecialization(
10312
10312
return false ;
10313
10313
}
10314
10314
10315
- static bool IsMoreConstrainedFunction (Sema &S, FunctionDecl *FD1,
10316
- FunctionDecl *FD2) {
10315
+ FunctionDecl *Sema::getMoreConstrainedFunction (FunctionDecl *FD1,
10316
+ FunctionDecl *FD2) {
10317
+ assert (!FD1->getDescribedTemplate () && !FD2->getDescribedTemplate () &&
10318
+ " not for function templates" );
10319
+ FunctionDecl *F1 = FD1;
10317
10320
if (FunctionDecl *MF = FD1->getInstantiatedFromMemberFunction ())
10318
- FD1 = MF;
10321
+ F1 = MF;
10322
+ FunctionDecl *F2 = FD2;
10319
10323
if (FunctionDecl *MF = FD2->getInstantiatedFromMemberFunction ())
10320
- FD2 = MF;
10324
+ F2 = MF;
10321
10325
llvm::SmallVector<const Expr *, 3 > AC1, AC2;
10322
- FD1 ->getAssociatedConstraints (AC1);
10323
- FD2 ->getAssociatedConstraints (AC2);
10326
+ F1 ->getAssociatedConstraints (AC1);
10327
+ F2 ->getAssociatedConstraints (AC2);
10324
10328
bool AtLeastAsConstrained1, AtLeastAsConstrained2;
10325
- if (S. IsAtLeastAsConstrained (FD1 , AC1, FD2 , AC2, AtLeastAsConstrained1))
10326
- return false ;
10327
- if (S. IsAtLeastAsConstrained (FD2 , AC2, FD1 , AC1, AtLeastAsConstrained2))
10328
- return false ;
10329
+ if (IsAtLeastAsConstrained (F1 , AC1, F2 , AC2, AtLeastAsConstrained1))
10330
+ return nullptr ;
10331
+ if (IsAtLeastAsConstrained (F2 , AC2, F1 , AC1, AtLeastAsConstrained2))
10332
+ return nullptr ;
10329
10333
if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
10330
- return false ;
10331
- return AtLeastAsConstrained1;
10334
+ return nullptr ;
10335
+ return AtLeastAsConstrained1 ? FD1 : FD2 ;
10332
10336
}
10333
10337
10334
10338
// / Perform semantic analysis for the given non-template member
@@ -10358,35 +10362,54 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
10358
10362
if (Previous.empty ()) {
10359
10363
// Nowhere to look anyway.
10360
10364
} else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Member)) {
10365
+ SmallVector<FunctionDecl *> Candidates;
10366
+ bool Ambiguous = false ;
10361
10367
for (LookupResult::iterator I = Previous.begin (), E = Previous.end ();
10362
10368
I != E; ++I) {
10363
- NamedDecl *D = (*I)->getUnderlyingDecl ();
10364
- if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
10365
- QualType Adjusted = Function->getType ();
10366
- if (!hasExplicitCallingConv (Adjusted))
10367
- Adjusted = adjustCCAndNoReturn (Adjusted, Method->getType ());
10368
- if (!Context.hasSameType (Adjusted, Method->getType ()))
10369
- continue ;
10370
- if (Method->getTrailingRequiresClause ()) {
10371
- ConstraintSatisfaction Satisfaction;
10372
- if (CheckFunctionConstraints (Method, Satisfaction,
10373
- /* UsageLoc=*/ Member->getLocation (),
10374
- /* ForOverloadResolution=*/ true ) ||
10375
- !Satisfaction.IsSatisfied )
10376
- continue ;
10377
- if (Instantiation &&
10378
- !IsMoreConstrainedFunction (*this , Method,
10379
- cast<CXXMethodDecl>(Instantiation)))
10380
- continue ;
10381
- }
10382
- // This doesn't handle deduced return types, but both function
10383
- // declarations should be undeduced at this point.
10369
+ CXXMethodDecl *Method =
10370
+ dyn_cast<CXXMethodDecl>((*I)->getUnderlyingDecl ());
10371
+ if (!Method)
10372
+ continue ;
10373
+ QualType Adjusted = Function->getType ();
10374
+ if (!hasExplicitCallingConv (Adjusted))
10375
+ Adjusted = adjustCCAndNoReturn (Adjusted, Method->getType ());
10376
+ // This doesn't handle deduced return types, but both function
10377
+ // declarations should be undeduced at this point.
10378
+ if (!Context.hasSameType (Adjusted, Function->getType ()))
10379
+ continue ;
10380
+ // FIXME: What if neither function is more constrained than the other?
10381
+ if (ConstraintSatisfaction Satisfaction;
10382
+ Method->getTrailingRequiresClause () &&
10383
+ (CheckFunctionConstraints (Method, Satisfaction,
10384
+ /* UsageLoc=*/ Member->getLocation (),
10385
+ /* ForOverloadResolution=*/ true ) ||
10386
+ !Satisfaction.IsSatisfied ))
10387
+ continue ;
10388
+ Candidates.push_back (Method);
10389
+ FunctionDecl *MoreConstrained =
10390
+ Instantiation ? getMoreConstrainedFunction (
10391
+ Method, cast<FunctionDecl>(Instantiation))
10392
+ : Method;
10393
+ if (!MoreConstrained) {
10394
+ Ambiguous = true ;
10395
+ continue ;
10396
+ }
10397
+ if (MoreConstrained == Method) {
10398
+ Ambiguous = false ;
10384
10399
FoundInstantiation = *I;
10385
10400
Instantiation = Method;
10386
10401
InstantiatedFrom = Method->getInstantiatedFromMemberFunction ();
10387
10402
MSInfo = Method->getMemberSpecializationInfo ();
10388
10403
}
10389
10404
}
10405
+ if (Ambiguous) {
10406
+ Diag (Member->getLocation (), diag::err_function_member_spec_ambiguous)
10407
+ << Member;
10408
+ for (FunctionDecl *Candidate : Candidates)
10409
+ Diag (Candidate->getLocation (), diag::note_function_member_spec_matched)
10410
+ << Candidate;
10411
+ return true ;
10412
+ }
10390
10413
} else if (isa<VarDecl>(Member)) {
10391
10414
VarDecl *PrevVar;
10392
10415
if (Previous.isSingleResult () &&
0 commit comments