diff mbox

C FE: implement fix-it hint for -Wmissing-braces

Message ID 1478914208-6193-1-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm Nov. 12, 2016, 1:30 a.m. UTC
This patch implements fix-it hints to -Wmissing-braces, showing where to
add braces.

For example:

  $ cat test.c
  int arr_2_3_2[2][3][2] =
    { 0, 1, 2, 3, 4, 5,
      6, 7, 8, 9, 10, 11};

  $ ./xgcc -B. -c test.c -Wall -fdiagnostics-generate-patch
  test.c:2:3: warning: missing braces around initializer [-Wmissing-braces]
     { 0, 1, 2, 3, 4, 5,
     ^
       {
       {   } {   } {   }
                       }
       6, 7, 8, 9, 10, 11};
       {
       {   } {   } {     }
                         }
  --- test.c
  +++ test.c
  @@ -1,3 +1,3 @@
   int arr_2_3_2[2][3][2] =
  -  { 0, 1, 2, 3, 4, 5,
  -    6, 7, 8, 9, 10, 11};
  +  { {{0, 1}, {2, 3}, {4, 5}},
  +    {{6, 7}, {8, 9}, {10, 11}}};

Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu; adds
29 PASS results to gcc.sum.

OK for trunk?

gcc/c/ChangeLog:
	* c-parser.c (c_parser_declaration_or_fndef): Create a
	rich_location at init_loc and parse it to start_init.
        (last_init_list_comma): New global.
	(c_parser_braced_init): Update last_init_list_comma when parsing
	commas.  Pass it to pop_init_level.  Pass location of closing
	brace to pop_init_level.
	(c_parser_postfix_expression_after_paren_type): Create a
	rich_location at type_loc and parse it to start_init.
	(c_parser_omp_declare_reduction): Likewise for loc.
	* c-tree.h (start_init): Add rich_location * param.
	(pop_init_level): Add location_t param.
	* c-typeck.c (struct initializer_stack): Add field
	"missing_brace_richloc".
	(start_init): Add richloc param, use it to initialize
	the stack node's missing_brace_richloc.
	(last_init_list_comma): New decl.
	(finish_implicit_inits): Pass last_init_list_comma to
	pop_init_level.
	(push_init_level): When finding missing open braces, add fix-it
	hints to the richloc.
	(pop_init_level): Add "insert_before" param and pass it
	when calling pop_init_level.  Add fixits about missing
	close braces to any richloc.  Use the richloc for the
	-Wmissing-braces warning.
	(set_designator): Pass last_init_list_comma to pop_init_level.
	(process_init_element): Likewise.

gcc/testsuite/ChangeLog:
	* gcc.dg/Wmissing-braces-fixits.c: New test case.
---
 gcc/c/c-parser.c                              |  26 +++-
 gcc/c/c-tree.h                                |   5 +-
 gcc/c/c-typeck.c                              |  53 +++++--
 gcc/testsuite/gcc.dg/Wmissing-braces-fixits.c | 202 ++++++++++++++++++++++++++
 4 files changed, 264 insertions(+), 22 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wmissing-braces-fixits.c

Comments

Jeff Law Dec. 7, 2016, 7:49 p.m. UTC | #1
On 11/11/2016 06:30 PM, David Malcolm wrote:
> This patch implements fix-it hints to -Wmissing-braces, showing where to
> add braces.
>
> For example:
>
>   $ cat test.c
>   int arr_2_3_2[2][3][2] =
>     { 0, 1, 2, 3, 4, 5,
>       6, 7, 8, 9, 10, 11};
>
>   $ ./xgcc -B. -c test.c -Wall -fdiagnostics-generate-patch
>   test.c:2:3: warning: missing braces around initializer [-Wmissing-braces]
>      { 0, 1, 2, 3, 4, 5,
>      ^
>        {
>        {   } {   } {   }
>                        }
>        6, 7, 8, 9, 10, 11};
>        {
>        {   } {   } {     }
>                          }
>   --- test.c
>   +++ test.c
>   @@ -1,3 +1,3 @@
>    int arr_2_3_2[2][3][2] =
>   -  { 0, 1, 2, 3, 4, 5,
>   -    6, 7, 8, 9, 10, 11};
>   +  { {{0, 1}, {2, 3}, {4, 5}},
>   +    {{6, 7}, {8, 9}, {10, 11}}};
>
> Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu; adds
> 29 PASS results to gcc.sum.
>
> OK for trunk?
>
> gcc/c/ChangeLog:
> 	* c-parser.c (c_parser_declaration_or_fndef): Create a
> 	rich_location at init_loc and parse it to start_init.
>         (last_init_list_comma): New global.
> 	(c_parser_braced_init): Update last_init_list_comma when parsing
> 	commas.  Pass it to pop_init_level.  Pass location of closing
> 	brace to pop_init_level.
> 	(c_parser_postfix_expression_after_paren_type): Create a
> 	rich_location at type_loc and parse it to start_init.
> 	(c_parser_omp_declare_reduction): Likewise for loc.
> 	* c-tree.h (start_init): Add rich_location * param.
> 	(pop_init_level): Add location_t param.
> 	* c-typeck.c (struct initializer_stack): Add field
> 	"missing_brace_richloc".
> 	(start_init): Add richloc param, use it to initialize
> 	the stack node's missing_brace_richloc.
> 	(last_init_list_comma): New decl.
> 	(finish_implicit_inits): Pass last_init_list_comma to
> 	pop_init_level.
> 	(push_init_level): When finding missing open braces, add fix-it
> 	hints to the richloc.
> 	(pop_init_level): Add "insert_before" param and pass it
> 	when calling pop_init_level.  Add fixits about missing
> 	close braces to any richloc.  Use the richloc for the
> 	-Wmissing-braces warning.
> 	(set_designator): Pass last_init_list_comma to pop_init_level.
> 	(process_init_element): Likewise.
>
> gcc/testsuite/ChangeLog:
> 	* gcc.dg/Wmissing-braces-fixits.c: New test case.
I'm a bit unsure about how useful this is in practice.  But OK.

jeff
diff mbox

Patch

diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 6bc42da..8029b80 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -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,
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index e8060f8..38c515a 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -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,
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index f0917ed..2b69498 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -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);
 	    }
 
diff --git a/gcc/testsuite/gcc.dg/Wmissing-braces-fixits.c b/gcc/testsuite/gcc.dg/Wmissing-braces-fixits.c
new file mode 100644
index 0000000..37998d0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wmissing-braces-fixits.c
@@ -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 "" } */