From bcf327af7b922955c1853666ea803b1e22420034 Mon Sep 17 00:00:00 2001 From: Larisse Voufo Date: Tue, 10 Feb 2015 02:20:14 +0000 Subject: [PATCH] A temporary fix for backward compatibility breakages caused by PR12117. llvm-svn: 228654 --- clang/lib/Sema/SemaInit.cpp | 19 +++++++++++++++---- .../SemaCXX/cxx0x-initializer-constructor.cpp | 7 ++++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index b35110a1e28e..a25aada0c2b3 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -3113,7 +3113,7 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc, ArrayRef Ctors, OverloadCandidateSet::iterator &Best, bool CopyInitializing, bool AllowExplicit, - bool OnlyListConstructors) { + bool OnlyListConstructors, bool IsListInit) { CandidateSet.clear(); for (ArrayRef::iterator @@ -3138,7 +3138,16 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc, // of a class copy-initialization, or // — 13.3.1.4, 13.3.1.5, or 13.3.1.6 (in all cases), // user-defined conversion sequences are not considered. - if (CopyInitializing && Constructor->isCopyOrMoveConstructor()) + // FIXME: This breaks backward compatibility, e.g. PR12117. As a + // temporary fix, let's re-instate the third bullet above until + // there is a resolution in the standard, i.e., + // - 13.3.1.7 when the initializer list has exactly one element that is + // itself an initializer list and a conversion to some class X or + // reference to (possibly cv-qualified) X is considered for the first + // parameter of a constructor of X. + if ((CopyInitializing || + (IsListInit && Args.size() == 1 && isa(Args[0]))) && + Constructor->isCopyOrMoveConstructor()) SuppressUserConversions = true; } @@ -3240,7 +3249,8 @@ static void TryConstructorInitialization(Sema &S, Result = ResolveConstructorOverload(S, Kind.getLocation(), Args, CandidateSet, Ctors, Best, CopyInitialization, AllowExplicit, - /*OnlyListConstructor=*/true); + /*OnlyListConstructor=*/true, + IsListInit); // Time to unwrap the init list. Args = MultiExprArg(ILE->getInits(), ILE->getNumInits()); @@ -3256,7 +3266,8 @@ static void TryConstructorInitialization(Sema &S, Result = ResolveConstructorOverload(S, Kind.getLocation(), Args, CandidateSet, Ctors, Best, CopyInitialization, AllowExplicit, - /*OnlyListConstructors=*/false); + /*OnlyListConstructors=*/false, + IsListInit); } if (Result) { Sequence.SetOverloadFailure(IsListInit ? diff --git a/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp b/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp index b481865d8447..0cd5aa7401a3 100644 --- a/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp +++ b/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp @@ -214,9 +214,10 @@ namespace PR12092 { namespace PR12117 { struct A { A(int); }; - struct B { B(A); } b{{0}}; // expected-error {{call to constructor of 'struct B' is ambiguous}} \ - // expected-note 2{{candidate is the implicit}} \ - // expected-note {{candidate constructor}} + struct B { B(A); } b{{0}}; //FIXME: non-conformant. Temporary fix until standard resolution. + // expected- error {{call to constructor of 'struct B' is ambiguous}} \ + // expected- note 2{{candidate is the implicit}} \ + // expected- note {{candidate constructor}} struct C { C(int); } c{0}; }