@@ -1950,8 +1950,9 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
c_parser_consume_token (parser);
if (auto_type_p)
{
- start_init (NULL_TREE, asm_name, global_bindings_p ());
init_loc = c_parser_peek_token (parser)->location;
+ rich_location richloc (line_table, init_loc);
+ start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
init = c_parser_expr_no_commas (parser, NULL);
if (TREE_CODE (init.value) == COMPONENT_REF
&& DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
@@ -2007,8 +2008,9 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|| !vec_safe_is_empty (parser->cilk_simd_fn_tokens))
c_finish_omp_declare_simd (parser, d, NULL_TREE,
omp_declare_simd_clauses);
- start_init (d, asm_name, global_bindings_p ());
init_loc = c_parser_peek_token (parser)->location;
+ rich_location richloc (line_table, init_loc);
+ start_init (d, asm_name, global_bindings_p (), &richloc);
init = c_parser_initializer (parser);
finish_init ();
}
@@ -4401,6 +4403,11 @@ c_parser_initializer (c_parser *parser)
}
}
+/* The location of the last comma within the current initializer list,
+ or UNKNOWN_LOCATION if not within one. */
+
+location_t last_init_list_comma;
+
/* Parse a braced initializer list. TYPE is the type specified for a
compound literal, and NULL_TREE for other initializers and for
nested braced lists. NESTED_P is true for nested braced lists,
@@ -4438,7 +4445,10 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
if (parser->error)
break;
if (c_parser_next_token_is (parser, CPP_COMMA))
- c_parser_consume_token (parser);
+ {
+ last_init_list_comma = c_parser_peek_token (parser)->location;
+ c_parser_consume_token (parser);
+ }
else
break;
if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
@@ -4452,13 +4462,13 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
ret.original_code = ERROR_MARK;
ret.original_type = NULL;
c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, "expected %<}%>");
- pop_init_level (brace_loc, 0, &braced_init_obstack);
+ pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
obstack_free (&braced_init_obstack, NULL);
return ret;
}
location_t close_loc = next_tok->location;
c_parser_consume_token (parser);
- ret = pop_init_level (brace_loc, 0, &braced_init_obstack);
+ ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
obstack_free (&braced_init_obstack, NULL);
set_c_expr_source_range (&ret, brace_loc, close_loc);
return ret;
@@ -8294,7 +8304,8 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser,
tree type_expr = NULL_TREE;
bool type_expr_const = true;
check_compound_literal_type (type_loc, type_name);
- start_init (NULL_TREE, NULL, 0);
+ rich_location richloc (line_table, type_loc);
+ start_init (NULL_TREE, NULL, 0, &richloc);
type = groktypename (type_name, &type_expr, &type_expr_const);
start_loc = c_parser_peek_token (parser)->location;
if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
@@ -17172,8 +17183,9 @@ c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
else
{
tree st = push_stmt_list ();
- start_init (omp_priv, NULL_TREE, 0);
location_t loc = c_parser_peek_token (parser)->location;
+ rich_location richloc (line_table, loc);
+ start_init (omp_priv, NULL_TREE, 0, &richloc);
struct c_expr init = c_parser_initializer (parser);
finish_init ();
finish_decl (omp_priv, loc, init.value,
@@ -637,12 +637,13 @@ extern tree c_cast_expr (location_t, struct c_type_name *, tree);
extern tree build_c_cast (location_t, tree, tree);
extern void store_init_value (location_t, tree, tree, tree);
extern void maybe_warn_string_init (location_t, tree, struct c_expr);
-extern void start_init (tree, tree, int);
+extern void start_init (tree, tree, int, rich_location *);
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 struct c_expr pop_init_level (location_t, int, struct obstack *,
+ location_t);
extern void set_init_index (location_t, tree, tree, struct obstack *);
extern void set_init_label (location_t, tree, location_t, struct obstack *);
extern void process_init_element (location_t, struct c_expr, bool,
@@ -7490,6 +7490,7 @@ struct initializer_stack
char top_level;
char require_constant_value;
char require_constant_elements;
+ rich_location *missing_brace_richloc;
};
static struct initializer_stack *initializer_stack;
@@ -7497,7 +7498,8 @@ static struct initializer_stack *initializer_stack;
/* Prepare to parse and output the initializer for variable DECL. */
void
-start_init (tree decl, tree asmspec_tree ATTRIBUTE_UNUSED, int top_level)
+start_init (tree decl, tree asmspec_tree ATTRIBUTE_UNUSED, int top_level,
+ rich_location *richloc)
{
const char *locus;
struct initializer_stack *p = XNEW (struct initializer_stack);
@@ -7513,6 +7515,7 @@ start_init (tree decl, tree asmspec_tree ATTRIBUTE_UNUSED, int top_level)
p->spelling_size = spelling_size;
p->top_level = constructor_top_level;
p->next = initializer_stack;
+ p->missing_brace_richloc = richloc;
initializer_stack = p;
constructor_decl = decl;
@@ -7697,6 +7700,8 @@ really_start_incremental_init (tree type)
}
}
+extern location_t last_init_list_comma;
+
/* Called when we see an open brace for a nested initializer. Finish
off any pending levels with implicit braces. */
void
@@ -7707,14 +7712,16 @@ finish_implicit_inits (location_t loc, struct obstack *braced_init_obstack)
if (RECORD_OR_UNION_TYPE_P (constructor_type)
&& constructor_fields == 0)
process_init_element (input_location,
- pop_init_level (loc, 1, braced_init_obstack),
+ pop_init_level (loc, 1, braced_init_obstack,
+ last_init_list_comma),
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),
+ pop_init_level (loc, 1, braced_init_obstack,
+ last_init_list_comma),
true, braced_init_obstack);
else
break;
@@ -7833,7 +7840,12 @@ push_init_level (location_t loc, int implicit,
}
if (implicit == 1)
- found_missing_braces = 1;
+ {
+ found_missing_braces = 1;
+ if (initializer_stack->missing_brace_richloc)
+ initializer_stack->missing_brace_richloc->add_fixit_insert_before
+ (loc, "{");
+ }
if (RECORD_OR_UNION_TYPE_P (constructor_type))
{
@@ -7911,7 +7923,8 @@ push_init_level (location_t loc, int implicit,
struct c_expr
pop_init_level (location_t loc, int implicit,
- struct obstack *braced_init_obstack)
+ struct obstack *braced_init_obstack,
+ location_t insert_before)
{
struct constructor_stack *p;
struct c_expr ret;
@@ -7925,10 +7938,15 @@ pop_init_level (location_t loc, int implicit,
pop any inner levels that didn't have explicit braces. */
while (constructor_stack->implicit)
process_init_element (input_location,
- pop_init_level (loc, 1, braced_init_obstack),
+ pop_init_level (loc, 1, braced_init_obstack,
+ insert_before),
true, braced_init_obstack);
gcc_assert (!constructor_range_stack);
}
+ else
+ if (initializer_stack->missing_brace_richloc)
+ initializer_stack->missing_brace_richloc->add_fixit_insert_before
+ (insert_before, "}");
/* Now output all pending elements. */
constructor_incremental = 1;
@@ -7985,8 +8003,12 @@ pop_init_level (location_t loc, int implicit,
/* Warn when some structs are initialized with direct aggregation. */
if (!implicit && found_missing_braces && warn_missing_braces
&& !constructor_zeroinit)
- warning_init (loc, OPT_Wmissing_braces,
- "missing braces around initializer");
+ {
+ gcc_assert (initializer_stack->missing_brace_richloc);
+ warning_at_rich_loc (initializer_stack->missing_brace_richloc,
+ OPT_Wmissing_braces,
+ "missing braces around initializer");
+ }
/* Warn when some struct elements are implicitly initialized to zero. */
if (warn_missing_field_initializers
@@ -8125,7 +8147,8 @@ set_designator (location_t loc, int array,
braces. */
while (constructor_stack->implicit)
process_init_element (input_location,
- pop_init_level (loc, 1, braced_init_obstack),
+ pop_init_level (loc, 1, braced_init_obstack,
+ last_init_list_comma),
true, braced_init_obstack);
constructor_designated = 1;
return 0;
@@ -9194,7 +9217,8 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
if (RECORD_OR_UNION_TYPE_P (constructor_type)
&& constructor_fields == 0)
process_init_element (loc,
- pop_init_level (loc, 1, braced_init_obstack),
+ pop_init_level (loc, 1, braced_init_obstack,
+ last_init_list_comma),
true, braced_init_obstack);
else if ((TREE_CODE (constructor_type) == ARRAY_TYPE
|| VECTOR_TYPE_P (constructor_type))
@@ -9202,7 +9226,8 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
&& tree_int_cst_lt (constructor_max_index,
constructor_index))
process_init_element (loc,
- pop_init_level (loc, 1, braced_init_obstack),
+ pop_init_level (loc, 1, braced_init_obstack,
+ last_init_list_comma),
true, braced_init_obstack);
else
break;
@@ -9535,7 +9560,8 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
gcc_assert (constructor_stack->implicit);
process_init_element (loc,
pop_init_level (loc, 1,
- braced_init_obstack),
+ braced_init_obstack,
+ last_init_list_comma),
true, braced_init_obstack);
}
for (p = range_stack;
@@ -9545,7 +9571,8 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
gcc_assert (constructor_stack->implicit);
process_init_element (loc,
pop_init_level (loc, 1,
- braced_init_obstack),
+ braced_init_obstack,
+ last_init_list_comma),
true, braced_init_obstack);
}
new file mode 100644
@@ -0,0 +1,202 @@
+/* { dg-options "-Wmissing-braces -fdiagnostics-show-caret" } */
+
+struct sf2 { int i; int j; };
+struct sf3 { int i; int j; int k; };
+struct sa2 { int arr[2]; };
+struct sa3 { int arr[3]; };
+
+int arr_12[12] = \
+ { 0, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11};
+
+int arr_12_1[12][1] = \
+ { 0, 1, 2, 3, 4, 5, /* { dg-warning "missing braces around initializer" } */
+ 6, 7, 8, 9, 10, 11};
+ /* { dg-begin-multiline-output "" }
+ { 0, 1, 2, 3, 4, 5,
+ ^
+ {} {} {} {} {} {}
+ 6, 7, 8, 9, 10, 11};
+ {} {} {} {} { } { }
+ { dg-end-multiline-output "" } */
+
+int arr_1_12[1][12] = \
+ { 0, 1, 2, 3, 4, 5, /* { dg-warning "missing braces around initializer" } */
+ 6, 7, 8, 9, 10, 11};
+ /* { dg-begin-multiline-output "" }
+ { 0, 1, 2, 3, 4, 5,
+ ^
+ {
+ 6, 7, 8, 9, 10, 11};
+ }
+ { dg-end-multiline-output "" } */
+
+int arr_2_6[2][6] = \
+ { 0, 1, 2, 3, 4, 5, /* { dg-warning "missing braces around initializer" } */
+ 6, 7, 8, 9, 10, 11};
+ /* { dg-begin-multiline-output "" }
+ { 0, 1, 2, 3, 4, 5,
+ ^
+ { }
+ 6, 7, 8, 9, 10, 11};
+ { }
+ { dg-end-multiline-output "" } */
+
+int arr_2_2_3[2][2][3] = \
+ { 0, 1, 2, 3, 4, 5, /* { dg-warning "missing braces around initializer" } */
+ 6, 7, 8, 9, 10, 11};
+ /* { dg-begin-multiline-output "" }
+ { 0, 1, 2, 3, 4, 5,
+ ^
+ {
+ { } { }
+ }
+ 6, 7, 8, 9, 10, 11};
+ {
+ { } { }
+ }
+ { dg-end-multiline-output "" } */
+
+int arr_2_3_2[2][3][2] = \
+ { 0, 1, 2, 3, 4, 5, /* { dg-warning "missing braces around initializer" } */
+ 6, 7, 8, 9, 10, 11};
+ /* { dg-begin-multiline-output "" }
+ { 0, 1, 2, 3, 4, 5,
+ ^
+ {
+ { } { } { }
+ }
+ 6, 7, 8, 9, 10, 11};
+ {
+ { } { } { }
+ }
+ { dg-end-multiline-output "" } */
+
+int arr_6_2[6][2] = \
+ { 0, 1, 2, 3, 4, 5, /* { dg-warning "missing braces around initializer" } */
+ 6, 7, 8, 9, 10, 11};
+ /* { dg-begin-multiline-output "" }
+ { 0, 1, 2, 3, 4, 5,
+ ^
+ { } { } { }
+ 6, 7, 8, 9, 10, 11};
+ { } { } { }
+ { dg-end-multiline-output "" } */
+
+int arr_3_2_2[3][2][2] = \
+ { 0, 1, 2, 3, 4, 5, /* { dg-warning "missing braces around initializer" } */
+ 6, 7, 8, 9, 10, 11};
+ /* { dg-begin-multiline-output "" }
+ { 0, 1, 2, 3, 4, 5,
+ ^
+ {
+ { } { }
+ } {
+ { }
+ 6, 7, 8, 9, 10, 11};
+ { }
+ } {
+ { } { }
+ }
+ { dg-end-multiline-output "" } */
+
+int arr_3_4[3][4] = \
+ { 0, 1, 2, 3, 4, 5, /* { dg-warning "missing braces around initializer" } */
+ 6, 7, 8, 9, 10, 11};
+ /* { dg-begin-multiline-output "" }
+ { 0, 1, 2, 3, 4, 5,
+ ^
+ { } {
+ 6, 7, 8, 9, 10, 11};
+ } { }
+ { dg-end-multiline-output "" } */
+
+int arr_4_3[4][3] = \
+ { 0, 1, 2, 3, 4, 5, /* { dg-warning "missing braces around initializer" } */
+ 6, 7, 8, 9, 10, 11};
+ /* { dg-begin-multiline-output "" }
+ { 0, 1, 2, 3, 4, 5,
+ ^
+ { } { }
+ 6, 7, 8, 9, 10, 11};
+ { } { }
+ { dg-end-multiline-output "" } */
+
+int arr_2_1_6[2][1][6] = \
+ { 0, 1, 2, 3, 4, 5, /* { dg-warning "missing braces around initializer" } */
+ 6, 7, 8, 9, 10, 11};
+ /* { dg-begin-multiline-output "" }
+ { 0, 1, 2, 3, 4, 5,
+ ^
+ {
+ { }
+ }
+ 6, 7, 8, 9, 10, 11};
+ {
+ { }
+ }
+ { dg-end-multiline-output "" } */
+
+struct sf2 arr_6_sf2[6] = \
+ { 0, 1, 2, 3, 4, 5, /* { dg-warning "missing braces around initializer" } */
+ 6, 7, 8, 9, 10, 11};
+ /* { dg-begin-multiline-output "" }
+ { 0, 1, 2, 3, 4, 5,
+ ^
+ { } { } { }
+ 6, 7, 8, 9, 10, 11};
+ { } { } { }
+ { dg-end-multiline-output "" } */
+
+struct sf3 arr_4_sf3[4] = \
+ { 0, 1, 2, 3, 4, 5, /* { dg-warning "missing braces around initializer" } */
+ 6, 7, 8, 9, 10, 11};
+ /* { dg-begin-multiline-output "" }
+ { 0, 1, 2, 3, 4, 5,
+ ^
+ { } { }
+ 6, 7, 8, 9, 10, 11};
+ { } { }
+ { dg-end-multiline-output "" } */
+
+struct sa2 arr_6_sa2[6] = \
+ { 0, 1, 2, 3, 4, 5, /* { dg-warning "missing braces around initializer" } */
+ 6, 7, 8, 9, 10, 11};
+ /* { dg-begin-multiline-output "" }
+ { 0, 1, 2, 3, 4, 5,
+ ^
+ {
+ { }
+ } {
+ { }
+ } {
+ { }
+ }
+ 6, 7, 8, 9, 10, 11};
+ {
+ { }
+ } {
+ { }
+ } {
+ { }
+ }
+ { dg-end-multiline-output "" } */
+
+struct sa3 arr_4_sa3[4] = \
+ { 0, 1, 2, 3, 4, 5, /* { dg-warning "missing braces around initializer" } */
+ 6, 7, 8, 9, 10, 11};
+ /* { dg-begin-multiline-output "" }
+ { 0, 1, 2, 3, 4, 5,
+ ^
+ {
+ { }
+ } {
+ { }
+ }
+ 6, 7, 8, 9, 10, 11};
+ {
+ { }
+ } {
+ { }
+ }
+ { dg-end-multiline-output "" } */