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
This commit is contained in:
parent
8424e0d8b1
commit
762397797c
4 changed files with 82 additions and 31 deletions
|
@ -1,3 +1,10 @@
|
|||
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>
|
||||
|
||||
Merge from gimple-tuples-branch.
|
||||
|
|
|
@ -4092,6 +4092,30 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
|
|||
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
|
||||
array until we finish parsing the initializer. If that's the
|
||||
situation we're in, update DECL accordingly. */
|
||||
|
@ -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. */
|
||||
int do_default = !DECL_EXTERNAL (decl);
|
||||
tree initializer = init ? init : DECL_INITIAL (decl);
|
||||
int failure = cp_complete_array_type (&TREE_TYPE (decl), initializer,
|
||||
do_default);
|
||||
int failure = 0;
|
||||
|
||||
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);
|
||||
TREE_TYPE (decl) = error_mark_node;
|
||||
VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (initializer);
|
||||
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;
|
||||
}
|
||||
/* 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);
|
||||
|
@ -4346,18 +4390,7 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d)
|
|||
{
|
||||
tree elt_init;
|
||||
|
||||
if (d->cur->index)
|
||||
{
|
||||
/* 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 ();
|
||||
}
|
||||
|
||||
check_array_designated_initializer (d->cur);
|
||||
elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false);
|
||||
if (elt_init == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
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>
|
||||
|
||||
PR fortran/30003
|
||||
|
|
6
gcc/testsuite/g++.dg/template/crash62.C
Normal file
6
gcc/testsuite/g++.dg/template/crash62.C
Normal file
|
@ -0,0 +1,6 @@
|
|||
// PR c++/29728
|
||||
|
||||
template<int> void foo()
|
||||
{
|
||||
int a[] = { X: 0 }; // { dg-error "designated initializer" }
|
||||
}
|
Loading…
Add table
Reference in a new issue