diff options
author | Jason Merrill <jason@redhat.com> | 2010-11-03 22:15:00 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2010-11-03 22:15:00 -0400 |
commit | bc99421e351e6f3ed3c8b5681179cd76d5f2862f (patch) | |
tree | 6afa7158366f31867efd482393eb42b9f7fddf4e /gcc/cp | |
parent | 5eb3445002aeacd5afccb96b869c37a55d943345 (diff) | |
download | gcc-bc99421e351e6f3ed3c8b5681179cd76d5f2862f.zip gcc-bc99421e351e6f3ed3c8b5681179cd76d5f2862f.tar.gz gcc-bc99421e351e6f3ed3c8b5681179cd76d5f2862f.tar.bz2 |
re PR c++/46289 (ICE in build_constexpr_constructor_member_initializers, at cp/semantics.c:5513)
PR c++/46289
* call.c (can_convert_array): New fn.
(build_aggr_conv): Use it.
From-SVN: r166296
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/call.c | 54 |
2 files changed, 46 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7c4b082..e384cf7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,6 +1,10 @@ 2010-11-03 Jason Merrill <jason@redhat.com> PR c++/46289 + * call.c (can_convert_array): New fn. + (build_aggr_conv): Use it. + + PR c++/46289 * semantics.c (build_constexpr_constructor_member_initializers): Avoid ICE on error. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index a1c8682..4507f3d 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -639,6 +639,29 @@ build_list_conv (tree type, tree ctor, int flags) return t; } +/* Subroutine of build_aggr_conv: check whether CTOR, a braced-init-list, + is a valid aggregate initializer for array type ATYPE. */ + +static bool +can_convert_array (tree atype, tree ctor, int flags) +{ + unsigned i; + tree elttype = TREE_TYPE (atype); + for (i = 0; i < CONSTRUCTOR_NELTS (ctor); ++i) + { + tree val = CONSTRUCTOR_ELT (ctor, i)->value; + bool ok; + if (TREE_CODE (elttype) == ARRAY_TYPE + && TREE_CODE (val) == CONSTRUCTOR) + ok = can_convert_array (elttype, val, flags); + else + ok = can_convert_arg (elttype, TREE_TYPE (val), val, flags); + if (!ok) + return false; + } + return true; +} + /* Represent a conversion from CTOR, a braced-init-list, to TYPE, an aggregate class, if such a conversion is possible. */ @@ -652,24 +675,31 @@ build_aggr_conv (tree type, tree ctor, int flags) for (; field; field = next_initializable_field (DECL_CHAIN (field))) { + tree ftype = TREE_TYPE (field); + tree val; + bool ok; + if (i < CONSTRUCTOR_NELTS (ctor)) - { - constructor_elt *ce = CONSTRUCTOR_ELT (ctor, i); - if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (ce->value), - ce->value, flags)) - return NULL; - ++i; - if (TREE_CODE (type) == UNION_TYPE) - break; - } + val = CONSTRUCTOR_ELT (ctor, i)->value; else { if (empty_ctor == NULL_TREE) empty_ctor = build_constructor (init_list_type_node, NULL); - if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (empty_ctor), - empty_ctor, flags)) - return NULL; + val = empty_ctor; } + ++i; + + if (TREE_CODE (ftype) == ARRAY_TYPE + && TREE_CODE (val) == CONSTRUCTOR) + ok = can_convert_array (ftype, val, flags); + else + ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags); + + if (!ok) + return NULL; + + if (TREE_CODE (type) == UNION_TYPE) + break; } if (i < CONSTRUCTOR_NELTS (ctor)) |