Commit 76239779 by Mark Mitchell Committed by Mark Mitchell

re PR c++/29728 (ICE on invalid initializer in template function)

	PR c++/29728
	* decl.c (check_array_designated_initializer): New function.
	(maybe_deduce_size_from_array_init): Use it.
	(reshape_init_array): Likewise.
	PR c++/29728
	* g++.dg/template/crash62.C: New test.

From-SVN: r119558
parent 8424e0d8
2006-12-05 Mark Mitchell <mark@codesourcery.com>
PR c++/29728
* decl.c (check_array_designated_initializer): New function.
(maybe_deduce_size_from_array_init): Use it.
(reshape_init_array): Likewise.
2006-12-05 Aldy Hernandez <aldyh@redhat.com> 2006-12-05 Aldy Hernandez <aldyh@redhat.com>
Merge from gimple-tuples-branch. Merge from gimple-tuples-branch.
......
...@@ -4092,6 +4092,30 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup) ...@@ -4092,6 +4092,30 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
return NULL_TREE; return NULL_TREE;
} }
/* Designated initializers in arrays are not supported in GNU C++.
The parser cannot detect this error since it does not know whether
a given brace-enclosed initializer is for a class type or for an
array. This function checks that CE does not use a designated
initializer. If it does, an error is issued. Returns true if CE
is valid, i.e., does not have a designated initializer. */
static bool
check_array_designated_initializer (const constructor_elt *ce)
{
/* Designated initializers for array elements arenot supported. */
if (ce->index)
{
/* The parser only allows identifiers as designated
intializers. */
gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE);
error ("name %qD used in a GNU-style designated "
"initializer for an array", ce->index);
return false;
}
return true;
}
/* When parsing `int a[] = {1, 2};' we don't know the size of the /* When parsing `int a[] = {1, 2};' we don't know the size of the
array until we finish parsing the initializer. If that's the array until we finish parsing the initializer. If that's the
situation we're in, update DECL accordingly. */ situation we're in, update DECL accordingly. */
...@@ -4109,32 +4133,52 @@ maybe_deduce_size_from_array_init (tree decl, tree init) ...@@ -4109,32 +4133,52 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
But let's leave it here to ease the eventual merge. */ But let's leave it here to ease the eventual merge. */
int do_default = !DECL_EXTERNAL (decl); int do_default = !DECL_EXTERNAL (decl);
tree initializer = init ? init : DECL_INITIAL (decl); tree initializer = init ? init : DECL_INITIAL (decl);
int failure = cp_complete_array_type (&TREE_TYPE (decl), initializer, int failure = 0;
do_default);
if (failure == 1) /* Check that there are no designated initializers in INIT, as
those are not supported in GNU C++, and as the middle-end
will crash if presented with a non-numeric designated
initializer. */
if (initializer && TREE_CODE (initializer) == CONSTRUCTOR)
{ {
error ("initializer fails to determine size of %qD", decl); VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (initializer);
TREE_TYPE (decl) = error_mark_node; constructor_elt *ce;
HOST_WIDE_INT i;
for (i = 0;
VEC_iterate (constructor_elt, v, i, ce);
++i)
if (!check_array_designated_initializer (ce))
failure = 1;
} }
else if (failure == 2)
if (!failure)
{ {
if (do_default) failure = cp_complete_array_type (&TREE_TYPE (decl), initializer,
do_default);
if (failure == 1)
{ {
error ("array size missing in %qD", decl); error ("initializer fails to determine size of %qD", decl);
TREE_TYPE (decl) = error_mark_node;
}
else if (failure == 2)
{
if (do_default)
{
error ("array size missing in %qD", decl);
TREE_TYPE (decl) = error_mark_node;
}
/* If a `static' var's size isn't known, make it extern as
well as static, so it does not get allocated. If it's not
`static', then don't mark it extern; finish_incomplete_decl
will give it a default size and it will get allocated. */
else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
DECL_EXTERNAL (decl) = 1;
}
else if (failure == 3)
{
error ("zero-size array %qD", decl);
TREE_TYPE (decl) = error_mark_node; TREE_TYPE (decl) = error_mark_node;
} }
/* If a `static' var's size isn't known, make it extern as
well as static, so it does not get allocated. If it's not
`static', then don't mark it extern; finish_incomplete_decl
will give it a default size and it will get allocated. */
else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
DECL_EXTERNAL (decl) = 1;
}
else if (failure == 3)
{
error ("zero-size array %qD", decl);
TREE_TYPE (decl) = error_mark_node;
} }
cp_apply_type_quals_to_decl (cp_type_quals (TREE_TYPE (decl)), decl); cp_apply_type_quals_to_decl (cp_type_quals (TREE_TYPE (decl)), decl);
...@@ -4346,18 +4390,7 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d) ...@@ -4346,18 +4390,7 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d)
{ {
tree elt_init; tree elt_init;
if (d->cur->index) check_array_designated_initializer (d->cur);
{
/* Handle array designated initializers (GNU extension). */
if (TREE_CODE (d->cur->index) == IDENTIFIER_NODE)
{
error ("name %qD used in a GNU-style designated "
"initializer for an array", d->cur->index);
}
else
gcc_unreachable ();
}
elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false); elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false);
if (elt_init == error_mark_node) if (elt_init == error_mark_node)
return error_mark_node; return error_mark_node;
......
2006-12-05 Mark Mitchell <mark@codesourcery.com>
PR c++/29728
* g++.dg/template/crash62.C: New test.
2006-12-05 Paul Thomas <pault@gcc.gnu.org> 2006-12-05 Paul Thomas <pault@gcc.gnu.org>
PR fortran/30003 PR fortran/30003
// PR c++/29728
template<int> void foo()
{
int a[] = { X: 0 }; // { dg-error "designated initializer" }
}
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