Tentatively fix PR12117. The test case from the bug now passes, and all existing tests still pass, but there may still be corner cases.

llvm-svn: 151716
This commit is contained in:
Sebastian Redl 2012-02-29 12:47:43 +00:00
parent 972720e564
commit c7b718eb53
2 changed files with 17 additions and 8 deletions

View File

@ -2795,7 +2795,7 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
DeclContext::lookup_iterator ConEnd, DeclContext::lookup_iterator ConEnd,
OverloadCandidateSet::iterator &Best, OverloadCandidateSet::iterator &Best,
bool CopyInitializing, bool AllowExplicit, bool CopyInitializing, bool AllowExplicit,
bool OnlyListConstructors) { bool OnlyListConstructors, bool InitListSyntax) {
CandidateSet.clear(); CandidateSet.clear();
for (; Con != ConEnd; ++Con) { for (; Con != ConEnd; ++Con) {
@ -2813,9 +2813,10 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
Constructor = cast<CXXConstructorDecl>(D); Constructor = cast<CXXConstructorDecl>(D);
// If we're performing copy initialization using a copy constructor, we // If we're performing copy initialization using a copy constructor, we
// suppress user-defined conversions on the arguments. // suppress user-defined conversions on the arguments. We do the same for
// FIXME: Move constructors? // move constructors.
if (CopyInitializing && Constructor->isCopyConstructor()) if ((CopyInitializing || (InitListSyntax && NumArgs == 1)) &&
Constructor->isCopyOrMoveConstructor())
SuppressUserConversions = true; SuppressUserConversions = true;
} }
@ -2825,8 +2826,8 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
if (ConstructorTmpl) if (ConstructorTmpl)
S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
/*ExplicitArgs*/ 0, /*ExplicitArgs*/ 0,
llvm::makeArrayRef(Args, NumArgs), CandidateSet, llvm::makeArrayRef(Args, NumArgs),
SuppressUserConversions); CandidateSet, SuppressUserConversions);
else { else {
// C++ [over.match.copy]p1: // C++ [over.match.copy]p1:
// - When initializing a temporary to be bound to the first parameter // - When initializing a temporary to be bound to the first parameter
@ -2919,7 +2920,8 @@ static void TryConstructorInitialization(Sema &S,
Result = ResolveConstructorOverload(S, Kind.getLocation(), Args, NumArgs, Result = ResolveConstructorOverload(S, Kind.getLocation(), Args, NumArgs,
CandidateSet, ConStart, ConEnd, Best, CandidateSet, ConStart, ConEnd, Best,
CopyInitialization, AllowExplicit, CopyInitialization, AllowExplicit,
/*OnlyListConstructor=*/true); /*OnlyListConstructor=*/true,
InitListSyntax);
// Time to unwrap the init list. // Time to unwrap the init list.
InitListExpr *ILE = cast<InitListExpr>(Args[0]); InitListExpr *ILE = cast<InitListExpr>(Args[0]);
@ -2937,7 +2939,8 @@ static void TryConstructorInitialization(Sema &S,
Result = ResolveConstructorOverload(S, Kind.getLocation(), Args, NumArgs, Result = ResolveConstructorOverload(S, Kind.getLocation(), Args, NumArgs,
CandidateSet, ConStart, ConEnd, Best, CandidateSet, ConStart, ConEnd, Best,
CopyInitialization, AllowExplicit, CopyInitialization, AllowExplicit,
/*OnlyListConstructors=*/false); /*OnlyListConstructors=*/false,
InitListSyntax);
} }
if (Result) { if (Result) {
Sequence.SetOverloadFailure(InitListSyntax ? Sequence.SetOverloadFailure(InitListSyntax ?

View File

@ -212,3 +212,9 @@ namespace PR12092 {
} }
} }
namespace PR12117 {
struct A { A(int); };
struct B { B(A); } b{{0}};
struct C { C(int); } c{0};
}