Skip to content

Commit 91546ca

Browse files
committed
Version 2: implementation based on overload resolution
1 parent 51c9e41 commit 91546ca

File tree

11 files changed

+251
-135
lines changed

11 files changed

+251
-135
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5143,8 +5143,8 @@ def err_addr_ovl_no_qualifier : Error<
51435143
"cannot form member pointer of type %0 without '&' and class name">;
51445144

51455145
def err_ovl_ambiguous_default_arg
5146-
: Error<"function call relies on ambiguous default argument %select{|for "
5147-
"parameter '%1'}0">;
5146+
: Error<"function call relies on default argument that has multiple "
5147+
"definitions">;
51485148

51495149
} // let Deferrable
51505150

clang/include/clang/Sema/Overload.h

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,13 @@ class Sema;
901901
LLVM_PREFERRED_TYPE(bool)
902902
unsigned Viable : 1;
903903

904+
/// Whether this candidate wouldn't be viable without default arguments.
905+
/// This is needed to implement the special provision about ambiguous
906+
/// default arguments of the best viable function described in
907+
/// [over.match.best]/4.
908+
LLVM_PREFERRED_TYPE(bool)
909+
unsigned ViableByDefaultArgument : 1;
910+
904911
/// Whether this candidate is the best viable function, or tied for being
905912
/// the best viable function.
906913
///
@@ -1177,11 +1184,38 @@ class Sema;
11771184
/// Whether diagnostics should be deferred.
11781185
bool shouldDeferDiags(Sema &S, ArrayRef<Expr *> Args, SourceLocation OpLoc);
11791186

1180-
/// Determine when this overload candidate will be new to the
1181-
/// overload set.
1187+
/// Determine when this overload candidate will be new to the overload set.
1188+
/// Typically the uniqueness is determined by canonical declaration
1189+
/// (i.e. semantic entity), but it's aware of a special case of default
1190+
/// arguments in redeclarations spanning across different lexical scopes.
1191+
/// See also eliminateDuplicatesWithUnusedDefaultArgs().
11821192
bool isNewCandidate(Decl *F, OverloadCandidateParamOrder PO =
11831193
OverloadCandidateParamOrder::Normal) {
11841194
uintptr_t Key = reinterpret_cast<uintptr_t>(F->getCanonicalDecl());
1195+
1196+
// There is one special case when we can't rely on just semantic
1197+
// properties of the function (i.e. entity in the Standard sense),
1198+
// which is default arguments defined in redeclarations across
1199+
// different scopes, because sets of default arguments are associated
1200+
// with lexical scope of function declaration. Which means single
1201+
// function entity can have more than one set of default arguments,
1202+
// and which of those sets are considered depends solely on what
1203+
// name lookup has found for each individual call expression.
1204+
// See [over.match.best]/4 for more details.
1205+
// In such case, we use (lexical) function declaration to determine
1206+
// uniqueness of overload candidate, instead of (semantic) entity
1207+
// it represents. This would lead to duplicates, which will be
1208+
// eliminated by eliminateDuplicatesWithUnusedDefaultArgs()
1209+
// after every candidate will be considered.
1210+
if (const auto *FD = dyn_cast<FunctionDecl>(F);
1211+
FD && FD->getLexicalDeclContext() !=
1212+
F->getCanonicalDecl()->getLexicalDeclContext()) {
1213+
auto HasDefaultArg = [](const ParmVarDecl *PDecl) {
1214+
return PDecl->hasDefaultArg();
1215+
};
1216+
if (llvm::any_of(FD->parameters(), HasDefaultArg))
1217+
Key = reinterpret_cast<uintptr_t>(FD);
1218+
}
11851219
Key |= static_cast<uintptr_t>(PO);
11861220
return Functions.insert(Key).second;
11871221
}
@@ -1195,6 +1229,14 @@ class Sema;
11951229
/// Clear out all of the candidates.
11961230
void clear(CandidateSetKind CSK);
11971231

1232+
/// Clean up duplicates left by isNewCandidate()
1233+
/// (see comment in its implementation for details.)
1234+
/// When this function is called, we should know which of duplicated
1235+
/// candidates are viable because of their default arguments, and those
1236+
/// are the only duplicates we are interested in during subsequent
1237+
/// selection of the best viable function.
1238+
void eliminateDuplicatesWithUnusedDefaultArgs();
1239+
11981240
using iterator = SmallVectorImpl<OverloadCandidate>::iterator;
11991241

12001242
iterator begin() { return Candidates.begin(); }

clang/lib/AST/Decl.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,6 +1883,33 @@ bool NamedDecl::declarationReplaces(const NamedDecl *OldD,
18831883
cast<UnresolvedUsingValueDecl>(OldD)->getQualifier());
18841884
}
18851885

1886+
{
1887+
// When default arguments across redeclarations in different lexical scopes
1888+
// are involved, we can't let one UsingShadowDecl to replace another based
1889+
// on the fact that they refer to the same canonical function.
1890+
const auto *OldShadowD = dyn_cast<UsingShadowDecl>(OldD);
1891+
const auto *NewShadowD = dyn_cast<UsingShadowDecl>(this);
1892+
if (OldShadowD && NewShadowD &&
1893+
isa<FunctionDecl>(OldShadowD->getTargetDecl()) &&
1894+
isa<FunctionDecl>(NewShadowD->getTargetDecl())) {
1895+
const auto *OldFDecl = cast<FunctionDecl>(OldShadowD->getTargetDecl());
1896+
const auto *NewFDecl = cast<FunctionDecl>(NewShadowD->getTargetDecl());
1897+
const DeclContext *OldDeclCtx = OldFDecl->getLexicalDeclContext()
1898+
->getNonTransparentContext()
1899+
->getPrimaryContext();
1900+
const DeclContext *NewDeclCtx = NewFDecl->getLexicalDeclContext()
1901+
->getNonTransparentContext()
1902+
->getPrimaryContext();
1903+
auto hasDefaultArg = [](const ParmVarDecl *PDecl) {
1904+
return PDecl->hasDefaultArg();
1905+
};
1906+
if (OldDeclCtx != NewDeclCtx &&
1907+
llvm::any_of(OldFDecl->parameters(), hasDefaultArg) &&
1908+
llvm::any_of(NewFDecl->parameters(), hasDefaultArg))
1909+
return false;
1910+
}
1911+
}
1912+
18861913
if (isRedeclarable(getKind())) {
18871914
if (getCanonicalDecl() != OldD->getCanonicalDecl())
18881915
return false;

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -490,18 +490,20 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old,
490490
continue;
491491
}
492492

493-
if (PrevForDefaultArgs->getLexicalDeclContext()->getPrimaryContext() !=
494-
ScopeDC->getPrimaryContext() &&
493+
if (PrevForDefaultArgs->getLexicalDeclContext()
494+
->getNonTransparentContext()
495+
->getPrimaryContext() !=
496+
ScopeDC->getNonTransparentContext()->getPrimaryContext() &&
495497
!New->isCXXClassMember())
496498
// If previous declaration is lexically in a different scope,
497499
// we don't inherit its default arguments, except for out-of-line
498500
// declarations of member functions.
499501
//
500502
// extern "C" and local functions can have default arguments across
501503
// different scopes, but diagnosing that early would reject well-formed
502-
// code (_N5001_.[over.match.best]/4.) Instead, they are checked
503-
// in ConvertArgumentsForCall, after the best viable function has been
504-
// selected.
504+
// code (C++2c [over.match.best]/4.) Instead, this check is deferred to
505+
// overload resolution. See handling of ambiguous overload resolution
506+
// result in FinishOverloadedCallExpr().
505507
continue;
506508

507509
// We found the right previous declaration.

clang/lib/Sema/SemaExpr.cpp

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -5826,62 +5826,6 @@ static bool isParenthetizedAndQualifiedAddressOfExpr(Expr *Fn) {
58265826
return false;
58275827
}
58285828

5829-
/// @brief Checks that each default argument needed to make the call
5830-
/// is defined only once, implementing [over.match.best]/4 rule.
5831-
///
5832-
/// @param FDecl Function declaration selected for the call
5833-
/// @param NumArgs Number of argument explicitly specified in the call
5834-
/// expression
5835-
/// @param CallLoc Source location of the call expression
5836-
static void checkDefaultArgumentsAcrossScopes(Sema &S, FunctionDecl *FDecl,
5837-
int NumArgs,
5838-
SourceLocation CallLoc) {
5839-
// [over.match.best]/4:
5840-
// If the best viable function resolves to a function
5841-
// for which multiple declarations were found,
5842-
// and if any two of these declarations inhabit different scopes
5843-
// and specify a default argument that made the function viable,
5844-
// the program is ill-formed.
5845-
5846-
// Calculate the range of parameters,
5847-
// default arguments of which made the candidate viable.
5848-
int FirstDefaultArgIndex = NumArgs;
5849-
int LastDefaultArgIndex = FDecl->getNumParams() - 1;
5850-
5851-
// For each such parameter, collect all redeclarations
5852-
// that have non-inherited default argument.
5853-
llvm::SmallDenseMap<int, llvm::TinyPtrVector<ParmVarDecl *>> ParamRedecls(
5854-
LastDefaultArgIndex - FirstDefaultArgIndex + 1);
5855-
for (FunctionDecl *Redecl : FDecl->redecls()) {
5856-
for (int i = FirstDefaultArgIndex; i <= LastDefaultArgIndex; ++i) {
5857-
ParmVarDecl *Param = Redecl->getParamDecl(i);
5858-
if (Param->hasDefaultArg() && !Param->hasInheritedDefaultArg())
5859-
ParamRedecls[i].push_back(Param);
5860-
}
5861-
}
5862-
5863-
// Emit the diagnostic if a given parameter has more than one declaration.
5864-
// MergeCXXFunctionDecl takes care of redeclarations of a default argument
5865-
// in the same scope, so if we found more than one,
5866-
// we assume they come from different scopes.
5867-
for (auto [ParamIndex, Redecls] : ParamRedecls) {
5868-
assert(!Redecls.empty());
5869-
if (Redecls.size() == 1)
5870-
continue;
5871-
5872-
ParmVarDecl *Param = FDecl->getParamDecl(ParamIndex);
5873-
if (!Param->getDeclName().isEmpty()) {
5874-
S.Diag(CallLoc, diag::err_ovl_ambiguous_default_arg)
5875-
<< 1 << Param->getName();
5876-
} else
5877-
S.Diag(CallLoc, diag::err_ovl_ambiguous_default_arg) << 0;
5878-
for (ParmVarDecl *Param : Redecls) {
5879-
S.Diag(Param->getDefaultArg()->getExprLoc(),
5880-
diag::note_default_argument_declared_here);
5881-
}
5882-
}
5883-
}
5884-
58855829
bool
58865830
Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
58875831
FunctionDecl *FDecl,
@@ -5955,13 +5899,6 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
59555899
// the call expression, before calling ConvertArgumentsForCall.
59565900
assert((Call->getNumArgs() == NumParams) &&
59575901
"We should have reserved space for the default arguments before!");
5958-
5959-
if (FDecl->isExternC() ||
5960-
std::any_of(
5961-
FDecl->redecls_begin(), FDecl->redecls_end(),
5962-
[](FunctionDecl *Redecl) { return Redecl->isLocalExternDecl(); }))
5963-
checkDefaultArgumentsAcrossScopes(*this, FDecl, Args.size(),
5964-
Call->getBeginLoc());
59655902
}
59665903

59675904
// If too many are passed and not variadic, error on the extras and drop

clang/lib/Sema/SemaLookup.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,8 +518,28 @@ void LookupResult::resolveKind() {
518518
llvm::BitVector RemovedDecls(N);
519519

520520
for (unsigned I = 0; I < N; I++) {
521-
const NamedDecl *D = Decls[I]->getUnderlyingDecl();
522-
D = cast<NamedDecl>(D->getCanonicalDecl());
521+
const NamedDecl *NonCanonicalD = Decls[I]->getUnderlyingDecl();
522+
const NamedDecl *D = cast<NamedDecl>(NonCanonicalD->getCanonicalDecl());
523+
524+
// When a function has redeclarations across different lexical scopes,
525+
// and at least some of them have default arguments, we end up with
526+
// multiple sets of default argument. Canonical declaration can't capture
527+
// that, so we use non-canonical declarations instead. Overload resolution
528+
// machinery is prepared to deal with that, see
529+
// OverloadCandidateSet::isNewCandidate() and
530+
// OverloadCandidateSet::eliminateDuplicatesWithUnusedDefaultArgs().
531+
const DeclContext *DCtx = D->getLexicalDeclContext()
532+
->getNonTransparentContext()
533+
->getPrimaryContext();
534+
if (const auto *FD = dyn_cast<FunctionDecl>(NonCanonicalD);
535+
FD && DCtx != FD->getLexicalDeclContext()
536+
->getNonTransparentContext()
537+
->getPrimaryContext()) {
538+
if (llvm::any_of(FD->parameters(), [](const ParmVarDecl *PDecl) {
539+
return PDecl->hasDefaultArg();
540+
}))
541+
D = NonCanonicalD;
542+
}
523543

524544
// Ignore an invalid declaration unless it's the only one left.
525545
// Also ignore HLSLBufferDecl which not have name conflict with other Decls.
@@ -551,6 +571,8 @@ void LookupResult::resolveKind() {
551571
continue;
552572
}
553573

574+
// If this declaration is not the first declaration of an entity,
575+
// this variable holds the index of the declaration we saw.
554576
std::optional<unsigned> ExistingI;
555577

556578
// Redeclarations of types via typedef can occur both within a scope

clang/lib/Sema/SemaOverload.cpp

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,15 @@ void OverloadCandidateSet::clear(CandidateSetKind CSK) {
11251125
Kind = CSK;
11261126
}
11271127

1128+
void OverloadCandidateSet::eliminateDuplicatesWithUnusedDefaultArgs() {
1129+
llvm::SmallPtrSet<Decl *, 16> UniqueEntities;
1130+
llvm::erase_if(Candidates, [&](const OverloadCandidate &Candidate) {
1131+
auto [It, New] =
1132+
UniqueEntities.insert(Candidate.Function->getCanonicalDecl());
1133+
return !(New || Candidate.ViableByDefaultArgument);
1134+
});
1135+
}
1136+
11281137
namespace {
11291138
class UnbridgedCastsSet {
11301139
struct Entry {
@@ -6986,6 +6995,7 @@ void Sema::AddOverloadCandidate(
69866995
Candidate.FoundDecl = FoundDecl;
69876996
Candidate.Function = Function;
69886997
Candidate.Viable = true;
6998+
Candidate.ViableByDefaultArgument = false;
69896999
Candidate.RewriteKind =
69907000
CandidateSet.getRewriteInfo().getRewriteKind(Function, PO);
69917001
Candidate.IsADLCandidate = llvm::to_underlying(IsADLCandidate);
@@ -7113,6 +7123,10 @@ void Sema::AddOverloadCandidate(
71137123
return;
71147124
}
71157125

7126+
if (Args.size() < Function->getNumParams()) {
7127+
Candidate.ViableByDefaultArgument = true;
7128+
}
7129+
71167130
// (CUDA B.1): Check for invalid calls between targets.
71177131
if (getLangOpts().CUDA) {
71187132
const FunctionDecl *Caller = getCurFunctionDecl(/*AllowLambda=*/true);
@@ -13726,6 +13740,8 @@ void Sema::AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE,
1372613740
CandidateSet, PartialOverloading,
1372713741
/*KnownValid*/ true);
1372813742

13743+
CandidateSet.eliminateDuplicatesWithUnusedDefaultArgs();
13744+
1372913745
if (ULE->requiresADL())
1373013746
AddArgumentDependentLookupCandidates(ULE->getName(), ULE->getExprLoc(),
1373113747
Args, ExplicitTemplateArgs,
@@ -14179,13 +14195,54 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
1417914195
break;
1418014196
}
1418114197

14182-
case OR_Ambiguous:
14198+
case OR_Ambiguous: {
14199+
auto handleAmbiguousDefaultArgs = [&] {
14200+
unsigned FirstDefaultArgIndex = Args.size();
14201+
llvm::SmallVector<PartialDiagnosticAt, 4> Notes;
14202+
for (const OverloadCandidate &Cand : *CandidateSet) {
14203+
if (!Cand.Best)
14204+
continue;
14205+
if (isa<CXXMethodDecl>(Cand.Function) ||
14206+
Cand.Function->isFunctionTemplateSpecialization()) {
14207+
return false;
14208+
}
14209+
if (!Cand.ViableByDefaultArgument) {
14210+
// We found a candidate marked best which wasn't made viable by
14211+
// default argument, which means this is not an "ambiguous by
14212+
// default argument" situation.
14213+
return false;
14214+
}
14215+
const ParmVarDecl *Parameter =
14216+
Cand.Function->getParamDecl(FirstDefaultArgIndex);
14217+
Notes.emplace_back(
14218+
Parameter->getDefaultArg()->getExprLoc(),
14219+
SemaRef.PDiag(diag::note_default_argument_declared_here)
14220+
<< Parameter->getDefaultArgRange());
14221+
}
14222+
if (Notes.empty())
14223+
return false;
14224+
14225+
assert(Notes.size() >= 2 &&
14226+
"Overloaded call is considered ambiguous by default arguments,"
14227+
" but we found less than two candidates");
14228+
SemaRef.Diag(Fn->getBeginLoc(), diag::err_ovl_ambiguous_default_arg)
14229+
<< Fn->getSourceRange();
14230+
llvm::sort(Notes);
14231+
for (const PartialDiagnosticAt &PDiag : Notes) {
14232+
SemaRef.Diag(PDiag.first, PDiag.second);
14233+
}
14234+
return true;
14235+
};
14236+
if (handleAmbiguousDefaultArgs())
14237+
break;
14238+
1418314239
CandidateSet->NoteCandidates(
1418414240
PartialDiagnosticAt(Fn->getBeginLoc(),
1418514241
SemaRef.PDiag(diag::err_ovl_ambiguous_call)
1418614242
<< ULE->getName() << Fn->getSourceRange()),
1418714243
SemaRef, OCD_AmbiguousCandidates, Args);
1418814244
break;
14245+
}
1418914246

1419014247
case OR_Deleted: {
1419114248
FunctionDecl *FDecl = (*Best)->Function;

0 commit comments

Comments
 (0)