Core issue 934
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Jul 2009 03:32:30 +0000 (03:32 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Jul 2009 03:32:30 +0000 (03:32 +0000)
* call.c (reference_binding): Implement binding to { }.
(initialize_reference): Binding temporary to non-const && is fine.
* decl.c (grok_reference_init): Remove error for CONSTRUCTOR.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149873 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/initlist22.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.brendan/init4.C

index 520ae54..86f8b50 100644 (file)
@@ -1,3 +1,10 @@
+2009-07-21  Jason Merrill  <jason@redhat.com>
+
+       Core issue 934
+       * call.c (reference_binding): Implement binding to { }.
+       (initialize_reference): Binding temporary to non-const && is fine.
+       * decl.c (grok_reference_init): Remove error for CONSTRUCTOR.
+
 2009-07-17  Richard Guenther  <rguenther@suse.de>
 
        PR c/40401
index f4b5b02..845fa56 100644 (file)
@@ -1221,7 +1221,21 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
       lvalue_p = clk_ordinary;
       from = TREE_TYPE (from);
     }
-  else if (expr)
+
+  if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
+    {
+      maybe_warn_cpp0x ("extended initializer lists");
+      conv = implicit_conversion (to, from, expr, c_cast_p,
+                                 flags);
+      if (!CLASS_TYPE_P (to)
+         && CONSTRUCTOR_NELTS (expr) == 1)
+       {
+         expr = CONSTRUCTOR_ELT (expr, 0)->value;
+         from = TREE_TYPE (expr);
+       }
+    }
+
+  if (lvalue_p == clk_none && expr)
     lvalue_p = real_lvalue_p (expr);
 
   tfrom = from;
@@ -1363,8 +1377,9 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
   if (!(flags & LOOKUP_COPY_PARM))
     flags |= LOOKUP_ONLYCONVERTING;
 
-  conv = implicit_conversion (to, from, expr, c_cast_p,
-                             flags);
+  if (!conv)
+    conv = implicit_conversion (to, from, expr, c_cast_p,
+                               flags);
   if (!conv)
     return NULL;
 
@@ -7541,6 +7556,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
   if (!conv || conv->bad_p)
     {
       if (!(TYPE_QUALS (TREE_TYPE (type)) & TYPE_QUAL_CONST)
+         && !TYPE_REF_IS_RVALUE (type)
          && !real_lvalue_p (expr))
        error ("invalid initialization of non-const reference of "
               "type %qT from a temporary of type %qT",
index 251d0a3..6fa9428 100644 (file)
@@ -4370,13 +4370,6 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
       return NULL_TREE;
     }
 
-  if (TREE_CODE (init) == CONSTRUCTOR)
-    {
-      error ("ISO C++ forbids use of initializer list to "
-            "initialize reference %qD", decl);
-      return NULL_TREE;
-    }
-
   if (TREE_CODE (init) == TREE_LIST)
     init = build_x_compound_expr_from_list (init, "initializer");
 
index ed0b13a..d007c46 100644 (file)
@@ -1,3 +1,8 @@
+2009-07-21  Jason Merrill  <jason@redhat.com>
+
+       Core issue 934
+       * g++.dg/cpp0x/initlist22.C: New.
+
 2009-07-21  Uros Bizjak  <ubizjak@gmail.com>
 
        * gcc.target/i386/vectorize8.c: New test.
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist22.C b/gcc/testsuite/g++.dg/cpp0x/initlist22.C
new file mode 100644 (file)
index 0000000..bf1c554
--- /dev/null
@@ -0,0 +1,24 @@
+// Core issue 934
+// { dg-options "-std=c++0x" }
+
+int i;
+
+int& r1{ i };                  // OK, direct binding
+int&& r2{ i };                 // OK, direct binding
+
+int& r3{ };                    // { dg-error "" } reference to temporary
+int&& r4{ };                   // OK, reference to temporary
+
+struct A { int i; } a;
+
+A& r5 { i };                   // { dg-error "" } reference to temporary
+A&& r6 { i };                  // OK, aggregate initialization of temporary
+A& r7 { a };                   // { dg-error "" } invalid aggregate initializer for A
+A&& r8 { a };                  // { dg-error "" } invalid aggregate initializer for A
+
+struct B { B(int); int i; } b(0);
+
+B& r9 { i };                   // { dg-error "" } reference to temporary
+B&& r10 { i };                 // OK, make temporary with B(int) constructor
+B& r11 { b };                  // { dg-error "" } reference to temporary
+B&& r12 { b };                 // OK, make temporary with copy constructor
index 71e7cd6..aa2bfb6 100644 (file)
@@ -2,4 +2,4 @@
 // GROUPS passed initialization
 struct CharList { int i; };
 
-const CharList& terminals = { 1 };// { dg-error "" } .*
+const CharList& terminals = { 1 }; // { dg-error "initializer lists" } c++0x