On 28/01/2026 05:02, Andrew Pinski wrote:
First sorry it took someone to review this version of the patch. I
also didn't have it in my inbox due to switching over to a new email
late last year.


Thank you for the review! I had given up hope.

     Commit 0547dbb725b reduced the number of cases in which
     union padding bits are zeroed when the relevant language
     standard does not strictly require it, unless gcc was
     invoked with -fzero-init-padding-bits=unions or
     -fzero-init-padding-bits=all in order to explicitly
     request zeroing of padding bits.

     This commit adds a closely related warning,
     -Wzero-init-padding-bits=, which is intended to help
     programmers to find code that might now need to be
     rewritten or recompiled with
     -fzero-init-padding-bits=unions or
     -fzero-init-padding-bits=all in order to replicate
     the behaviour that it had when compiled by older
     versions of GCC. It can also be used to find struct
     padding that was never previously guaranteed to be
     zero initialized and still isn't unless GCC is
     invoked with -fzero-init-padding-bits=all.

This is definitely useful for the recent changes.

We think so. Based on feedback from the Yocto Project, my patch does what they need it to do. They reported 53 warnings in total across 12 packages.


     The new warning can be set to the same three states
     as -fzero-init-padding-bits ('standard', 'unions'
     or 'all') and has the same default value ('standard').

     The two options interact as follows:

              f: standard  f: unions   f: all
     w: standard     X         X         X
     w: unions       U         X         X
     w: all          A         S         X

     X = No warnings about padding
     U = Warnings about padding of unions.
     S = Warnings about padding of structs.
     A = Warnings about padding of structs and unions.

     The level of optimisation and whether or not the
     entire initializer is dropped to memory can both
     affect whether warnings are produced when compiling
     a given program. This is intentional, since tying
     the warnings more closely to the relevant language
     standard would require a very different approach
     that would still be target-dependent, might impose
     an unacceptable burden on programmers, and would
     risk not satisfying the intended use-case (which
     is closely tied to a specific optimisation).

gcc/ChangeLog:

         * common.opt: Add Wzero-init-padding-bits=.
         * doc/invoke.texi: Document Wzero-init-padding-bits=.
         * expr.cc (categorize_ctor_elements_1): Update new struct type
         ctor_completeness instead of an integer to indicate presence of
         padding or missing fields in a constructor. Instead of setting -1
         upon discovery of padding bits in both structs and unions,
         set separate flags to indicate the type of padding bits.
         (categorize_ctor_elements): Update the type and documentation of
         the p_complete parameter.
         (mostly_zeros_p): Use new struct type ctor_completeness when
         calling categorize_ctor_elements.
         (all_zeros_p): Use new struct type ctor_completeness when
         calling categorize_ctor_elements.
         * expr.h (struct ctor_completeness): New struct type to replace an
         an integer that could take the value -1 ('all fields are
         initialized, but there's padding'), 0 ('fields are missing') or
         1 ('all fields are initialized, and there's no padding'). Named
         bool members make the code easier to understand and make room to
         disambiguate struct padding bits from union padding bits.
         (categorize_ctor_elements): Update the function declaration to use
         the new struct type in the last parameter declaration.
         * gimplify.cc (gimplify_init_constructor): Replace use of
         complete_p != 0 ('all fields are initialized') with !sparse,
         replace use of complete == 0 ('fields are missing') with sparse, and
         replace use of complete <= 0 ('fields are missing' or 'all fields are
         initialized, but there's padding') with sparse || padded_union or
         padded_non_union. Trigger new warnings if storage for the object
         is not zeroed but padded_union or padded_non_union is set
         (because this combination implies possible non-zero padding bits).

gcc/testsuite/ChangeLog:

         * gcc.dg/c23-empty-init-warn-1.c: New test.
         * gcc.dg/c23-empty-init-warn-10.c: New test.
         * gcc.dg/c23-empty-init-warn-11.c: New test.
         * gcc.dg/c23-empty-init-warn-12.c: New test.
         * gcc.dg/c23-empty-init-warn-13.c: New test.
         * gcc.dg/c23-empty-init-warn-14.c: New test.
         * gcc.dg/c23-empty-init-warn-15.c: New test.
         * gcc.dg/c23-empty-init-warn-16.c: New test.
         * gcc.dg/c23-empty-init-warn-17.c: New test.
         * gcc.dg/c23-empty-init-warn-2.c: New test.
         * gcc.dg/c23-empty-init-warn-3.c: New test.
         * gcc.dg/c23-empty-init-warn-4.c: New test.
         * gcc.dg/c23-empty-init-warn-5.c: New test.
         * gcc.dg/c23-empty-init-warn-6.c: New test.
         * gcc.dg/c23-empty-init-warn-7.c: New test.
         * gcc.dg/c23-empty-init-warn-8.c: New test.
         * gcc.dg/c23-empty-init-warn-9.c: New test.
         * gcc.dg/gnu11-empty-init-warn-1.c: New test.
         * gcc.dg/gnu11-empty-init-warn-10.c: New test.
         * gcc.dg/gnu11-empty-init-warn-11.c: New test.
         * gcc.dg/gnu11-empty-init-warn-12.c: New test.
         * gcc.dg/gnu11-empty-init-warn-13.c: New test.
         * gcc.dg/gnu11-empty-init-warn-14.c: New test.
         * gcc.dg/gnu11-empty-init-warn-15.c: New test.
         * gcc.dg/gnu11-empty-init-warn-16.c: New test.
         * gcc.dg/gnu11-empty-init-warn-17.c: New test.
         * gcc.dg/gnu11-empty-init-warn-2.c: New test.
         * gcc.dg/gnu11-empty-init-warn-3.c: New test.
         * gcc.dg/gnu11-empty-init-warn-4.c: New test.
         * gcc.dg/gnu11-empty-init-warn-5.c: New test.
         * gcc.dg/gnu11-empty-init-warn-6.c: New test.
         * gcc.dg/gnu11-empty-init-warn-7.c: New test.
         * gcc.dg/gnu11-empty-init-warn-8.c: New test.
         * gcc.dg/gnu11-empty-init-warn-9.c: New test.
---
  gcc/common.opt                                |  4 +
  gcc/doc/invoke.texi                           | 85 ++++++++++++++++++-
  gcc/expr.cc                                   | 41 ++++-----
  gcc/expr.h                                    |  7 +-
  gcc/gimplify.cc                               | 27 +++++-
  gcc/testsuite/gcc.dg/c23-empty-init-warn-1.c  | 68 +++++++++++++++
  gcc/testsuite/gcc.dg/c23-empty-init-warn-10.c |  8 ++
  gcc/testsuite/gcc.dg/c23-empty-init-warn-11.c |  8 ++
  gcc/testsuite/gcc.dg/c23-empty-init-warn-12.c |  8 ++
  gcc/testsuite/gcc.dg/c23-empty-init-warn-13.c |  8 ++
  gcc/testsuite/gcc.dg/c23-empty-init-warn-14.c |  8 ++
  gcc/testsuite/gcc.dg/c23-empty-init-warn-15.c |  8 ++
  gcc/testsuite/gcc.dg/c23-empty-init-warn-16.c |  8 ++
  gcc/testsuite/gcc.dg/c23-empty-init-warn-17.c | 51 +++++++++++
  gcc/testsuite/gcc.dg/c23-empty-init-warn-2.c  | 69 +++++++++++++++
  gcc/testsuite/gcc.dg/c23-empty-init-warn-3.c  |  7 ++
  gcc/testsuite/gcc.dg/c23-empty-init-warn-4.c  | 69 +++++++++++++++
  gcc/testsuite/gcc.dg/c23-empty-init-warn-5.c  |  8 ++
  gcc/testsuite/gcc.dg/c23-empty-init-warn-6.c  |  8 ++
  gcc/testsuite/gcc.dg/c23-empty-init-warn-7.c  |  8 ++
  gcc/testsuite/gcc.dg/c23-empty-init-warn-8.c  |  8 ++
  gcc/testsuite/gcc.dg/c23-empty-init-warn-9.c  | 69 +++++++++++++++
  .../gcc.dg/gnu11-empty-init-warn-1.c          | 52 ++++++++++++
  .../gcc.dg/gnu11-empty-init-warn-10.c         |  8 ++
  .../gcc.dg/gnu11-empty-init-warn-11.c         |  8 ++
  .../gcc.dg/gnu11-empty-init-warn-12.c         |  8 ++
  .../gcc.dg/gnu11-empty-init-warn-13.c         |  8 ++
  .../gcc.dg/gnu11-empty-init-warn-14.c         |  8 ++
  .../gcc.dg/gnu11-empty-init-warn-15.c         |  8 ++
  .../gcc.dg/gnu11-empty-init-warn-16.c         |  8 ++
  .../gcc.dg/gnu11-empty-init-warn-17.c         | 51 +++++++++++
  .../gcc.dg/gnu11-empty-init-warn-2.c          | 59 +++++++++++++
  .../gcc.dg/gnu11-empty-init-warn-3.c          |  7 ++
  .../gcc.dg/gnu11-empty-init-warn-4.c          | 63 ++++++++++++++
  .../gcc.dg/gnu11-empty-init-warn-5.c          |  8 ++
  .../gcc.dg/gnu11-empty-init-warn-6.c          |  8 ++
  .../gcc.dg/gnu11-empty-init-warn-7.c          |  8 ++
  .../gcc.dg/gnu11-empty-init-warn-8.c          |  8 ++
  .../gcc.dg/gnu11-empty-init-warn-9.c          | 55 ++++++++++++
  39 files changed, 935 insertions(+), 25 deletions(-)
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-1.c
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-10.c
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-11.c
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-12.c
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-13.c
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-14.c
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-15.c
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-16.c
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-17.c
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-2.c
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-3.c
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-4.c
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-5.c
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-6.c
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-7.c
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-8.c
  create mode 100644 gcc/testsuite/gcc.dg/c23-empty-init-warn-9.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-1.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-10.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-11.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-12.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-13.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-14.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-15.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-16.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-17.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-2.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-3.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-4.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-5.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-6.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-7.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-8.c
  create mode 100644 gcc/testsuite/gcc.dg/gnu11-empty-init-warn-9.c

diff --git a/gcc/common.opt b/gcc/common.opt
index 0e50305dde8..3d8da881aa3 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -911,6 +911,10 @@ Wtsan
  Common Var(warn_tsan) Init(1) Warning
  Warn about unsupported features in ThreadSanitizer.

+Wzero-init-padding-bits=
+Common Joined RejectNegative Enum(zero_init_padding_bits_kind)
Var(warn_zero_init_padding_bits) Init(ZERO_INIT_PADDING_BITS_STANDARD)
Warning
+-Wzero-init-padding-bits=[standard|unions|all] Warn about
initializers that might not zero padding bits.
+
  Xassembler
  Driver Separate

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index f31d504f99e..67c2f6a1644 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -446,7 +446,8 @@ Objective-C and Objective-C++ Dialects}.
  -Wvolatile-register-var  -Wwrite-strings
  -Wno-xor-used-as-pow
  -Wzero-as-null-pointer-constant
--Wzero-length-bounds}
+-Wzero-length-bounds
+-Wzero-init-padding-bits=@var{value}}

  @item Static Analyzer Options
  @gccoptlist{
@@ -10973,6 +10974,88 @@ Suppress warnings when a positional
initializer is used to initialize
  a structure that has been marked with the @code{designated_init}
  attribute.

+@opindex Wzero-init-padding-bits=
+@item -Wzero-init-padding-bits=@var{value}
+Warn about automatic variable initializers that might not zero
+initialize padding bits.
+
+Certain languages guarantee zero initialization of padding bits in
+certain cases. The @code{-fzero-init-padding-bits=unions} and
+@code{-fzero-init-padding-bits=all} options provide additional
+guarantees that padding bits will be zero initialized in other
+circumstances.
+
+This warning is mainly intended to find source code that might need to
+be modified or else recompiled with
+@code{-fzero-init-padding-bits=unions} or
+@code{-fzero-init-padding-bits=all} in order to retain the behaviour
+that it had when compiled by versions of GCC older than 15. It can also

s/15/15.1/ based on other places which mention the specific version of gcc.

Done.

+be used to find code that might result in uninitialized struct padding
+unless GCC is invoked with @code{-fzero-init-padding-bits=all}
+(regardless of the fact that older versions of GCC would not have
+guaranteed initialization of struct padding either).
+
+It does not follow that all source code which causes warnings about
+uninitialized padding bits has undefined behaviour: usually, the values
s/behaviour/behavior/ That is the American spelling as mentioned on
https://gcc.gnu.org/codingconventions.html#Spelling .

Done.

+of padding bits have no effect on execution of a program.
+
+The two options interact as follows:
+
+@multitable @columnfractions 0.25 0.25 0.25 0.25
+@headitem @tab f:standard @tab f:unions @tab f:all
+@item W:standard @tab X @tab X @tab X
+@item W:unions @tab U @tab X @tab X
+@item W:all @tab A @tab S @tab X
+@end multitable
+
+@multitable @columnfractions .10 .90
+@headitem Letter @tab Meaning
+@item X @tab No warnings about padding bits.
+@item U @tab Warnings about padding bits of unions.
+@item S @tab Warnings about padding bits of structs.
+@item A @tab Warnings about padding bits of structs and unions.
+@end multitable
+
+Examples of union initialization for ISO C23 with
+@code{-fzero-init-padding-bits=standard} and
+@code{-Wzero-init-padding-bits=unions}:
+
+@smallexample
+  long long q;
+  unsigned char r;
+  union U @{ unsigned char a; long long b; @};
+  struct F @{ long long a; union U b; @};
+
+  // Padding bits are explicitly initialized
+  union U h = @{@};
+
+  // Padding bits might not be initialized
+  union U i = @{ r @};
+
+  // Padding bits might not be initialized
+  union U j = @{ .a = r @};
+
+  // Union is expected to have no padding bits
+  union U k = @{ .b = q @};
+
+  // Padding bits (of union) are explicitly initialized
+  struct F l = @{ q, @{@}, .b.a = r @};
+
+  // Padding bits (of union) might not be initialized
+  struct F m = @{ q, @{@}, .b = @{.a = r@} @};
+@end smallexample
+
+In the declaration of @code{m}, an empty initializer that would otherwise
+guarantee zero initialization of the padding bits of the union (i.e. storage
+allocated for member @code{b} that is not part of member @code{a}) is
+overridden by a subsequently listed initializer. This is an anti-pattern.
+
+Whether or not a given initializer causes a warning to be produced can be
+predicted for simple cases but in general it is target-dependent because the
+layout of storage is target-dependent. The level of optimisation, size, and

s/optimisation/optimization/ American spelling.

Done.

+initial value of the object being initialized also affect whether warnings are
+produced.
+
  @end table

  @node Static Analyzer Options
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 3815c565e2d..2e4442ff2f2 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -7101,7 +7101,8 @@ count_type_elements (const_tree type, bool for_ctor_p)
  static bool
  categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
                             HOST_WIDE_INT *p_unique_nz_elts,
-                           HOST_WIDE_INT *p_init_elts, int *p_complete)
+                           HOST_WIDE_INT *p_init_elts,
+                           ctor_completeness *p_complete)
  {
    unsigned HOST_WIDE_INT idx;
    HOST_WIDE_INT nz_elts, unique_nz_elts, init_elts, num_fields;
@@ -7228,34 +7229,38 @@ categorize_ctor_elements_1 (const_tree ctor,
HOST_WIDE_INT *p_nz_elts,
         }
      }

-  if (*p_complete && !complete_ctor_at_level_p (TREE_TYPE (ctor),
+  if (!p_complete->sparse && !complete_ctor_at_level_p (TREE_TYPE (ctor),
                                                 num_fields, elt_type))
-    *p_complete = 0;
+    p_complete->sparse = true;
    else if (TREE_CODE (TREE_TYPE (ctor)) == UNION_TYPE
            || TREE_CODE (TREE_TYPE (ctor)) == QUAL_UNION_TYPE)
      {
-      if (*p_complete
+      if (!p_complete->sparse
           && CONSTRUCTOR_ZERO_PADDING_BITS (ctor)
           && (num_fields
               ? simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)),
                                   TYPE_SIZE (elt_type)) != 1
               : type_has_padding_at_level_p (TREE_TYPE (ctor))))
-       *p_complete = 0;
-      else if (*p_complete > 0
+       {
+         p_complete->sparse = true;
+       }

The braces here are not needed and I think it is recommended not to use them.

Done.

+      else if (!p_complete->sparse && !p_complete->padded_union
                && (num_fields
                    ? simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)),
                                        TYPE_SIZE (elt_type)) != 1
                    : type_has_padding_at_level_p (TREE_TYPE (ctor))))
-       *p_complete = -1;
+       p_complete->padded_union = true;
      }
-  else if (*p_complete
+  else if (!p_complete->sparse
            && (CONSTRUCTOR_ZERO_PADDING_BITS (ctor)
                || flag_zero_init_padding_bits == ZERO_INIT_PADDING_BITS_ALL)
            && type_has_padding_at_level_p (TREE_TYPE (ctor)))
-    *p_complete = 0;
-  else if (*p_complete > 0
+    {
+      p_complete->sparse = true;
+    }

Likewise.

Done.

+  else if (!p_complete->sparse && !p_complete->padded_non_union
            && type_has_padding_at_level_p (TREE_TYPE (ctor)))
-    *p_complete = -1;
+    p_complete->padded_non_union = true;

    *p_nz_elts += nz_elts;
    *p_unique_nz_elts += unique_nz_elts;
@@ -7277,9 +7282,6 @@ categorize_ctor_elements_1 (const_tree ctor,
HOST_WIDE_INT *p_nz_elts,
     * whether the constructor is complete -- in the sense that every
       meaningful byte is explicitly given a value --
       and place it in *P_COMPLETE:
-     -  0 if any field is missing
-     -  1 if all fields are initialized, and there's no padding
-     - -1 if all fields are initialized, but there's padding

     Return whether or not CTOR is a valid static constant initializer, the same
     as "initializer_constant_valid_p (CTOR, TREE_TYPE (CTOR)) != 0".  */
@@ -7287,12 +7289,13 @@ categorize_ctor_elements_1 (const_tree ctor,
HOST_WIDE_INT *p_nz_elts,
  bool
  categorize_ctor_elements (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
                           HOST_WIDE_INT *p_unique_nz_elts,
-                         HOST_WIDE_INT *p_init_elts, int *p_complete)
+                         HOST_WIDE_INT *p_init_elts,
+                         ctor_completeness *p_complete)
  {
    *p_nz_elts = 0;
    *p_unique_nz_elts = 0;
    *p_init_elts = 0;
-  *p_complete = 1;
+  *p_complete = {};

    return categorize_ctor_elements_1 (ctor, p_nz_elts, p_unique_nz_elts,
                                      p_init_elts, p_complete);
@@ -7366,11 +7369,11 @@ mostly_zeros_p (const_tree exp)
    if (TREE_CODE (exp) == CONSTRUCTOR)
      {
        HOST_WIDE_INT nz_elts, unz_elts, init_elts;
-      int complete_p;
+      ctor_completeness complete_p;

        categorize_ctor_elements (exp, &nz_elts, &unz_elts, &init_elts,
                                 &complete_p);
-      return !complete_p || nz_elts < init_elts / 4;
+      return complete_p.sparse || nz_elts < init_elts / 4;
      }

    return initializer_zerop (exp);
@@ -7384,7 +7387,7 @@ all_zeros_p (const_tree exp)
    if (TREE_CODE (exp) == CONSTRUCTOR)
      {
        HOST_WIDE_INT nz_elts, unz_elts, init_elts;
-      int complete_p;
+      ctor_completeness complete_p;

        categorize_ctor_elements (exp, &nz_elts, &unz_elts, &init_elts,
                                 &complete_p);
diff --git a/gcc/expr.h b/gcc/expr.h
index 53ab625787e..a31cdcd54b7 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -359,9 +359,14 @@ extern bool can_move_by_pieces (unsigned
HOST_WIDE_INT, unsigned int);

  extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree);

+struct ctor_completeness
+{
+  bool sparse:1, padded_non_union:1, padded_union:1;

Formatting. I think we specify each field on its own line.
Would be useful to have a comment on what each field means.

Done.

I have been wondering whether this should actually have been an enum. Having thought about it for the first time in many months, I think I decided on bit fields because I didn't want the function that computes a ctor_completeness value to make any assumptions about whether padding in unions is more or less important than padding in other types.

It is only a little strange that padded_non_union and padded_union may not be set at all (despite a constructor satisfying the corresponding conditions) if the sparse bit is set for that constructor first. I did not want to risk making changes to the control logic that might not be easily verifiable and might harm compilation efficiency.

+};
+
  extern bool categorize_ctor_elements (const_tree, HOST_WIDE_INT *,
                                       HOST_WIDE_INT *, HOST_WIDE_INT *,
-                                     int *);
+                                     ctor_completeness *);
  extern bool type_has_padding_at_level_p (tree);
  extern bool immediate_const_ctor_p (const_tree, unsigned int words = 1);
  extern void store_constructor (tree, rtx, int, poly_int64, bool);
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 4f385b1b779..daf5ce30724 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -6360,7 +6360,7 @@ gimplify_init_constructor (tree *expr_p,
gimple_seq *pre_p, gimple_seq *post_p,
         struct gimplify_init_ctor_preeval_data preeval_data;
         HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
         HOST_WIDE_INT num_unique_nonzero_elements;
-       int complete_p;
+       ctor_completeness complete_p;
         bool valid_const_initializer;

         /* Aggregate types must lower constructors to initialization of
@@ -6445,7 +6445,7 @@ gimplify_init_constructor (tree *expr_p,
gimple_seq *pre_p, gimple_seq *post_p,
              objects.  Initializers for such objects must explicitly set
              every field that needs to be set.  */
           cleared = false;
-       else if (!complete_p)
+       else if (complete_p.sparse)
           /* If the constructor isn't complete, clear the whole object
              beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.

@@ -6470,7 +6470,8 @@ gimplify_init_constructor (tree *expr_p,
gimple_seq *pre_p, gimple_seq *post_p,
            That will avoid wasting cycles preserving any padding bits
            that might be there, and if there aren't any, the compiler
            is smart enough to optimize the clearing out.  */
-       else if (complete_p <= 0
+       else if ((complete_p.sparse || complete_p.padded_union
+                 || complete_p.padded_non_union)
                  && !TREE_ADDRESSABLE (ctor)
                  && !TREE_THIS_VOLATILE (object)
                  && (TYPE_MODE (type) != BLKmode || TYPE_NO_FORCE_BLK (type))
@@ -6489,7 +6490,7 @@ gimplify_init_constructor (tree *expr_p,
gimple_seq *pre_p, gimple_seq *post_p,
            clearing), and don't try to make bitwise copies of
            TREE_ADDRESSABLE types.  */
         if (valid_const_initializer
-           && complete_p
+           && !complete_p.sparse
             && !(cleared || num_nonzero_elements == 0)
             && !TREE_ADDRESSABLE (type))
           {
@@ -6544,6 +6545,24 @@ gimplify_init_constructor (tree *expr_p,
gimple_seq *pre_p, gimple_seq *post_p,
               }
           }

+       if (!cleared)
+         {
+           if (complete_p.padded_non_union
+               && warn_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_ALL)
+               warning (OPT_Wzero_init_padding_bits_,
+                        "padding might not be initialized to zero; "
+                        "if code relies on it being zero, consider "
+                        "using %<-fzero-init-padding-bits=all%>");
+           else if (complete_p.padded_union
+                    && warn_zero_init_padding_bits
+                       >= ZERO_INIT_PADDING_BITS_UNIONS)
+               warning (OPT_Wzero_init_padding_bits_,
+                        "padding might not be initialized to zero; "
+                        "if code relies on it being zero, consider "
+                        "using %<-fzero-init-padding-bits=unions%> "
+                        "or %<-fzero-init-padding-bits=all%>");
+         }
+

Ok from me with those changes.

Thank you. I'll push v5 later today, with the changes that you requested.

Richard,
   This was submitted back in May of last year and had already 3 other
versions with reviews but this version was not reviewed until today .
Should we wait for GCC 17 stage 1 for this or is this ok now?

Thanks,
Andrew Pinski
It does seem a bit odd from a user perspective to delay introducing warnings that are designed to mitigate the risk of a change in GCC 15 until GCC 17. Other than that, I don't feel strongly.

--
Christopher Bazley
Staff Software Engineer, GNU Tools Team.
Arm Ltd, 110 Fulbourn Road, Cambridge, CB1 9NJ, UK.
http://www.arm.com/

Reply via email to