On Tue, May 27, 2014 at 4:06 PM, Patrick Palka <patr...@parcs.ath.cx> wrote:
> On Tue, May 27, 2014 at 8:32 AM, Patrick Palka <patr...@parcs.ath.cx> wrote:
>> On Tue, May 27, 2014 at 3:33 AM, Richard Biener
>> <richard.guent...@gmail.com> wrote:
>>> On Mon, May 26, 2014 at 9:01 PM, Patrick Palka <patr...@parcs.ath.cx> wrote:
>>>> Hi,
>>>>
>>>> This patch teaches the C++ frontend to warn on NULL checks against
>>>> inline functions and it teaches the middle-end to fold NULL checks
>>>> against inline functions.  These two things are currently done for
>>>> non-inline C++ functions, but inline functions are exceptional in that
>>>> the C++ frontend marks them as weak, and NULL checks against weak
>>>> symbols cannot be folded in general because the symbol may be mapped to
>>>> NULL at link-time.
>>>>
>>>> But in the case of an inline function, the fact that it's a weak symbol
>>>> is an implementation detail.  And because it is not permitted to
>>>> explicitly give an inline function the "weak" attribute (see
>>>> handle_weak_attribute), in order to acheive $SUBJECT it suffices to
>>>> assume that all inline functions are non-null, which is what this patch
>>>> does.
>>>>
>>>> Bootstrap and regtest against x86_64-unknown-linux-gnu in progress.  Is
>>>> this patch OK assuming no regressions?
>>>
>>> What about always_inline function wrappers as used in FORTIFY_SOURCE?
>>> IIRC the actual referenced function may be declared weak and thus the
>>> address can compare to NULL?  Sth like
>>>
>>> extern void __foo (void) __attribute__((weak,asm("foo")));
>>> extern inline __attribute__((always_inline,gnu_inline)) void foo (void)
>>> {
>>>   __foo ();
>>> }
>>>
>>> int main()
>>> {
>>>   if (foo == 0)
>>>     return 0;
>>>   abort ();
>>> }
>>>
>>> The issue is that the inline and alias may be hidden to the user and thus
>>> he'll get unwanted and confusing warnings.
>>>
>>> Richard.
>>
>> So as it stands the foo == 0 check in the above example gets folded
>> with or without my patch.  The issue here seems to be related to the
>> use of gnu_inline.  The address of an inline function marked
>> gnu_inline shouldn't be considered non-NULL because a standalone
>> function does not actually get emitted.  Of course, one could inspect
>> aliases but in general it is not correct to assume such functions are
>> non-NULL.  Does this sound right?
>>
>> This issue has slight overlap with the issue that my patch tries to
>> fix.  I could try to handle it as well.
>
> Oh, disregard the above.  I think I see what you mean now, Richard.
> Because __foo is an alias for foo, and __foo is weak, is it safe to
> assume that foo is non-NULL?  That is a tricky question...

No (I wasn't making a folding validity remark).  I want to make sure
we won't see diagnostics on code like

#include <string.h>

int main()
{
   if (malloc != 0)
     ...
}

just because it is built with -D_FORTIFY_SOURCE.  Whether we
may fold that check at all is another question, of course (and again
that should _not_ differ between -D_FORTIFY_SOURCE or -U_FORTIFY_SOURCE,
but it may well also be a glibc issue).

And yes, aliases are tricky beasts ...

Richard.

Reply via email to