]> granicus.if.org Git - clang/commitdiff
A temporary fix for backward compatibility breakages caused by PR12117.
authorLarisse Voufo <lvoufo@google.com>
Tue, 10 Feb 2015 02:20:14 +0000 (02:20 +0000)
committerLarisse Voufo <lvoufo@google.com>
Tue, 10 Feb 2015 02:20:14 +0000 (02:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@228654 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaInit.cpp
test/SemaCXX/cxx0x-initializer-constructor.cpp

index b35110a1e28ea8d1ecd11dd9a12bdda46e1bf784..a25aada0c2b32ae7c2e2f065088ce3ebeae08357 100644 (file)
@@ -3113,7 +3113,7 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
                            ArrayRef<NamedDecl *> Ctors,
                            OverloadCandidateSet::iterator &Best,
                            bool CopyInitializing, bool AllowExplicit,
-                           bool OnlyListConstructors) {
+                           bool OnlyListConstructors, bool IsListInit) {
   CandidateSet.clear();
 
   for (ArrayRef<NamedDecl *>::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<InitListExpr>(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 ?
index b481865d844778efb1cf9cc36c8b8c1c4dc44b7e..0cd5aa7401a35cf23b434109e1025240fd852a0d 100644 (file)
@@ -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};
 }