<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Dec 1, 2021 at 2:46 PM Alejandro Colomar (man-pages) via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Joerg,<br>
<br>
On 12/1/21 23:24, Joerg Sonnenberger via cfe-dev wrote:<br>
> On Wed, Dec 01, 2021 at 10:57:51PM +0100, Alejandro Colomar (man-pages) via cfe-dev wrote:<br>
>> (2):  I'm not sure I understand this one.  I also didn't find the LKML<br>
>> thread.  My idea is that if the compiler enforces nonnull-ness as it<br>
>> does currently with const, it will be possible to guarantee that sanity<br>
>> checks are unnecessary, and therefore they can be safely omitted (by the<br>
>> user, not the compiler).<br>
> <br>
> The original "bug" boils down to something like this:<br>
> <br>
>    int f(int *p) {<br>
>       int x = *p;<br>
>       if (!p)<br>
>         return -1;<br>
>       return x;<br>
>    }<br>
> <br>
> GCC sees the *p, and drops the if condition. Replace that with a call to<br>
> a function that has a nonnull attribute and you get the same problem.<br>
> <br>
<br>
If I add [[gnu::nonnull]], I get a warning (-Wnonnull-compare, implied<br>
by -Wall) with GCC, even with -O3:<br>
<br>
nonnull.c: In function ‘f’:<br>
nonnull.c:5:10: warning: ‘nonnull’ argument ‘p’ compared to NULL<br>
[-Wnonnull-compare]<br>
    5 |       if (!p)<br>
      |          ^<br>
<br>
This warning should be mandatory by the standard IMO (if _Nonnull is<br>
added), since there's no valid point in comparing a nonnull pointer to<br>
NULL, but could also be non-mandatory, since it's not a dangerous thing.<br>
 Having it in -Wall would be fine too.<br>
<br>
--<br>
<br>
About when nonnull is _not_ specified:<br>
<br>
GCC detects some broken code, and optimizes it.<br>
What GCC should do IMO is warn about some broken code in the begining.<br>
<br>
Clang produces the exact same code that GCC produces;<br>
both optimize the (!p) branch entirely.<br>
This is something to be reported to both of the compilers as bugs.<br>
Broken code should be warned, not optimized, and that code is broken.<br></blockquote><div><br>The issue is this code comes up in many non-broken cases, like the case Joerg mentions once you indirect through a function call:<br><br>  bool other_func(int *p) {<br>    if (!p)<br>      return true;<br>    /* probably do some other stuff */<br>  }<br>  int f(int *p) {</div>      int x = *p;<br>      if (other_func(p))<br>        return -1;<br>      return x;<br>  }<br><br>Now it's not clear this code isn't working as intended - it's probably possible to say that for every case Clang can warn about (ones that don't require a lot of non-local reasoning) it could also suppress any optimization of such a null check (but would that be especially useful? I find it doubtful - the user could address the warning instead), but for all the more complicated non-local reasoning (due to inlining or other optimizations) it's unlikely Clang would suppress such optimizations - because in the above code, for instance, the optimization may be exactly what the user wants - in this /particular/ call site of other_func, the pointer is always non-null so the compiler can optimize away the null test from some generic code when specializing it for this particular call site.<br><br>- Dave</div></div>