Commit bc99421e by Jason Merrill Committed by Jason Merrill

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
parent 5eb34450
2010-11-03 Jason Merrill <jason@redhat.com> 2010-11-03 Jason Merrill <jason@redhat.com>
PR c++/46289 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): * semantics.c (build_constexpr_constructor_member_initializers):
Avoid ICE on error. Avoid ICE on error.
......
...@@ -639,6 +639,29 @@ build_list_conv (tree type, tree ctor, int flags) ...@@ -639,6 +639,29 @@ build_list_conv (tree type, tree ctor, int flags)
return t; 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 /* Represent a conversion from CTOR, a braced-init-list, to TYPE, an
aggregate class, if such a conversion is possible. */ aggregate class, if such a conversion is possible. */
...@@ -652,24 +675,31 @@ build_aggr_conv (tree type, tree ctor, int flags) ...@@ -652,24 +675,31 @@ build_aggr_conv (tree type, tree ctor, int flags)
for (; field; field = next_initializable_field (DECL_CHAIN (field))) for (; field; field = next_initializable_field (DECL_CHAIN (field)))
{ {
tree ftype = TREE_TYPE (field);
tree val;
bool ok;
if (i < CONSTRUCTOR_NELTS (ctor)) if (i < CONSTRUCTOR_NELTS (ctor))
{ val = CONSTRUCTOR_ELT (ctor, i)->value;
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;
}
else else
{ {
if (empty_ctor == NULL_TREE) if (empty_ctor == NULL_TREE)
empty_ctor = build_constructor (init_list_type_node, NULL); empty_ctor = build_constructor (init_list_type_node, NULL);
if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (empty_ctor), val = empty_ctor;
empty_ctor, flags))
return NULL;
} }
++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)) if (i < CONSTRUCTOR_NELTS (ctor))
......
2010-11-03 Jason Merrill <jason@redhat.com>
PR c++/46289
* g++.dg/cpp0x/initlist45.C: New.
2010-11-03 Nicola Pero <nicola.pero@meta-innovation.com> 2010-11-03 Nicola Pero <nicola.pero@meta-innovation.com>
* objc.dg/property/dynamic-2.m: Updated for the fact that @dynamic * objc.dg/property/dynamic-2.m: Updated for the fact that @dynamic
......
// PR c++/46289
// { dg-options -std=c++0x }
struct A
{
int i[2];
};
struct B
{
A a;
B(): a({{1,2}}) { }
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment