features.h: do not consider _GNU_SOURCE for gets

Message ID 20260815222047.1510706-1-arsen@aarsen.me (mailing list archive)
State New
Delegated to: Florian Weimer
Headers
Series features.h: do not consider _GNU_SOURCE for gets |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Build passed
redhat-pt-bot/TryBot-32bit success Build for i686
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Test passed

Commit Message

Arsen Arsenović Aug. 15, 2026, 10:18 p.m. UTC
  Currently, -std=c99 -D_GNU_SOURCE and similar lack the 'gets'
declaration.

This causes, say, programs using the:

  extern __typeof__ (gets) function __attribute__ ((__warning__ (...)))

... trick to add warnings to 'gets' use to break.  (_GL_WARN_ON_USE in
gnulib).

The decision not to declare 'gets' w/ _GNU_SOURCE is clearly intended
(see c3a87236702cb73be1dada3438bbd3c3934e83f8), but I don't see the
benefit in it (given that we already emit a diagnostic), and, as noted,
it does cause certain older versions of Gnulib to fail to compile
(which, in turn, causes multiple packages to fail to compile while
building), and no rationale was provided in the commit message.

It was not unreasonable for programs to assume that _GNU_SOURCE does not
remove declarations, I think.

So, let's keep it in -std=gnu99/c99 -D_GNU_SOURCE instead.

One test needed to ignore the 'gets' deprecation now, since it became
exposed to the deprecated declaration.
---
Tested on x86_64-linux-gnu.

Four failures that seem to be definitely unrelated (the GDB ones are a
GDB crash, the malloc one is a timeout, and tst-pthread-exited seems to
get EPERMs for some reason):

  ~/gnu/glibc/glibc/_b$ grep ^FAIL tests.sum
  FAIL: malloc/tst-malloc-tcache-leak-malloc-largetcache
  FAIL: nptl/tst-pthread-exited
  FAIL: nptl/tst-pthread-gdb-attach
  FAIL: nptl/tst-pthread-gdb-attach-static

I'd debug this normally, but it's getting late..

 include/features.h | 4 +++-
 libio/Makefile     | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)
  

Comments

Sam James Aug. 16, 2026, 12:01 a.m. UTC | #1
Arsen Arsenović <arsen@aarsen.me> writes:

> Currently, -std=c99 -D_GNU_SOURCE and similar lack the 'gets'
> declaration.
>
> This causes, say, programs using the:
>
>   extern __typeof__ (gets) function __attribute__ ((__warning__ (...)))
>
> ... trick to add warnings to 'gets' use to break.  (_GL_WARN_ON_USE in
> gnulib).
>
> The decision not to declare 'gets' w/ _GNU_SOURCE is clearly intended
> (see c3a87236702cb73be1dada3438bbd3c3934e83f8), but I don't see the
> benefit in it (given that we already emit a diagnostic), and, as noted,
> it does cause certain older versions of Gnulib to fail to compile
> (which, in turn, causes multiple packages to fail to compile while
> building), and no rationale was provided in the commit message.

Interestingly, nobody questioned it in the followup at
https://inbox.sourceware.org/libc-alpha/20170216151151.9E56214B9D@panix1.panix.com/
and indeed nobody really argued in
https://inbox.sourceware.org/libc-alpha/CAOPLpQeb2HAkBVmoyOVrTsHtT6tG2ECEMBrK74zZV0Xw2243yg@mail.gmail.com/
either.

I feel like I've seen some discussion of this over the years but I can't
find it now, so maybe imagined it.

>
> It was not unreasonable for programs to assume that _GNU_SOURCE does not
> remove declarations, I think.

I agree that it's rather counterintuitive. I think adding (even
aggressive) warnings is arguably in scope for _GNU_SOURCE but outright
hiding a fnuction isn't.

It encourages people to redefine it incorrectly anyway and I'd argue is
harmful in getting people to use feature test macros correctly.

>
> So, let's keep it in -std=gnu99/c99 -D_GNU_SOURCE instead.
>
> One test needed to ignore the 'gets' deprecation now, since it became
> exposed to the deprecated declaration.
> ---
> Tested on x86_64-linux-gnu.
>
> Four failures that seem to be definitely unrelated (the GDB ones are a
> GDB crash, the malloc one is a timeout, and tst-pthread-exited seems to
> get EPERMs for some reason):
>
>   ~/gnu/glibc/glibc/_b$ grep ^FAIL tests.sum
>   FAIL: malloc/tst-malloc-tcache-leak-malloc-largetcache
>   FAIL: nptl/tst-pthread-exited
>   FAIL: nptl/tst-pthread-gdb-attach
>   FAIL: nptl/tst-pthread-gdb-attach-static
>
> I'd debug this normally, but it's getting late..
>
>  include/features.h | 4 +++-
>  libio/Makefile     | 2 +-
>  2 files changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/include/features.h b/include/features.h
> index b3277f342cd6..a3f483fa7869 100644
> --- a/include/features.h
> +++ b/include/features.h
> @@ -475,7 +475,9 @@
>     safely.  It has been removed from ISO C11 and ISO C++14.  Note: for
>     compatibility with various implementations of <cstdio>, this test
>     must consider only the value of __cplusplus when compiling C++.  */
> -#if defined __cplusplus ? __cplusplus >= 201402L : defined __USE_ISOC11
> +#if (defined __cplusplus			\
> +     ? __cplusplus >= 201402L			\
> +     : (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L))
>  # define __GLIBC_USE_DEPRECATED_GETS 0
>  #else
>  # define __GLIBC_USE_DEPRECATED_GETS 1
> diff --git a/libio/Makefile b/libio/Makefile
> index 616107ee105b..836a9dbb70d4 100644
> --- a/libio/Makefile
> +++ b/libio/Makefile
> @@ -258,7 +258,7 @@ CFLAGS-oldtmpfile.c += -fexceptions
>  
>  # Prevent fortification as these are built with -O0
>  CFLAGS-tst-bz24051.c += $(no-fortify-source)
> -CFLAGS-tst-bz24153.c += $(no-fortify-source)
> +CFLAGS-tst-bz24153.c += $(no-fortify-source) -Wno-deprecated-declarations
>  
>  CFLAGS-tst_putwc.c += -DOBJPFX=\"$(objpfx)\"
  
Arsen Arsenović Aug. 16, 2026, 9:04 a.m. UTC | #2
Arsen Arsenović <arsen@aarsen.me> writes:

> Currently, -std=c99 -D_GNU_SOURCE and similar lack the 'gets'
> declaration.
>
> This causes, say, programs using the:
>
>   extern __typeof__ (gets) function __attribute__ ((__warning__ (...)))

There's a typo there.  That's meant to be:

  extern __typeof__ (gets) gets __attribute__ ((__warning__ (...)))

... of course.
  
Arsen Arsenović Aug. 28, 2026, 9:18 p.m. UTC | #3
Gentle ping on this patch.
  
H.J. Lu Aug. 28, 2026, 9:55 p.m. UTC | #4
On Sun, Aug 16, 2026 at 5:05 PM Arsen Arsenović <arsen@aarsen.me> wrote:
>
> Arsen Arsenović <arsen@aarsen.me> writes:
>
> > Currently, -std=c99 -D_GNU_SOURCE and similar lack the 'gets'
> > declaration.
> >
> > This causes, say, programs using the:
> >
> >   extern __typeof__ (gets) function __attribute__ ((__warning__ (...)))
>
> There's a typo there.  That's meant to be:
>
>   extern __typeof__ (gets) gets __attribute__ ((__warning__ (...)))
>
> ... of course.
> --
> Arsen Arsenović

At least, more tests are needed for changed behavior:

1. No gets prototype for ISO C11 and ISO C++14.
2. Warnings of gets usage from compiler before ISO C11 or ISO C++14.
  
Arsen Arsenović Aug. 28, 2026, 10:26 p.m. UTC | #5
Hi H.J,

Thanks for responding.

"H.J. Lu" <hjl.tools@gmail.com> writes:

> On Sun, Aug 16, 2026 at 5:05 PM Arsen Arsenović <arsen@aarsen.me> wrote:
>>
>> Arsen Arsenović <arsen@aarsen.me> writes:
>>
>> > Currently, -std=c99 -D_GNU_SOURCE and similar lack the 'gets'
>> > declaration.
>> >
>> > This causes, say, programs using the:
>> >
>> >   extern __typeof__ (gets) function __attribute__ ((__warning__ (...)))
>>
>> There's a typo there.  That's meant to be:
>>
>>   extern __typeof__ (gets) gets __attribute__ ((__warning__ (...)))
>>
>> ... of course.
>> --
>> Arsen Arsenović
>
> At least, more tests are needed for changed behavior:
>
> 1. No gets prototype for ISO C11 and ISO C++14.

Isn't C11 covered by conform/ already?

I initially accidentally made the 'gets' signature available in C11 (by
typo-ing the stdc value), and it was caught.  And, indeed, stdio.h has:

  #if !defined ISO11 && !defined ISO23
  function {char*} gets (char*)
  #endif

As for C++, sure, that makes sense, but there's no existing framework
for writing those as far as I can tell.

Similarly, for ...

> 2. Warnings of gets usage from compiler before ISO C11 or ISO C++14.

... I am not sure how diagnostic tests would work in glibc (obviously
its testsuite differs to that of GCC), and I haven't been able to parse
out the right approach from the makefiles.

AFAICS, the right thing to do would be a tst-*.sh that greps compiler
output?

But then, that seems redundant with the existing conform/ machinery (and
the warnings are not something peculiar to this patch, they already
exist in glibc today).

Guidance appreciated on how to approach writing these two tests.

Thanks in advance!
Have a lovely evening.
  
H.J. Lu Aug. 29, 2026, 12:16 a.m. UTC | #6
On Sat, Aug 29, 2026 at 6:26 AM Arsen Arsenović <arsen@aarsen.me> wrote:
>
> Hi H.J,
>
> Thanks for responding.
>
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
> > On Sun, Aug 16, 2026 at 5:05 PM Arsen Arsenović <arsen@aarsen.me> wrote:
> >>
> >> Arsen Arsenović <arsen@aarsen.me> writes:
> >>
> >> > Currently, -std=c99 -D_GNU_SOURCE and similar lack the 'gets'
> >> > declaration.
> >> >
> >> > This causes, say, programs using the:
> >> >
> >> >   extern __typeof__ (gets) function __attribute__ ((__warning__ (...)))
> >>
> >> There's a typo there.  That's meant to be:
> >>
> >>   extern __typeof__ (gets) gets __attribute__ ((__warning__ (...)))
> >>
> >> ... of course.
> >> --
> >> Arsen Arsenović
> >
> > At least, more tests are needed for changed behavior:
> >
> > 1. No gets prototype for ISO C11 and ISO C++14.
>
> Isn't C11 covered by conform/ already?
>
> I initially accidentally made the 'gets' signature available in C11 (by
> typo-ing the stdc value), and it was caught.  And, indeed, stdio.h has:
>
>   #if !defined ISO11 && !defined ISO23
>   function {char*} gets (char*)
>   #endif

That is good to know.

> As for C++, sure, that makes sense, but there's no existing framework
> for writing those as far as I can tell.
>
> Similarly, for ...
>
> > 2. Warnings of gets usage from compiler before ISO C11 or ISO C++14.
>
> ... I am not sure how diagnostic tests would work in glibc (obviously
> its testsuite differs to that of GCC), and I haven't been able to parse
> out the right approach from the makefiles.
>
> AFAICS, the right thing to do would be a tst-*.sh that greps compiler
> output?
>
> But then, that seems redundant with the existing conform/ machinery (and
> the warnings are not something peculiar to this patch, they already
> exist in glibc today).

 tst-*.sh should work C++ prototype check and warning check.

> Guidance appreciated on how to approach writing these two tests.
>
> Thanks in advance!
> Have a lovely evening.
> --
> Arsen Arsenović
  

Patch

diff --git a/include/features.h b/include/features.h
index b3277f342cd6..a3f483fa7869 100644
--- a/include/features.h
+++ b/include/features.h
@@ -475,7 +475,9 @@ 
    safely.  It has been removed from ISO C11 and ISO C++14.  Note: for
    compatibility with various implementations of <cstdio>, this test
    must consider only the value of __cplusplus when compiling C++.  */
-#if defined __cplusplus ? __cplusplus >= 201402L : defined __USE_ISOC11
+#if (defined __cplusplus			\
+     ? __cplusplus >= 201402L			\
+     : (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L))
 # define __GLIBC_USE_DEPRECATED_GETS 0
 #else
 # define __GLIBC_USE_DEPRECATED_GETS 1
diff --git a/libio/Makefile b/libio/Makefile
index 616107ee105b..836a9dbb70d4 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -258,7 +258,7 @@  CFLAGS-oldtmpfile.c += -fexceptions
 
 # Prevent fortification as these are built with -O0
 CFLAGS-tst-bz24051.c += $(no-fortify-source)
-CFLAGS-tst-bz24153.c += $(no-fortify-source)
+CFLAGS-tst-bz24153.c += $(no-fortify-source) -Wno-deprecated-declarations
 
 CFLAGS-tst_putwc.c += -DOBJPFX=\"$(objpfx)\"