On 07/19/16 18:37, Jakub Jelinek wrote:
> On Tue, Jul 19, 2016 at 04:20:55PM +0000, Bernd Edlinger wrote:
>> As discussed at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71876,
>> we have a _very_ old hack in gcc, that recognizes certain functions by
>> name, and inserts in some cases unsafe attributes, that don't work for
>> a freestanding environment.
>>
>> It is unsafe to return ECF_MAY_BE_ALLOCA, ECF_LEAF and ECF_NORETURN
>> from special_function_p, just by the name of the function, especially
>> for less well known functions, like "getcontext" or "savectx", which
>> could easily used for something completely different.
>>
>> Moreover, from the backend library we cannot check flag_hosted, or if
>> the function has "C" or "C++" binding.
>
> I believe this will regress handling of various functions.
> E.g. for alloca (as opposed to __builtin_alloca/__builtin_alloca_with_align,
> this means EFC_MAY_BE_ALLOCA will not be set anymore.
>
That depends on which options are used: with -ansi and -ffreestanding,
alloca is just a normal function, which is kind of correct.
If you include glibc's <alloca.h>, alloca is directly defined to
__builtin_alloca(x), which should work always.
If alloca is declared as void *alloca(size_t); it is also recognized as
built-in unless -ansi or -ffreestanding is used, so that handling was
in a way duplicated already.
So I see no regression here.
> _longjmp/siglongjmp will no longer be ECF_NORETURN (glibc
> doesn't declare them as such), __sigsetjmp will no longer be ECF_LEAF.
Which version of glibc do you refer to?
My 2.19-0ubuntu6.9 has:
extern void _longjmp (struct __jmp_buf_tag __env[1], int __val)
__THROWNL __attribute__ ((__noreturn__));
extern int __sigsetjmp (struct __jmp_buf_tag __env[1], int __savemask)
__THROWNL;
So yes, __THROWNL is "__attribute__ ((__nothrow__))".
But they also have __THROW around which is "__attribute__ ((__nothrow__
__LEAF))", so that is just a minor bug in the glibc header, the header
should declare it __THROW if it is no leaf.
If you are concerned about the leaf attribute, it would
be easy to add a builtin for _longjmp, and __sigsetjmp, as
the _ is reserved anyway. However I considered it an implementation
detail of glibc, that could change, and I did not check newlib on that
either.
Should I add built-in for _longjmp and __sigsetjmp, and check if
that works for newlib too?
Thanks
Bernd.