[cfe-dev] ISO C3X proposal: nonnull qualifier
David Blaikie via cfe-dev
cfe-dev at lists.llvm.org
Wed Dec 1 14:55:13 PST 2021
On Wed, Dec 1, 2021 at 2:46 PM Alejandro Colomar (man-pages) via cfe-dev <
cfe-dev at lists.llvm.org> wrote:
> Hi Joerg,
>
> On 12/1/21 23:24, Joerg Sonnenberger via cfe-dev wrote:
> > On Wed, Dec 01, 2021 at 10:57:51PM +0100, Alejandro Colomar (man-pages)
> via cfe-dev wrote:
> >> (2): I'm not sure I understand this one. I also didn't find the LKML
> >> thread. My idea is that if the compiler enforces nonnull-ness as it
> >> does currently with const, it will be possible to guarantee that sanity
> >> checks are unnecessary, and therefore they can be safely omitted (by the
> >> user, not the compiler).
> >
> > The original "bug" boils down to something like this:
> >
> > int f(int *p) {
> > int x = *p;
> > if (!p)
> > return -1;
> > return x;
> > }
> >
> > GCC sees the *p, and drops the if condition. Replace that with a call to
> > a function that has a nonnull attribute and you get the same problem.
> >
>
> If I add [[gnu::nonnull]], I get a warning (-Wnonnull-compare, implied
> by -Wall) with GCC, even with -O3:
>
> nonnull.c: In function ‘f’:
> nonnull.c:5:10: warning: ‘nonnull’ argument ‘p’ compared to NULL
> [-Wnonnull-compare]
> 5 | if (!p)
> | ^
>
> This warning should be mandatory by the standard IMO (if _Nonnull is
> added), since there's no valid point in comparing a nonnull pointer to
> NULL, but could also be non-mandatory, since it's not a dangerous thing.
> Having it in -Wall would be fine too.
>
> --
>
> About when nonnull is _not_ specified:
>
> GCC detects some broken code, and optimizes it.
> What GCC should do IMO is warn about some broken code in the begining.
>
> Clang produces the exact same code that GCC produces;
> both optimize the (!p) branch entirely.
> This is something to be reported to both of the compilers as bugs.
> Broken code should be warned, not optimized, and that code is broken.
>
The issue is this code comes up in many non-broken cases, like the case
Joerg mentions once you indirect through a function call:
bool other_func(int *p) {
if (!p)
return true;
/* probably do some other stuff */
}
int f(int *p) {
int x = *p;
if (other_func(p))
return -1;
return x;
}
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.
- Dave
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20211201/3ba4f520/attachment.html>
More information about the cfe-dev
mailing list