From a0eae2ab7b45d22d67487279564f604206149143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 19 Mar 2026 11:35:00 +0100 Subject: [PATCH 1/3] Stop disabling -Wattributes In one of the reviews one of the LLMs noticed that the pragma is set but never unset, so it remains in effect for the rest of the translation unit. From the comment, it's not clear how old those "old compilers" were, so let's try if things work without this workaround. --- src/basic/static-destruct.h | 2 -- src/libsystemd/sd-bus/bus-error.h | 4 +--- src/shared/tests.h | 1 - 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/basic/static-destruct.h b/src/basic/static-destruct.h index 5772d24240..00087ad779 100644 --- a/src/basic/static-destruct.h +++ b/src/basic/static-destruct.h @@ -12,8 +12,6 @@ typedef void (*free_func_t)(void *p); * variables declared in .so's, as the list is private to the same linking unit. But maybe that's a good thing. */ #define _common_static_destruct_attrs_ \ - /* Older compilers don't know "retain" attribute. */ \ - _Pragma("GCC diagnostic ignored \"-Wattributes\"") \ /* The actual destructor structure we place in a special section to find it. */ \ _section_("SYSTEMD_STATIC_DESTRUCT") \ /* Use pointer alignment, since that is apparently what gcc does for static variables. */ \ diff --git a/src/libsystemd/sd-bus/bus-error.h b/src/libsystemd/sd-bus/bus-error.h index ac3c90c0d3..5aca67f006 100644 --- a/src/libsystemd/sd-bus/bus-error.h +++ b/src/libsystemd/sd-bus/bus-error.h @@ -31,12 +31,10 @@ const char* _bus_error_message(const sd_bus_error *e, int error, char buf[static * the error map is really added to the final binary. * * In addition, set the retain attribute so that the section cannot be - * discarded by ld --gc-sections -z start-stop-gc. Older compilers would - * warn for the unknown attribute, so just disable -Wattributes. + * discarded by ld --gc-sections -z start-stop-gc. */ #define BUS_ERROR_MAP_ELF_REGISTER \ - _Pragma("GCC diagnostic ignored \"-Wattributes\"") \ _section_("SYSTEMD_BUS_ERROR_MAP") \ _used_ \ _retain_ \ diff --git a/src/shared/tests.h b/src/shared/tests.h index ae57cab386..4e1bfad86d 100644 --- a/src/shared/tests.h +++ b/src/shared/tests.h @@ -101,7 +101,6 @@ typedef struct TestFunc { /* See static-destruct.h for an explanation of how this works. */ #define REGISTER_TEST(func, ...) \ - _Pragma("GCC diagnostic ignored \"-Wattributes\"") \ _section_("SYSTEMD_TEST_TABLE") _alignptr_ _used_ _retain_ _variable_no_sanitize_address_ \ static const TestFunc UNIQ_T(static_test_table_entry, UNIQ) = { \ .f = (union f) &(func), \ From fabc22f5998e610eb7ba70a963cab9f94dca5c0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 19 Mar 2026 17:06:17 +0100 Subject: [PATCH 2/3] meson: disable __attribute__((__retain__)) on old compilers This attribute was introduced in gcc 11, and our baseline is currently 8.4. So let's allow using _retain_ everywhere, but make it into a noop if not supported. Using __has_attribute was suggested, but with gcc-11.5.0-14.el9.x86_64, __has__attribute(__retain__) is true, but we get a warning when the attribute is actually used. --- meson.build | 6 ++++++ src/boot/meson.build | 7 +++++-- src/fundamental/macro-fundamental.h | 7 ++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/meson.build b/meson.build index 3672005d75..c52f8e17c2 100644 --- a/meson.build +++ b/meson.build @@ -524,6 +524,12 @@ if cc.compiles(''' add_project_arguments('-Werror=shadow', language : 'c') endif +have = cc.compiles( + '__attribute__((__retain__)) int x;', + args : '-Werror=attributes', + name : '__attribute__((__retain__))') +conf.set10('HAVE_ATTRIBUTE_RETAIN', have) + if cxx_cmd != '' add_project_arguments(cxx.get_supported_arguments(basic_disabled_warnings), language : 'cpp') endif diff --git a/src/boot/meson.build b/src/boot/meson.build index 06c8146a9e..c51510e96f 100644 --- a/src/boot/meson.build +++ b/src/boot/meson.build @@ -80,8 +80,11 @@ endif efi_conf = configuration_data() # import several configs from userspace -foreach name : ['HAVE_WARNING_ZERO_LENGTH_BOUNDS', 'HAVE_WARNING_ZERO_AS_NULL_POINTER_CONSTANT'] - efi_conf.set10(name, conf.get(name) == 1) +foreach name : ['HAVE_ATTRIBUTE_RETAIN', + 'HAVE_WARNING_ZERO_AS_NULL_POINTER_CONSTANT', + 'HAVE_WARNING_ZERO_LENGTH_BOUNDS', + ] + efi_conf.set(name, conf.get(name)) endforeach efi_conf.set10('ENABLE_TPM', get_option('tpm')) diff --git a/src/fundamental/macro-fundamental.h b/src/fundamental/macro-fundamental.h index e8757b1fc3..39004183d9 100644 --- a/src/fundamental/macro-fundamental.h +++ b/src/fundamental/macro-fundamental.h @@ -88,7 +88,6 @@ #define _printf_(a, b) __attribute__((__format__(printf, a, b))) #define _public_ __attribute__((__visibility__("default"))) #define _pure_ __attribute__((__pure__)) -#define _retain_ __attribute__((__retain__)) #define _returns_nonnull_ __attribute__((__returns_nonnull__)) #define _section_(x) __attribute__((__section__(x))) #define _sentinel_ __attribute__((__sentinel__)) @@ -99,6 +98,12 @@ #define _weak_ __attribute__((__weak__)) #define _weakref_(x) __attribute__((__weakref__(#x))) +#if HAVE_ATTRIBUTE_RETAIN +# define _retain_ __attribute__((__retain__)) +#else +# define _retain_ +#endif + #ifdef __clang__ # define _alloc_(...) #else From 7e14d3b979d3ec51d42b10ffa0561a3c4b3e7dd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 20 Mar 2026 09:50:27 +0100 Subject: [PATCH 3/3] boot: inline a single-use variable Also, in general we prefer variables that are always defined over checking with #ifdef, so #if defined(HAVE_NO_STACK_PROTECTOR_ATTRIBUTE) is something that we want to avoid. --- src/boot/efi-log.h | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/boot/efi-log.h b/src/boot/efi-log.h index 5458f90109..5dbcb42516 100644 --- a/src/boot/efi-log.h +++ b/src/boot/efi-log.h @@ -5,15 +5,12 @@ #include "efi-string.h" #include "proto/simple-text-io.h" /* IWYU pragma: keep */ -#if defined __has_attribute -# if __has_attribute(no_stack_protector) -# define HAVE_NO_STACK_PROTECTOR_ATTRIBUTE -# endif -#endif - -#if defined(HAVE_NO_STACK_PROTECTOR_ATTRIBUTE) && \ - (defined(__SSP__) || defined(__SSP_ALL__) || \ - defined(__SSP_STRONG__) || defined(__SSP_EXPLICIT__)) +#if defined(__has_attribute) && \ + __has_attribute(no_stack_protector) && \ + (defined(__SSP__) || \ + defined(__SSP_ALL__) || \ + defined(__SSP_STRONG__) || \ + defined(__SSP_EXPLICIT__)) # define STACK_PROTECTOR_RANDOM 1 __attribute__((no_stack_protector, noinline)) void __stack_chk_guard_init(void); #else