CWG 2267 - list-initialization of reference temporary
authorJason Merrill <jason@redhat.com>
Thu, 10 May 2018 18:57:50 +0000 (14:57 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 10 May 2018 18:57:50 +0000 (14:57 -0400)
* call.c (reference_binding): List-initializing a reference
temporary is copy-list-initialization.

From-SVN: r260126

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/g++.dg/cpp0x/initlist-ref-2267.C [new file with mode: 0644]

index 76a7087..e6223ae 100644 (file)
@@ -1,5 +1,9 @@
 2018-05-09  Jason Merrill  <jason@redhat.com>
 
+       CWG 2267 - list-initialization of reference temporary
+       * call.c (reference_binding): List-initializing a reference
+       temporary is copy-list-initialization.
+
        * parser.c (cp_parser_class_head): Use num_template_headers_for_class.
 
        * pt.c (instantiate_decl): Make sure we aren't trying to do a nested
index d3ee152..30fe682 100644 (file)
@@ -1560,12 +1560,10 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
              goto skip;
            }
        }
-      /* Otherwise, if T is a reference type, a prvalue temporary of the
-        type referenced by T is copy-list-initialized or
-        direct-list-initialized, depending on the kind of initialization
-        for the reference, and the reference is bound to that temporary. */
-      conv = implicit_conversion (to, from, expr, c_cast_p,
-                                 flags|LOOKUP_NO_TEMP_BIND, complain);
+      /* Otherwise, if T is a reference type, a prvalue temporary of the type
+        referenced by T is copy-list-initialized, and the reference is bound
+        to that temporary. */
+      CONSTRUCTOR_IS_DIRECT_INIT (expr) = false;
     skip:;
     }
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-ref-2267.C b/gcc/testsuite/g++.dg/cpp0x/initlist-ref-2267.C
new file mode 100644 (file)
index 0000000..dfd735a
--- /dev/null
@@ -0,0 +1,14 @@
+// CWG 2267
+// { dg-do compile { target c++11 } }
+
+struct A {} a; 
+struct B { explicit B(const A&); }; 
+B b1(a); // #1, ok 
+const B &b2{a}; // { dg-error "" }
+const B &b3(a); // { dg-error "" }
+
+struct D { D(); }; 
+struct C { explicit operator D(); } c; 
+D d1(c); // ok 
+const D &d2{c}; // { dg-error "" }
+const D &d3(c); // { dg-error "" }