From dd35aac798661f0ad778384bc8d0751584a137c0 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 28 Mar 2011 12:14:22 -0400 Subject: [PATCH] Core 1232 Core 1232 * call.c (build_array_conv): New. (implicit_conversion): Use it. From-SVN: r171614 --- gcc/cp/ChangeLog | 4 ++ gcc/cp/call.c | 49 ++++++++++++++++++++ gcc/testsuite/ChangeLog | 2 + gcc/testsuite/g++.dg/cpp0x/initlist-array2.C | 12 +++++ 4 files changed, 67 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/initlist-array2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 15d8a979387..22bd6b83d06 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2011-03-28 Jason Merrill + Core 1232 + * call.c (build_array_conv): New. + (implicit_conversion): Use it. + * call.c (reference_binding): Allow direct binding to an array rvalue. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 9a9ac760d3f..a1cfa96e795 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/ChangeLog b/gcc/testsuite/ChangeLog index 2424c15f2fd..4445d51694e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2011-03-28 Jason Merrill + * g++.dg/cpp0x/initlist-array2.C: New. + * g++.dg/cpp0x/initlist-array1.C: New. * g++.dg/cpp0x/constexpr-compound.C: New. 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 00000000000..19eec33acf7 --- /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}); +}