parser.c (cp_parser_initializer_list): Handle C99 .id= and [N]= designated initializer syntax.

* parser.c (cp_parser_initializer_list): Handle C99 .id= and [N]=
	designated initializer syntax.
	* decl.c (check_array_designated_initializer): Add index parm.
	(maybe_deduce_size_from_array_init): Pass it.
	(reshape_init_array_1): Likewise.

From-SVN: r176530
This commit is contained in:
Jason Merrill 2011-07-20 14:18:03 -04:00 committed by Jason Merrill
parent cd88bb8c77
commit 458f8a16a1
5 changed files with 83 additions and 11 deletions

View File

@ -1,5 +1,11 @@
2011-07-20 Jason Merrill <jason@redhat.com>
* parser.c (cp_parser_initializer_list): Handle C99 .id= and [N]=
designated initializer syntax.
* decl.c (check_array_designated_initializer): Add index parm.
(maybe_deduce_size_from_array_init): Pass it.
(reshape_init_array_1): Likewise.
PR c++/6709 (DR 743)
PR c++/42603 (DR 950)
* parser.c (token_is_decltype, cp_lexer_next_token_is_decltype): New.

View File

@ -4648,7 +4648,8 @@ build_init_list_var_init (tree decl, tree type, tree init, tree *array_init,
is valid, i.e., does not have a designated initializer. */
static bool
check_array_designated_initializer (const constructor_elt *ce)
check_array_designated_initializer (const constructor_elt *ce,
unsigned HOST_WIDE_INT index)
{
/* Designated initializers for array elements are not supported. */
if (ce->index)
@ -4659,8 +4660,13 @@ check_array_designated_initializer (const constructor_elt *ce)
error ("name used in a GNU-style designated "
"initializer for an array");
else if (TREE_CODE (ce->index) == INTEGER_CST)
/* An index added by reshape_init. */
return true;
{
/* A C99 designator is OK if it matches the current index. */
if (TREE_INT_CST_LOW (ce->index) == index)
return true;
else
sorry ("non-trivial designated initializers not supported");
}
else
{
gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE);
@ -4702,7 +4708,7 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
constructor_elt *ce;
HOST_WIDE_INT i;
FOR_EACH_VEC_ELT (constructor_elt, v, i, ce)
if (!check_array_designated_initializer (ce))
if (!check_array_designated_initializer (ce, i))
failure = 1;
}
@ -4961,7 +4967,7 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
{
tree elt_init;
check_array_designated_initializer (d->cur);
check_array_designated_initializer (d->cur, index);
elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false,
complain);
if (elt_init == error_mark_node)

View File

@ -16693,8 +16693,13 @@ cp_parser_braced_list (cp_parser* parser, bool* non_constant_p)
GNU Extension:
initializer-list:
identifier : initializer-clause
initializer-list, identifier : initializer-clause
designation initializer-clause ...[opt]
initializer-list , designation initializer-clause ...[opt]
designation:
. identifier =
identifier :
[ constant-expression ] =
Returns a VEC of constructor_elt. The VALUE of each elt is an expression
for the initializer. If the INDEX of the elt is non-NULL, it is the
@ -16713,7 +16718,7 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
while (true)
{
cp_token *token;
tree identifier;
tree designator;
tree initializer;
bool clause_non_constant_p;
@ -16728,12 +16733,38 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
pedwarn (input_location, OPT_pedantic,
"ISO C++ does not allow designated initializers");
/* Consume the identifier. */
identifier = cp_lexer_consume_token (parser->lexer)->u.value;
designator = cp_lexer_consume_token (parser->lexer)->u.value;
/* Consume the `:'. */
cp_lexer_consume_token (parser->lexer);
}
/* Also handle the C99 syntax, '. id ='. */
else if (cp_parser_allow_gnu_extensions_p (parser)
&& cp_lexer_next_token_is (parser->lexer, CPP_DOT)
&& cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME
&& cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_EQ)
{
/* Warn the user that they are using an extension. */
pedwarn (input_location, OPT_pedantic,
"ISO C++ does not allow C99 designated initializers");
/* Consume the `.'. */
cp_lexer_consume_token (parser->lexer);
/* Consume the identifier. */
designator = cp_lexer_consume_token (parser->lexer)->u.value;
/* Consume the `='. */
cp_lexer_consume_token (parser->lexer);
}
/* Also handle C99 array designators, '[ const ] ='. */
else if (cp_parser_allow_gnu_extensions_p (parser)
&& !c_dialect_objc ()
&& cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
{
cp_lexer_consume_token (parser->lexer);
designator = cp_parser_constant_expression (parser, false, NULL);
cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
cp_parser_require (parser, CPP_EQ, RT_EQ);
}
else
identifier = NULL_TREE;
designator = NULL_TREE;
/* Parse the initializer. */
initializer = cp_parser_initializer_clause (parser,
@ -16754,7 +16785,7 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
}
/* Add it to the vector. */
CONSTRUCTOR_APPEND_ELT(v, identifier, initializer);
CONSTRUCTOR_APPEND_ELT (v, designator, initializer);
/* If the next token is not a comma, we have reached the end of
the list. */

View File

@ -1,3 +1,7 @@
2011-07-20 Jason Merrill <jason@redhat.com>
* g++.dg/ext/desig2.C: New.
2011-07-20 Michael Meissner <meissner@linux.vnet.ibm.com>
* gcc.target/powerpc/ppc-fma-1.c: Adjust to allow non-VSX fmas to

View File

@ -0,0 +1,25 @@
// Test for C99-style designated array initializer
union U
{
long l;
const char *p;
};
__extension__ U u = { .p = "" };
__extension__ int i[4] = { [0] = 1, [1] = 2 };
// Currently, except for unions, the C++ front end only supports
// designators that designate the element that would have been initialized
// anyway. While that's true, make sure that we get a sorry rather than
// bad code.
struct A
{
int i;
int j;
};
__extension__ A a = { .j = 1 }; // { dg-message "non-trivial" }
__extension__ int j[2] = { [1] = 1 }; // { dg-message "non-trivial" }