File gcc48-bnc1011348-dr1288.patch of Package cross-ppc64-gcc48-icecream-backend.7695
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