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.
The above is intended for optimized compilation, and I think it works just
fine then.
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