aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2010-11-03 22:15:00 -0400
committerJason Merrill <jason@gcc.gnu.org>2010-11-03 22:15:00 -0400
commitbc99421e351e6f3ed3c8b5681179cd76d5f2862f (patch)
tree6afa7158366f31867efd482393eb42b9f7fddf4e /gcc/cp
parent5eb3445002aeacd5afccb96b869c37a55d943345 (diff)
downloadgcc-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/ChangeLog4
-rw-r--r--gcc/cp/call.c54
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))