File gcc48-bnc1011348-dr1288.patch of Package cross-i386-gcc48-icecream-backend.8471

2014-01-27  Jason Merrill  <jason@redhat.com>

	Core DR 1288
	* call.c (reference_binding): Only elide braces if the single
	element is reference-related.

Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c	(revision 235439)
+++ gcc/cp/call.c	(working copy)
@@ -1463,16 +1463,29 @@ reference_binding (tree rto, tree rfrom,
   if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
     {
       maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
-      conv = implicit_conversion (to, from, expr, c_cast_p,
-				  flags|LOOKUP_NO_TEMP_BIND, complain);
-      if (!CLASS_TYPE_P (to)
-	  && CONSTRUCTOR_NELTS (expr) == 1)
+      /* DR 1288: Otherwise, if the initializer list has a single element
+	 of type E and ... [T's] referenced type is reference-related to E,
+	 the object or reference is initialized from that element... */
+      if (CONSTRUCTOR_NELTS (expr) == 1)
 	{
-	  expr = CONSTRUCTOR_ELT (expr, 0)->value;
-	  if (error_operand_p (expr))
+	  tree elt = CONSTRUCTOR_ELT (expr, 0)->value;
+	  if (error_operand_p (elt))
 	    return NULL;
-	  from = TREE_TYPE (expr);
+	  tree etype = TREE_TYPE (elt);
+	  if (reference_related_p (to, etype))
+	    {
+	      expr = elt;
+	      from = etype;
+	      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);
+    skip:;
     }
 
   if (TREE_CODE (from) == REFERENCE_TYPE)

Index: gcc/testsuite/g++.dg/cpp0x/initlist22.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/initlist22.C	(revision 235439)
+++ gcc/testsuite/g++.dg/cpp0x/initlist22.C	(working copy)
@@ -1,4 +1,4 @@
-// Core issue 934
+// Core issue 934/1288
 // { dg-options "-std=c++0x" }
 
 int i;
@@ -13,12 +13,12 @@ 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
+A& r7 { a };			// OK, direct-initialization
+A&& r8 { a };			// { dg-error "lvalue" } binding && to lvalue
 
 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
+B& r11 { b };			// OK, direct-initialization
+B&& r12 { b };			// { dg-error "lvalue" } binding && to lvalue
openSUSE Build Service is sponsored by