On Tue, 2024-07-02 at 19:02 +0200, Jakub Jelinek wrote:
> On Tue, Jul 02, 2024 at 12:54:09PM -0400, David Malcolm via Gcc
> wrote:
> > Back in 2007 glibc gained some logic to implement "error" and
> > "error_at_line" by splitting into zero and non-zero cases, with the
> > nonzero case calling a "noreturn" function [1].
> > 
> > This doesn't seem to work. I tested back to 4.8.1 with Compiler
> > Explorer [2], which seems to be the earliest GCC that supports -
> > fdump-
> > tree-original=stderr.
> > 
> > What happens is that glibc's 
> > 
> > __extern_always_inline void
> > error (int __status, int __errnum, const char *__format, ...)
> > {
> >   if (__builtin_constant_p (__status) && __status != 0)
> >     __error_noreturn (__status, __errnum, __format, __va_arg_pack
> > ());
> >   else
> >     __error_alias (__status, __errnum, __format, __va_arg_pack ());
> > }
> > 
> > comes out of GCC's C frontend as:
> > 
> > {
> >   if (0)
> >     {
> >       __error_noreturn (__status, __errnum, __format,
> > __builtin_va_arg_pack ());
> >     }
> >   else
> >     {
> >       __error_alias (__status, __errnum, __format,
> > __builtin_va_arg_pack ());
> >     }
> > }
> > 
> > since __status is not a builtin constant,
> 
> At -O0 sure, that is how __builtin_constant_p works.

Aha!  That's what I was missing.

> The above is intended for optimized compilation, and I think it works
> just
> fine then.

Indeed it does.

Sorry for the noise.
Dave

> The fact that in some cases the function after optimization appears
> to be
> noreturn isn't something one can really rely on, just pass a function
> parameter or something that will not optimize into a constant and it
> will be
> fallthrough as well...
> 
>         Jakub
> 

Reply via email to