diff options
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
| -rw-r--r-- | gcc/cp/call.c | 49 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 2 | ||||
| -rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist-array2.C | 12 |
4 files changed, 67 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 15d8a97..22bd6b8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2011-03-28 Jason Merrill <jason@redhat.com> + 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 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/ChangeLog b/gcc/testsuite/ChangeLog index 2424c15..4445d51 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2011-03-28 Jason Merrill <jason@redhat.com> + * 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 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}); +} |
