forked from OSchip/llvm-project
When performing overload resolution, only compare the final conversion
sequences for two conversion functions when in fact we are in the text of initialization by a user-defined conversion sequences. Fixes PR8034. llvm-svn: 113724
This commit is contained in:
parent
6162334ce0
commit
d5b730c9d5
|
@ -630,7 +630,8 @@ namespace clang {
|
|||
|
||||
/// Find the best viable function on this overload set, if it exists.
|
||||
OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc,
|
||||
OverloadCandidateSet::iterator& Best);
|
||||
OverloadCandidateSet::iterator& Best,
|
||||
bool UserDefinedConversion = false);
|
||||
|
||||
void NoteCandidates(Sema &S,
|
||||
OverloadCandidateDisplayKind OCD,
|
||||
|
@ -642,7 +643,8 @@ namespace clang {
|
|||
bool isBetterOverloadCandidate(Sema &S,
|
||||
const OverloadCandidate& Cand1,
|
||||
const OverloadCandidate& Cand2,
|
||||
SourceLocation Loc);
|
||||
SourceLocation Loc,
|
||||
bool UserDefinedConversion = false);
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_SEMA_OVERLOAD_H
|
||||
|
|
|
@ -2389,7 +2389,7 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
|
|||
// Perform overload resolution. If it fails, return the failed result.
|
||||
OverloadCandidateSet::iterator Best;
|
||||
if (OverloadingResult Result
|
||||
= CandidateSet.BestViableFunction(S, DeclLoc, Best))
|
||||
= CandidateSet.BestViableFunction(S, DeclLoc, Best, true))
|
||||
return Result;
|
||||
|
||||
FunctionDecl *Function = Best->Function;
|
||||
|
@ -2981,7 +2981,7 @@ static void TryUserDefinedConversion(Sema &S,
|
|||
// Perform overload resolution. If it fails, return the failed result.
|
||||
OverloadCandidateSet::iterator Best;
|
||||
if (OverloadingResult Result
|
||||
= CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
|
||||
= CandidateSet.BestViableFunction(S, DeclLoc, Best, true)) {
|
||||
Sequence.SetOverloadFailure(
|
||||
InitializationSequence::FK_UserConversionOverloadFailed,
|
||||
Result);
|
||||
|
@ -3276,10 +3276,10 @@ static bool shouldDestroyTemporary(const InitializedEntity &Entity) {
|
|||
/// a temporary object, or an error expression if a copy could not be
|
||||
/// created.
|
||||
static ExprResult CopyObject(Sema &S,
|
||||
QualType T,
|
||||
const InitializedEntity &Entity,
|
||||
ExprResult CurInit,
|
||||
bool IsExtraneousCopy) {
|
||||
QualType T,
|
||||
const InitializedEntity &Entity,
|
||||
ExprResult CurInit,
|
||||
bool IsExtraneousCopy) {
|
||||
// Determine which class type we're copying to.
|
||||
Expr *CurInitExpr = (Expr *)CurInit.get();
|
||||
CXXRecordDecl *Class = 0;
|
||||
|
@ -4033,7 +4033,8 @@ bool InitializationSequence::Diagnose(Sema &S,
|
|||
<< Args[0]->getSourceRange();
|
||||
OverloadCandidateSet::iterator Best;
|
||||
OverloadingResult Ovl
|
||||
= FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
|
||||
= FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best,
|
||||
true);
|
||||
if (Ovl == OR_Deleted) {
|
||||
S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
|
||||
<< Best->Function->isDeleted();
|
||||
|
|
|
@ -2041,7 +2041,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
|
|||
}
|
||||
|
||||
OverloadCandidateSet::iterator Best;
|
||||
switch (CandidateSet.BestViableFunction(S, From->getLocStart(), Best)) {
|
||||
switch (CandidateSet.BestViableFunction(S, From->getLocStart(), Best, true)) {
|
||||
case OR_Success:
|
||||
// Record the standard conversion we used and the conversion function.
|
||||
if (CXXConstructorDecl *Constructor
|
||||
|
@ -2769,7 +2769,7 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
|
|||
}
|
||||
|
||||
OverloadCandidateSet::iterator Best;
|
||||
switch (CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
|
||||
switch (CandidateSet.BestViableFunction(S, DeclLoc, Best, true)) {
|
||||
case OR_Success:
|
||||
// C++ [over.ics.ref]p1:
|
||||
//
|
||||
|
@ -5329,7 +5329,8 @@ bool
|
|||
isBetterOverloadCandidate(Sema &S,
|
||||
const OverloadCandidate& Cand1,
|
||||
const OverloadCandidate& Cand2,
|
||||
SourceLocation Loc) {
|
||||
SourceLocation Loc,
|
||||
bool UserDefinedConversion) {
|
||||
// Define viable functions to be better candidates than non-viable
|
||||
// functions.
|
||||
if (!Cand2.Viable)
|
||||
|
@ -5404,7 +5405,7 @@ isBetterOverloadCandidate(Sema &S,
|
|||
// the type of the entity being initialized) is a better
|
||||
// conversion sequence than the standard conversion sequence
|
||||
// from the return type of F2 to the destination type.
|
||||
if (Cand1.Function && Cand2.Function &&
|
||||
if (UserDefinedConversion && Cand1.Function && Cand2.Function &&
|
||||
isa<CXXConversionDecl>(Cand1.Function) &&
|
||||
isa<CXXConversionDecl>(Cand2.Function)) {
|
||||
switch (CompareStandardConversionSequences(S,
|
||||
|
@ -5441,12 +5442,14 @@ isBetterOverloadCandidate(Sema &S,
|
|||
/// \returns The result of overload resolution.
|
||||
OverloadingResult
|
||||
OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
|
||||
iterator& Best) {
|
||||
iterator& Best,
|
||||
bool UserDefinedConversion) {
|
||||
// Find the best viable function.
|
||||
Best = end();
|
||||
for (iterator Cand = begin(); Cand != end(); ++Cand) {
|
||||
if (Cand->Viable)
|
||||
if (Best == end() || isBetterOverloadCandidate(S, *Cand, *Best, Loc))
|
||||
if (Best == end() || isBetterOverloadCandidate(S, *Cand, *Best, Loc,
|
||||
UserDefinedConversion))
|
||||
Best = Cand;
|
||||
}
|
||||
|
||||
|
@ -5459,7 +5462,8 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
|
|||
for (iterator Cand = begin(); Cand != end(); ++Cand) {
|
||||
if (Cand->Viable &&
|
||||
Cand != Best &&
|
||||
!isBetterOverloadCandidate(S, *Best, *Cand, Loc)) {
|
||||
!isBetterOverloadCandidate(S, *Best, *Cand, Loc,
|
||||
UserDefinedConversion)) {
|
||||
Best = end();
|
||||
return OR_Ambiguous;
|
||||
}
|
||||
|
|
|
@ -343,3 +343,13 @@ namespace PR8065 {
|
|||
|
||||
Container<int> test;
|
||||
}
|
||||
|
||||
namespace PR8034 {
|
||||
struct C {
|
||||
operator int();
|
||||
|
||||
private:
|
||||
template <typename T> operator T();
|
||||
};
|
||||
int x = C().operator int();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue