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:
parent
cd88bb8c77
commit
458f8a16a1
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
25
gcc/testsuite/g++.dg/ext/desig2.C
Normal file
25
gcc/testsuite/g++.dg/ext/desig2.C
Normal 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" }
|
Loading…
Reference in New Issue
Block a user