mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 15:03:53 +02:00

GCC 15 introduces a regression in "= { 0 }" style initialization of
unions that Linux has depended on for eliminating uninitialized variable
contents. GCC does not seem likely to fix it[1], instead suggesting[2]
that affected projects start using -fzero-init-padding-bits=unions.
To avoid future surprises beyond just the current situation with unions,
enable -fzero-init-padding-bits=all when available (GCC 15+). This will
correctly zero padding bits in unions and structs that might have been
left uninitialized, and will make sure there is no immediate regression
in union initializations. As seen in the stackinit KUnit selftest union
cases, which were passing before, were failing under GCC 15:
not ok 18 test_small_start_old_zero
ok 29 test_small_start_dynamic_partial # SKIP XFAIL uninit bytes: 63
ok 32 test_small_start_assigned_dynamic_partial # SKIP XFAIL uninit bytes: 63
ok 67 test_small_start_static_partial # SKIP XFAIL uninit bytes: 63
ok 70 test_small_start_static_all # SKIP XFAIL uninit bytes: 56
ok 73 test_small_start_dynamic_all # SKIP XFAIL uninit bytes: 56
ok 82 test_small_start_assigned_static_partial # SKIP XFAIL uninit bytes: 63
ok 85 test_small_start_assigned_static_all # SKIP XFAIL uninit bytes: 56
ok 88 test_small_start_assigned_dynamic_all # SKIP XFAIL uninit bytes: 56
The above all now pass again with -fzero-init-padding-bits=all added.
This also fixes the following cases for struct initialization that had
been XFAIL until now because there was no compiler support beyond the
larger "-ftrivial-auto-var-init=zero" option:
ok 38 test_small_hole_static_all # SKIP XFAIL uninit bytes: 3
ok 39 test_big_hole_static_all # SKIP XFAIL uninit bytes: 124
ok 40 test_trailing_hole_static_all # SKIP XFAIL uninit bytes: 7
ok 42 test_small_hole_dynamic_all # SKIP XFAIL uninit bytes: 3
ok 43 test_big_hole_dynamic_all # SKIP XFAIL uninit bytes: 124
ok 44 test_trailing_hole_dynamic_all # SKIP XFAIL uninit bytes: 7
ok 58 test_small_hole_assigned_static_all # SKIP XFAIL uninit bytes: 3
ok 59 test_big_hole_assigned_static_all # SKIP XFAIL uninit bytes: 124
ok 60 test_trailing_hole_assigned_static_all # SKIP XFAIL uninit bytes: 7
ok 62 test_small_hole_assigned_dynamic_all # SKIP XFAIL uninit bytes: 3
ok 63 test_big_hole_assigned_dynamic_all # SKIP XFAIL uninit bytes: 124
ok 64 test_trailing_hole_assigned_dynamic_all # SKIP XFAIL uninit bytes: 7
All of the above now pass when built under GCC 15. Tests can be seen
with:
./tools/testing/kunit/kunit.py run stackinit --arch=x86_64 \
--make_option CC=gcc-15
Clang continues to fully initialize these kinds of variables[3] without
additional flags.
Suggested-by: Jakub Jelinek <jakub@redhat.com>
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118403 [1]
Link: https://lore.kernel.org/linux-toolchains/Z0hRrrNU3Q+ro2T7@tucnak/ [2]
Link: 7a086e1b2d
[3]
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
Acked-by: Masahiro Yamada <masahiroy@kernel.org>
Link: https://lore.kernel.org/r/20250127191031.245214-3-kees@kernel.org
Signed-off-by: Kees Cook <kees@kernel.org>
200 lines
6.6 KiB
Makefile
200 lines
6.6 KiB
Makefile
# SPDX-License-Identifier: GPL-2.0
|
|
# ==========================================================================
|
|
# make W=... settings
|
|
#
|
|
# There are four warning groups enabled by W=1, W=2, W=3, and W=e
|
|
# They are independent, and can be combined like W=12 or W=123e.
|
|
# ==========================================================================
|
|
|
|
# Default set of warnings, always enabled
|
|
KBUILD_CFLAGS += -Wall
|
|
KBUILD_CFLAGS += -Wundef
|
|
KBUILD_CFLAGS += -Werror=implicit-function-declaration
|
|
KBUILD_CFLAGS += -Werror=implicit-int
|
|
KBUILD_CFLAGS += -Werror=return-type
|
|
KBUILD_CFLAGS += -Werror=strict-prototypes
|
|
KBUILD_CFLAGS += -Wno-format-security
|
|
KBUILD_CFLAGS += -Wno-trigraphs
|
|
KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,)
|
|
KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member)
|
|
KBUILD_CFLAGS += -Wmissing-declarations
|
|
KBUILD_CFLAGS += -Wmissing-prototypes
|
|
|
|
ifneq ($(CONFIG_FRAME_WARN),0)
|
|
KBUILD_CFLAGS += -Wframe-larger-than=$(CONFIG_FRAME_WARN)
|
|
endif
|
|
|
|
KBUILD_CPPFLAGS-$(CONFIG_WERROR) += -Werror
|
|
KBUILD_CPPFLAGS += $(KBUILD_CPPFLAGS-y)
|
|
KBUILD_CFLAGS-$(CONFIG_CC_NO_ARRAY_BOUNDS) += -Wno-array-bounds
|
|
|
|
ifdef CONFIG_CC_IS_CLANG
|
|
# The kernel builds with '-std=gnu11' so use of GNU extensions is acceptable.
|
|
KBUILD_CFLAGS += -Wno-gnu
|
|
else
|
|
|
|
# gcc inanely warns about local variables called 'main'
|
|
KBUILD_CFLAGS += -Wno-main
|
|
endif
|
|
|
|
# These result in bogus false positives
|
|
KBUILD_CFLAGS += $(call cc-disable-warning, dangling-pointer)
|
|
|
|
# Variable Length Arrays (VLAs) should not be used anywhere in the kernel
|
|
KBUILD_CFLAGS += -Wvla
|
|
|
|
# disable pointer signed / unsigned warnings in gcc 4.0
|
|
KBUILD_CFLAGS += -Wno-pointer-sign
|
|
|
|
# In order to make sure new function cast mismatches are not introduced
|
|
# in the kernel (to avoid tripping CFI checking), the kernel should be
|
|
# globally built with -Wcast-function-type.
|
|
KBUILD_CFLAGS += $(call cc-option, -Wcast-function-type)
|
|
|
|
# The allocators already balk at large sizes, so silence the compiler
|
|
# warnings for bounds checks involving those possible values. While
|
|
# -Wno-alloc-size-larger-than would normally be used here, earlier versions
|
|
# of gcc (<9.1) weirdly don't handle the option correctly when _other_
|
|
# warnings are produced (?!). Using -Walloc-size-larger-than=SIZE_MAX
|
|
# doesn't work (as it is documented to), silently resolving to "0" prior to
|
|
# version 9.1 (and producing an error more recently). Numeric values larger
|
|
# than PTRDIFF_MAX also don't work prior to version 9.1, which are silently
|
|
# ignored, continuing to default to PTRDIFF_MAX. So, left with no other
|
|
# choice, we must perform a versioned check to disable this warning.
|
|
# https://lore.kernel.org/lkml/20210824115859.187f272f@canb.auug.org.au
|
|
KBUILD_CFLAGS-$(call gcc-min-version, 90100) += -Wno-alloc-size-larger-than
|
|
KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH)
|
|
|
|
# Prohibit date/time macros, which would make the build non-deterministic
|
|
KBUILD_CFLAGS += -Werror=date-time
|
|
|
|
# enforce correct pointer usage
|
|
KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types)
|
|
|
|
# Require designated initializers for all marked structures
|
|
KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init)
|
|
|
|
# Warn if there is an enum types mismatch
|
|
KBUILD_CFLAGS += $(call cc-option,-Wenum-conversion)
|
|
|
|
# Explicitly clear padding bits during variable initialization
|
|
KBUILD_CFLAGS += $(call cc-option,-fzero-init-padding-bits=all)
|
|
|
|
KBUILD_CFLAGS += -Wextra
|
|
KBUILD_CFLAGS += -Wunused
|
|
|
|
#
|
|
# W=1 - warnings which may be relevant and do not occur too often
|
|
#
|
|
ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),)
|
|
|
|
KBUILD_CFLAGS += -Wmissing-format-attribute
|
|
KBUILD_CFLAGS += -Wmissing-include-dirs
|
|
KBUILD_CFLAGS += $(call cc-option, -Wunused-const-variable)
|
|
|
|
KBUILD_CPPFLAGS += -Wundef
|
|
KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1
|
|
|
|
else
|
|
|
|
# Some diagnostics enabled by default are noisy.
|
|
# Suppress them by using -Wno... except for W=1.
|
|
KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
|
|
KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable)
|
|
KBUILD_CFLAGS += $(call cc-disable-warning, packed-not-aligned)
|
|
KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow)
|
|
ifdef CONFIG_CC_IS_GCC
|
|
KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation)
|
|
else
|
|
# Clang checks for overflow/truncation with '%p', while GCC does not:
|
|
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111219
|
|
KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow-non-kprintf)
|
|
KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation-non-kprintf)
|
|
endif
|
|
KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation)
|
|
|
|
KBUILD_CFLAGS += -Wno-override-init # alias for -Wno-initializer-overrides in clang
|
|
|
|
ifdef CONFIG_CC_IS_CLANG
|
|
# Clang before clang-16 would warn on default argument promotions.
|
|
ifneq ($(call clang-min-version, 160000),y)
|
|
# Disable -Wformat
|
|
KBUILD_CFLAGS += -Wno-format
|
|
# Then re-enable flags that were part of the -Wformat group that aren't
|
|
# problematic.
|
|
KBUILD_CFLAGS += -Wformat-extra-args -Wformat-invalid-specifier
|
|
KBUILD_CFLAGS += -Wformat-zero-length -Wnonnull
|
|
# Requires clang-12+.
|
|
ifeq ($(call clang-min-version, 120000),y)
|
|
KBUILD_CFLAGS += -Wformat-insufficient-args
|
|
endif
|
|
endif
|
|
KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast)
|
|
KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare
|
|
KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access)
|
|
KBUILD_CFLAGS += -Wno-enum-compare-conditional
|
|
KBUILD_CFLAGS += -Wno-enum-enum-conversion
|
|
endif
|
|
|
|
endif
|
|
|
|
#
|
|
# W=2 - warnings which occur quite often but may still be relevant
|
|
#
|
|
ifneq ($(findstring 2, $(KBUILD_EXTRA_WARN)),)
|
|
|
|
KBUILD_CFLAGS += -Wdisabled-optimization
|
|
KBUILD_CFLAGS += -Wshadow
|
|
KBUILD_CFLAGS += $(call cc-option, -Wlogical-op)
|
|
KBUILD_CFLAGS += $(call cc-option, -Wunused-macros)
|
|
|
|
KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN2
|
|
|
|
else
|
|
|
|
# The following turn off the warnings enabled by -Wextra
|
|
KBUILD_CFLAGS += -Wno-missing-field-initializers
|
|
KBUILD_CFLAGS += -Wno-type-limits
|
|
KBUILD_CFLAGS += -Wno-shift-negative-value
|
|
|
|
ifdef CONFIG_CC_IS_GCC
|
|
KBUILD_CFLAGS += -Wno-maybe-uninitialized
|
|
endif
|
|
|
|
endif
|
|
|
|
#
|
|
# W=3 - more obscure warnings, can most likely be ignored
|
|
#
|
|
ifneq ($(findstring 3, $(KBUILD_EXTRA_WARN)),)
|
|
|
|
KBUILD_CFLAGS += -Wbad-function-cast
|
|
KBUILD_CFLAGS += -Wcast-align
|
|
KBUILD_CFLAGS += -Wcast-qual
|
|
KBUILD_CFLAGS += -Wconversion
|
|
KBUILD_CFLAGS += -Wpacked
|
|
KBUILD_CFLAGS += -Wpadded
|
|
KBUILD_CFLAGS += -Wpointer-arith
|
|
KBUILD_CFLAGS += -Wredundant-decls
|
|
KBUILD_CFLAGS += -Wsign-compare
|
|
KBUILD_CFLAGS += -Wswitch-default
|
|
|
|
KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN3
|
|
|
|
else
|
|
|
|
# The following turn off the warnings enabled by -Wextra
|
|
KBUILD_CFLAGS += -Wno-sign-compare
|
|
KBUILD_CFLAGS += -Wno-unused-parameter
|
|
|
|
endif
|
|
|
|
#
|
|
# W=e - error out on warnings
|
|
#
|
|
ifneq ($(findstring e, $(KBUILD_EXTRA_WARN)),)
|
|
|
|
KBUILD_CFLAGS += -Werror
|
|
|
|
endif
|