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 option. 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). Bootstrapped the compiler and tested on AArch64 and x86-64 using some new tests for -Wzero-init-padding-bits and the existing tests for -fzero-init-padding-bits (check-gcc RUNTESTFLAGS="dg.exp=*-empty-init-*.c"). Base commit is a470433732e77ae29a717cf79049ceeea3cbe979 Changes in v2: - Added missing changelog entry. Changes in v3: - Modified two tests in which I had neglected to ensure that initializers were not compile time constants. This policy prevents the entire initializer being dropped to memory, which would otherwise prevent the expected diagnostic message from being produced. - Amended the diagnostic message from "Padding bits might not.." to "padding might not..." Changes in v4: - Removed redundant braces. - Added "if code relies on it being zero," to the diagnostic message. Link to v1: https://inbox.sourceware.org/gcc-patches/20250520104940.3546-1-chris.baz...@arm.com/ Link to v2: https://inbox.sourceware.org/gcc-patches/20250520144524.5968-1-chris.baz...@arm.com/ Link to v3: https://inbox.sourceware.org/gcc-patches/20250521124745.24592-1-chris.baz...@arm.com/ Christopher Bazley (1): Add warnings of potentially-uninitialized padding bits 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 -- 2.43.0