[cfe-dev] ISO C3X proposal: nonnull qualifier

Alejandro Colomar (man-pages) via cfe-dev cfe-dev at lists.llvm.org
Wed Dec 1 15:11:11 PST 2021


Hi David,

On 12/1/21 23:55, David Blaikie via cfe-dev wrote:
> 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.

In this case it seems correct code to me.  A _Nonnull qualifier would
better clarify the correctness/intent of the code:


   bool other_func(int *p) {
     if (!p)
       return true;
     /* probably do some other stuff */
   }
   int f(int *_Nonnull p) {
       int x = *p;
       if (other_func(p))
         return -1;
       return x;
   }


The above would be fine, and the optimization would be perfect.  Since
there's an implicit conversion where the _Nonnull qualifier is
discarded, there should be no warning, since the check is done to a
nullable pointer.


   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;
   }

The above code, in an ideal C3X scenario, would issue a warning at
 `int x = *p;`
due to dereference of a nullable pointer.  Now that I think, since this
was legal C in the past, this warning should not be mandatory (otherwise
we would issue many spurious warnings for old code), but could be warned
by -Wall.


   bool other_func(int *_Nonnull p) {
     if (!p)
       return true;
     /* probably do some other stuff */
   }
   int f(int *_Nonnull p) {
       int x = *p;
       if (other_func(p))
         return -1;
       return x;
   }

And this code should have a mandatory warning: comparing to NULL a
nonnull pointer.


   bool other_func(int *_Nonnull 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;
   }

Of course, ignoring the dereference, this code would also have another
warning (this one could be mandatory):  Passing p to other_func()
implicitly adds _Nonnull qualifier.


Cheers,

Alex


More information about the cfe-dev mailing list