Use a simpler scheme to pacify GCC.
* lib/careadlinkat.c (readlink_stk): With GCC 12+,
do not ignore -Wreturn-local-addr if -flto is being used,
as this does not work with current coreutils and with
gcc 16.1.1 20260501 (Red Hat 16.1.1-1) x86-64.
Instead, fall back on __attribute__ ((__noinline__)).
(GCC_BOGUS_WRETURN_LOCAL_ADDR): Remove.  Do not bother
with this as it complicates maintenance and is present only
for better diagnostics in older compilers.
Just use __attribute__ ((__noinline__)) instead.
All uses removed.
---
 ChangeLog          | 15 +++++++++++++++
 lib/careadlinkat.c | 24 ++++++++++--------------
 2 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 38d6fdc0f8..b72794c0f1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2026-05-10  Paul Eggert  <[email protected]>
+
+       careadlinkat: pacify GCC 16 -flto
+       Use a simpler scheme to pacify GCC.
+       * lib/careadlinkat.c (readlink_stk): With GCC 12+,
+       do not ignore -Wreturn-local-addr if -flto is being used,
+       as this does not work with current coreutils and with
+       gcc 16.1.1 20260501 (Red Hat 16.1.1-1) x86-64.
+       Instead, fall back on __attribute__ ((__noinline__)).
+       (GCC_BOGUS_WRETURN_LOCAL_ADDR): Remove.  Do not bother
+       with this as it complicates maintenance and is present only
+       for better diagnostics in older compilers.
+       Just use __attribute__ ((__noinline__)) instead.
+       All uses removed.
+
 2026-05-10  Paul Eggert  <[email protected]>
 
        chown: use AC_CHECK_HEADERS_ONCE on standard headers
diff --git a/lib/careadlinkat.c b/lib/careadlinkat.c
index fa19e09986..d9c27ed4f0 100644
--- a/lib/careadlinkat.c
+++ b/lib/careadlinkat.c
@@ -42,22 +42,22 @@ enum { STACK_BUF_SIZE = 1024 };
 /* Act like careadlinkat (see below), with an additional argument
    STACK_BUF that can be used as temporary storage.
 
-   If GCC_LINT is defined, do not inline this function with GCC 10.1
-   and later, to avoid creating a pointer to the stack that GCC
+   Suppress -Wreturn-local-addr false alarms, as follows.
+   If GCC 12+ and -flto is not being used (in which case -DUSING_LTO
+   should also be used), simply use a pragma.
+   Otherwise, in GCC 10+, do not inline this function
+   to avoid creating a pointer to the stack that
    -Wreturn-local-addr incorrectly complains about.  See:
    https://gcc.gnu.org/PR93644
    Although the noinline attribute can hurt performance a bit, no better way
-   to pacify GCC is known; even an explicit #pragma does not pacify GCC.
+   to pacify GCC is known; even an explicit #pragma does not pacify GCC
+   10 or 11, or GCC 12+ with -flto.
    When the GCC bug is fixed this workaround should be limited to the
    broken GCC versions.  */
-#if _GL_GNUC_PREREQ (10, 1)
-# if _GL_GNUC_PREREQ (12, 1)
-#  pragma GCC diagnostic ignored "-Wreturn-local-addr"
-# elif defined GCC_LINT || defined lint
+#if _GL_GNUC_PREREQ (12, 1) && !USING_LTO
+# pragma GCC diagnostic ignored "-Wreturn-local-addr"
+#elif _GL_GNUC_PREREQ (10, 1)
 __attribute__ ((__noinline__))
-# elif __OPTIMIZE__ && !__NO_INLINE__
-#  define GCC_BOGUS_WRETURN_LOCAL_ADDR
-# endif
 #endif
 static char *
 readlink_stk (int fd, char const *filename,
@@ -172,10 +172,6 @@ careadlinkat (int fd, char const *filename,
      common case of a symlink of small size, we get away with a
      single small malloc instead of a big malloc followed by a
      shrinking realloc.  */
-  #ifdef GCC_BOGUS_WRETURN_LOCAL_ADDR
-   #warning "GCC might issue a bogus -Wreturn-local-addr warning here."
-   #warning "See <https://gcc.gnu.org/PR93644>."
-  #endif
   char stack_buf[STACK_BUF_SIZE];
   return readlink_stk (fd, filename, buffer, buffer_size, alloc,
                        preadlinkat, stack_buf);
-- 
2.54.0


Reply via email to