+2016-02-12 Bernd Schmidt <bschmidt@redhat.com>
+
+ PR c/69522
+ * c-parser.c (c_parser_braced_init): New arg outer_obstack. All
+ callers changed. If nested_p is true, use it to call
+ finish_implicit_inits.
+ * c-tree.h (finish_implicit_inits): Declare.
+ * c-typeck.c (finish_implicit_inits): New function. Move code
+ from ...
+ (push_init_level): ... here.
+ (set_designator, process_init_element): Call finish_implicit_inits.
+
2016-02-11 Jakub Jelinek <jakub@redhat.com>
PR c/69768
static tree c_parser_attributes (c_parser *);
static struct c_type_name *c_parser_type_name (c_parser *);
static struct c_expr c_parser_initializer (c_parser *);
-static struct c_expr c_parser_braced_init (c_parser *, tree, bool);
+static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
+ struct obstack *);
static void c_parser_initelt (c_parser *, struct obstack *);
static void c_parser_initval (c_parser *, struct c_expr *,
struct obstack *);
c_parser_initializer (c_parser *parser)
{
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
- return c_parser_braced_init (parser, NULL_TREE, false);
+ return c_parser_braced_init (parser, NULL_TREE, false, NULL);
else
{
struct c_expr ret;
top-level initializer in a declaration. */
static struct c_expr
-c_parser_braced_init (c_parser *parser, tree type, bool nested_p)
+c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
+ struct obstack *outer_obstack)
{
struct c_expr ret;
struct obstack braced_init_obstack;
gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
c_parser_consume_token (parser);
if (nested_p)
- push_init_level (brace_loc, 0, &braced_init_obstack);
+ {
+ finish_implicit_inits (brace_loc, outer_obstack);
+ push_init_level (brace_loc, 0, &braced_init_obstack);
+ }
else
really_start_incremental_init (type);
if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
location_t loc = c_parser_peek_token (parser)->location;
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
- init = c_parser_braced_init (parser, NULL_TREE, true);
+ init = c_parser_braced_init (parser, NULL_TREE, true,
+ braced_init_obstack);
else
{
init = c_parser_expr_no_commas (parser, after);
error_at (type_loc, "compound literal has variable size");
type = error_mark_node;
}
- init = c_parser_braced_init (parser, type, false);
+ init = c_parser_braced_init (parser, type, false, NULL);
finish_init ();
maybe_warn_string_init (type_loc, type, init);
extern void start_init (tree, tree, int);
extern void finish_init (void);
extern void really_start_incremental_init (tree);
+extern void finish_implicit_inits (location_t, struct obstack *);
extern void push_init_level (location_t, int, struct obstack *);
extern struct c_expr pop_init_level (location_t, int, struct obstack *);
extern void set_init_index (location_t, tree, tree, struct obstack *);
}
}
\f
+/* Called when we see an open brace for a nested initializer. Finish
+ off any pending levels with implicit braces. */
+void
+finish_implicit_inits (location_t loc, struct obstack *braced_init_obstack)
+{
+ while (constructor_stack->implicit)
+ {
+ if (RECORD_OR_UNION_TYPE_P (constructor_type)
+ && constructor_fields == 0)
+ process_init_element (input_location,
+ pop_init_level (loc, 1, braced_init_obstack),
+ true, braced_init_obstack);
+ else if (TREE_CODE (constructor_type) == ARRAY_TYPE
+ && constructor_max_index
+ && tree_int_cst_lt (constructor_max_index,
+ constructor_index))
+ process_init_element (input_location,
+ pop_init_level (loc, 1, braced_init_obstack),
+ true, braced_init_obstack);
+ else
+ break;
+ }
+}
+
/* Push down into a subobject, for initialization.
If this is for an explicit set of braces, IMPLICIT is 0.
If it is because the next element belongs at a lower level,
struct constructor_stack *p;
tree value = NULL_TREE;
- /* If we've exhausted any levels that didn't have braces,
- pop them now. If implicit == 1, this will have been done in
- process_init_element; do not repeat it here because in the case
- of excess initializers for an empty aggregate this leads to an
- infinite cycle of popping a level and immediately recreating
- it. */
- if (implicit != 1)
- {
- while (constructor_stack->implicit)
- {
- if (RECORD_OR_UNION_TYPE_P (constructor_type)
- && constructor_fields == 0)
- process_init_element (input_location,
- pop_init_level (loc, 1, braced_init_obstack),
- true, braced_init_obstack);
- else if (TREE_CODE (constructor_type) == ARRAY_TYPE
- && constructor_max_index
- && tree_int_cst_lt (constructor_max_index,
- constructor_index))
- process_init_element (input_location,
- pop_init_level (loc, 1, braced_init_obstack),
- true, braced_init_obstack);
- else
- break;
- }
- }
-
/* Unless this is an explicit brace, we need to preserve previous
content if any. */
if (implicit)
}
constructor_designated = 1;
+ finish_implicit_inits (loc, braced_init_obstack);
push_init_level (loc, 2, braced_init_obstack);
return 0;
}
p = p->next;
if (!p)
break;
+ finish_implicit_inits (loc, braced_init_obstack);
push_init_level (loc, 2, braced_init_obstack);
p->stack = constructor_stack;
if (p->range_end && tree_int_cst_equal (p->index, p->range_end))
+2016-02-12 Bernd Schmidt <bschmidt@redhat.com>
+
+ PR c/69522
+ gcc.dg/pr69522.c: New test.
+
2016-02-12 Patrick Palka <ppalka@gcc.gnu.org>
PR c++/69098
--- /dev/null
+/* { dg-do compile } */
+struct str {};
+struct {
+ struct str b;
+ float c[1];
+ int d[1];
+ float e[2];
+ int f[1];
+} a = {{}, 0, {0.5}, 0, 0, {0}};