Adjust how gcc4 handles the "missing braces around initializer" warning.
authorclaudio <claudio@openbsd.org>
Wed, 18 Jan 2023 10:27:05 +0000 (10:27 +0000)
committerclaudio <claudio@openbsd.org>
Wed, 18 Jan 2023 10:27:05 +0000 (10:27 +0000)
In c99 any value can be initalised using a { 0 } constructor independent
of the type. Now if a struct's first member is another struct then gcc4
issues the above warning but it should not do that.

Move the warning check from push_init_level() to pop_init_level() and
check if either { 0 } or { } was used. If additional implicit braces
were added surpress the warning.

Inspired by gcc PR#64709
OK deraadt@ miod@

gnu/gcc/gcc/c-typeck.c

index 8d3c228..ce565aa 100644 (file)
@@ -4873,6 +4873,9 @@ static int constructor_simple;
 /* 1 if this constructor is erroneous so far.  */
 static int constructor_erroneous;
 
+/* 1 if this constructor is a zero init. */
+static int constructor_zeroinit;
+
 /* Structure for managing pending initializer elements, organized as an
    AVL tree.  */
 
@@ -5032,6 +5035,7 @@ start_init (tree decl, tree asmspec_tree ATTRIBUTE_UNUSED, int top_level)
   constructor_stack = 0;
   constructor_range_stack = 0;
 
+  constructor_zeroinit = 0;
   missing_braces_mentioned = 0;
 
   spelling_base = 0;
@@ -5314,12 +5318,6 @@ push_init_level (int implicit)
        set_nonincremental_init ();
     }
 
-  if (implicit == 1 && warn_missing_braces && !missing_braces_mentioned)
-    {
-      missing_braces_mentioned = 1;
-      warning_init ("missing braces around initializer");
-    }
-
   if (TREE_CODE (constructor_type) == RECORD_TYPE
           || TREE_CODE (constructor_type) == UNION_TYPE)
     {
@@ -5447,6 +5445,22 @@ pop_init_level (int implicit)
        }
     }
 
+  if (VEC_length (constructor_elt,constructor_elements) == 0)
+     constructor_zeroinit = 1;
+  else if (VEC_length (constructor_elt,constructor_elements) == 1 &&
+      initializer_zerop (VEC_index (constructor_elt,constructor_elements,0)->value))
+     constructor_zeroinit = 1;
+  else
+     constructor_zeroinit = 0;
+
+  /* only warn for missing braces unless it is { 0 } */
+  if (p->implicit == 1 && warn_missing_braces && !missing_braces_mentioned &&
+      !constructor_zeroinit)
+    {
+      missing_braces_mentioned = 1;
+      warning_init ("missing braces around initializer");
+    }
+
   /* Warn when some struct elements are implicitly initialized to zero.  */
   if (warn_missing_field_initializers
       && constructor_type