Hello,

I accidentally wrote 'free(loc)' instead of 'free (loc)'. Please see the
fixed patch attached below (contrib/check_GNU_style.sh says it's OK
now):
From 0445fba96ee9030feb00ebec893f8dfed153b12d Mon Sep 17 00:00:00 2001
From: Asher Gordon <asd...@posteo.net>
Date: Wed, 3 Jun 2020 17:20:08 -0400
Subject: [PATCH] Treat { 0 } specially for structs with the designated_init
 attribute.

Closes #95379.

gcc/ChangeLog:

	* doc/extend.texi: Document { 0 } as a special case for the
	designated_init attribute.

gcc/c/ChangeLog:

	* c-typeck.c (struct location_list): New type.
	(struct initializer_stack): Add positional_init_locs for
	-Wdesignated-init warnings.
	(start_init): Initialize initializer_stack->positional_init_locs
	to NULL.
	(finish_init): Free initializer_stack->positional_init_locs.
	(pop_init_level): Move -Wdesignated-init warning here from
	process_init_element so that we can treat { 0 } specially.
	(process_init_element): Instead of warning on -Wdesignated-init
	here, remember a list of locations where we should warn and do the
	actual warning in pop_init_level.

gcc/testsuite/ChangeLog:

	* gcc.dg/Wdesignated-init.c: Add tests for ignoring { 0 }.
---
 gcc/ChangeLog                           |  5 +++
 gcc/c/ChangeLog                         | 14 +++++++
 gcc/c/c-typeck.c                        | 55 +++++++++++++++++++++++--
 gcc/doc/extend.texi                     |  4 ++
 gcc/testsuite/ChangeLog                 |  4 ++
 gcc/testsuite/gcc.dg/Wdesignated-init.c |  3 ++
 6 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index edbcaf2bc4d..fd60a248226 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -95,6 +95,11 @@
 	(lto_tree_code_to_tag): Update.
 	(lto_tag_to_tree_code): Update.
 
+2020-06-03  Asher Gordon  <asd...@posteo.net>
+
+	* doc/extend.texi: Document { 0 } as a special case for the
+	designated_init attribute.
+
 2020-06-02  Felix Yang  <felix.y...@huawei.com>
 
 	PR target/95459
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index abf31e57688..e77f46930ef 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -17,6 +17,20 @@
 
 	* c-objc-common.h (LANG_HOOKS_OMP_PREDETERMINED_MAPPING): Redefine.
 
+2020-06-03  Asher Gordon  <asd...@posteo.net>
+
+	* c-typeck.c (struct location_list): New type.
+	(struct initializer_stack): Add positional_init_locs for
+	-Wdesignated-init warnings.
+	(start_init): Initialize initializer_stack->positional_init_locs
+	to NULL.
+	(finish_init): Free initializer_stack->positional_init_locs.
+	(pop_init_level): Move -Wdesignated-init warning here from
+	process_init_element so that we can treat { 0 } specially.
+	(process_init_element): Instead of warning on -Wdesignated-init
+	here, remember a list of locations where we should warn and do the
+	actual warning in pop_init_level.
+
 2020-05-28  Nicolas BĂ©rtolo  <nicolasbert...@gmail.com>
 
 	* Make-lang.in: Remove extra slash.
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 385bf3a1c7b..2d04f70f0cf 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -8179,6 +8179,13 @@ struct constructor_range_stack
 
 static struct constructor_range_stack *constructor_range_stack;
 
+/* A list of locations.  */
+
+struct location_list {
+  struct location_list *next;
+  location_t loc;
+};
+
 /* This stack records separate initializers that are nested.
    Nested initializers can't happen in ANSI C, but GNU C allows them
    in cases like { ... (struct foo) { ... } ... }.  */
@@ -8197,6 +8204,7 @@ struct initializer_stack
   char require_constant_value;
   char require_constant_elements;
   rich_location *missing_brace_richloc;
+  struct location_list *positional_init_locs;
 };
 
 static struct initializer_stack *initializer_stack;
@@ -8222,6 +8230,7 @@ start_init (tree decl, tree asmspec_tree ATTRIBUTE_UNUSED, int top_level,
   p->top_level = constructor_top_level;
   p->next = initializer_stack;
   p->missing_brace_richloc = richloc;
+  p->positional_init_locs = NULL;
   initializer_stack = p;
 
   constructor_decl = decl;
@@ -8287,6 +8296,13 @@ finish_init (void)
   spelling_size = p->spelling_size;
   constructor_top_level = p->top_level;
   initializer_stack = p->next;
+
+  while (p->positional_init_locs)
+    {
+      struct location_list *list = p->positional_init_locs;
+      p->positional_init_locs = list->next;
+      free (list);
+    }
   free (p);
 }

@@ -8744,6 +8760,22 @@ pop_init_level (location_t loc, int implicit,
 	  }
     }
 
+  /* Warn when positional initializers are used for a structure with
+     the designated_init attribute, but make an exception for { 0 }.  */
+  while (initializer_stack->positional_init_locs)
+    {
+      struct location_list *loc = initializer_stack->positional_init_locs;
+
+      if (!constructor_zeroinit)
+	warning_init (loc->loc,
+		      OPT_Wdesignated_init,
+		      "positional initialization of field in %<struct%> "
+		      "declared with %<designated_init%> attribute");
+
+      initializer_stack->positional_init_locs = loc->next;
+      free (loc);
+    }
+
   /* Pad out the end of the structure.  */
   if (p->replacement_value.value)
     /* If this closes a superfluous brace pair,
@@ -9975,10 +10007,25 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
       && TREE_CODE (constructor_type) == RECORD_TYPE
       && lookup_attribute ("designated_init",
 			   TYPE_ATTRIBUTES (constructor_type)))
-    warning_init (loc,
-		  OPT_Wdesignated_init,
-		  "positional initialization of field "
-		  "in %<struct%> declared with %<designated_init%> attribute");
+    {
+      struct location_list *new_loc;
+
+      /* Remember where we got a positional initializer so we can warn
+	 if it initializes a field of a structure with the
+	 designated_init attribute.  */
+      new_loc = XNEW (struct location_list);
+      new_loc->next = NULL;
+      new_loc->loc = loc;
+      if (initializer_stack->positional_init_locs)
+	{
+	  struct location_list *last = initializer_stack->positional_init_locs;
+	  while (last->next)
+	    last++;
+	  last->next = new_loc;
+	}
+      else
+	initializer_stack->positional_init_locs = new_loc;
+    }
 
   /* If we've exhausted any levels that didn't have braces,
      pop them now.  */
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index cced19d2018..a3c5059a8b0 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -8093,6 +8093,10 @@ attribute is to allow the programmer to indicate that a structure's
 layout may change, and that therefore relying on positional
 initialization will result in future breakage.
 
+Note that the universal zero initializer, @code{@{ 0 @}}, is considered
+a special case and will not produce a warning when used to initialize a
+structure with the @code{designated_init} attribute.
+
 GCC emits warnings based on this attribute by default; use
 @option{-Wno-designated-init} to suppress them.
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 89a1ad55923..a155c3c5332 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -67,6 +67,10 @@
 	PR middle-end/94874
 	* c-c++-common/gomp/pr94874.c: New.
 
+2020-06-03  Asher Gordon  <asd...@posteo.net>
+
+	* gcc.dg/Wdesignated-init.c: Add tests for ignoring { 0 }.
+
 2020-06-02  David Malcolm  <dmalc...@redhat.com>
 
 	PR jit/95426
diff --git a/gcc/testsuite/gcc.dg/Wdesignated-init.c b/gcc/testsuite/gcc.dg/Wdesignated-init.c
index b9ca572206c..adb7949df55 100644
--- a/gcc/testsuite/gcc.dg/Wdesignated-init.c
+++ b/gcc/testsuite/gcc.dg/Wdesignated-init.c
@@ -24,6 +24,9 @@ struct Des {
 struct Des d1 = { 5, 5 }; /* { dg-warning "(positional|near initialization)" } */
 struct Des d2 = { .x = 5, .y = 5 };
 struct Des d3 = { .x = 5, 5 }; /* { dg-warning "(positional|near initialization)" } */
+struct Des d4 = { 0 };
+struct Des d5 = { 5 }; /* { dg-warning "(positional|near initialization)" } */
+struct Des d6 = { 0, 0 }; /* { dg-warning "(positional|near initialization)" } */
 
 struct Des fd1 (void)
 {
-- 
2.26.2

Thanks,
Asher

-- 
<cas> well there ya go.  say something stupid in irc and have it
      immortalised forever in someone's .sig file
                               --------
I prefer to send and receive mail encrypted. Please send me your
public key, and if you do not have my public key, please let me
know. Thanks.

GPG fingerprint: 38F3 975C D173 4037 B397  8095 D4C9 C4FC 5460 8E68

Attachment: signature.asc
Description: PGP signature

Reply via email to