Comments
Patch
@@ -1429,7 +1429,9 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
|| (((CP_TYPE_CONST_NON_VOLATILE_P (to)
&& !(flags & LOOKUP_NO_TEMP_BIND))
|| TYPE_REF_IS_RVALUE (rto))
- && (CLASS_TYPE_P (from) || (expr && lvalue_p (expr))))))
+ && (CLASS_TYPE_P (from)
+ || TREE_CODE (from) == ARRAY_TYPE
+ || (expr && lvalue_p (expr))))))
{
/* [dcl.init.ref]
new file mode 100644
@@ -0,0 +1,5 @@
+// { dg-options -std=c++0x }
+
+typedef int IRT[2];
+
+const IRT& ir = IRT{1,2};
In discussion of core issue 1232 we realized that we already do allow array temporaries in some cases (primarily as subobjects of class temporaries), so we ought to handle them consistently. The first patch fixes direct binding to array prvalues, which has been specified for a while. The second patch specifies the semantics of a conversion from initializer-list to array for binding the temporary to a reference. Tested x86_64-pc-linux-gnu, applying to trunk and 4.6. commit 43d838d444e21ec34ed9d72e2e64315129d02291 Author: Jason Merrill <jason@redhat.com> Date: Thu Mar 24 14:48:44 2011 +0100 * call.c (reference_binding): Allow direct binding to an array rvalue. commit e84d467f48170f6b8fda35b38569cdab4104427f Author: Jason Merrill <jason@redhat.com> Date: Thu Mar 24 15:36:12 2011 +0100 Core 1232 * call.c (build_array_conv): New. (implicit_conversion): Use it. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 9a9ac76..a1cfa96 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -801,6 +801,53 @@ build_aggr_conv (tree type, tree ctor, int flags) return c; } +/* Represent a conversion from CTOR, a braced-init-list, to TYPE, an + array type, if such a conversion is possible. */ + +static conversion * +build_array_conv (tree type, tree ctor, int flags) +{ + conversion *c; + unsigned HOST_WIDE_INT len = CONSTRUCTOR_NELTS (ctor); + tree elttype = TREE_TYPE (type); + unsigned i; + tree val; + bool bad = false; + bool user = false; + enum conversion_rank rank = cr_exact; + + if (TYPE_DOMAIN (type)) + { + unsigned HOST_WIDE_INT alen = tree_low_cst (array_type_nelts_top (type), 1); + if (alen < len) + return NULL; + } + + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val) + { + conversion *sub + = implicit_conversion (elttype, TREE_TYPE (val), val, + false, flags); + if (sub == NULL) + return NULL; + + if (sub->rank > rank) + rank = sub->rank; + if (sub->user_conv_p) + user = true; + if (sub->bad_p) + bad = true; + } + + c = alloc_conversion (ck_aggr); + c->type = type; + c->rank = rank; + c->user_conv_p = user; + c->bad_p = bad; + c->u.next = NULL; + return c; +} + /* Build a representation of the identity conversion from EXPR to itself. The TYPE should match the type of EXPR, if EXPR is non-NULL. */ @@ -1623,6 +1670,8 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, return conv; } } + else if (TREE_CODE (to) == ARRAY_TYPE) + return build_array_conv (to, expr, flags); } if (expr != NULL_TREE diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-array2.C b/gcc/testsuite/g++.dg/cpp0x/initlist-array2.C new file mode 100644 index 0000000..19eec33 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-array2.C @@ -0,0 +1,12 @@ +// { dg-options -std=c++0x } + +typedef int IA[2]; +typedef double DA[2]; + +void f(const IA&) { } +void f(const DA&); + +int main() +{ + f({1,2}); +}