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)
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);
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;
}
{
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)
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
while (true)
{
cp_token *token;
- tree identifier;
+ tree designator;
tree initializer;
bool clause_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,
}
/* 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. */
--- /dev/null
+// 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" }