[cfe-dev] [analyzer] Questions about the null dereference checker

Artem Dergachev via cfe-dev cfe-dev at lists.llvm.org
Mon Sep 20 12:43:12 PDT 2021


Again, *p is not a dereference. The result of this expression is still 
the location, not the value read from that location. You can easily 
convert this location back to the numeric value of the address: &*p. 
This is completely normal code with null pointers that does not 
constitute any UB and in fact has practical uses: for example, you can 
calculate offset of field x in struct S as (uintptr_t)&(((S *)0)->x), 
people have macros like this.

On the contrary, *p in (*p + 1) or *p in (x = *p) or in your example are 
actual dereferences because they are contextually converted to rvalues 
in order to perform the surrounding operations. /This conversion is the 
dereference, not the operator* on its own./ The operator simply converts 
rvalue to lvalue - it still represents a location.

Operators * and & are modeled in the static analyzer as no-op for the 
above reason: they really don't do anything on their own. The implicit 
cast from lvalue to rvalue is the read and this is what the checker 
reacts to. This is also why I'm nervous every time I see 
IgnoringParenImpCasts() in the code: some of these implicit casts are 
really important and shouldn't be missed most of the time.

You should read AST dumps of these expressions for more clarity, it 
really helped me back in the day.

On 9/20/21 6:44 AM, via cfe-dev wrote:
>
> Thanks Harald,
>
> I missed that.
>
> On the other hand, I still think that we should be consistent. (Hereby 
> thanks for Deep for the unique_ptr case.)
>
> And, by definition we dereferenced a null pointer, so the abstract 
> machine should halt.
>
> That being said, a slightly modified version of the same code:
>
> https://godbolt.org/z/Eenavva8x <https://godbolt.org/z/Eenavva8x>
>
> constexpr void foo() {
>
>   int *p = 0;
>
>   *p = 44;
>
> }
>
> This code won’t compile, and reports an error:
>
> error: constexpr function never produces a constant expression 
> [-Winvalid-constexpr]
>
> note: assignment to dereferenced null pointer is not allowed in a 
> constant expression
>
> So, in this sense, the abstract machine (aka. the analyzer) should 
> recognize this null dereference IMO.
>
> That way it would be consistent with the users expectation, also with 
> the store (lvalue) case and with the unique_ptr case.
>
> Balazs
>
> *From:*Harald van Dijk <harald at gigawatt.nl>
> *Sent:* 2021. szeptember 20., hétfő 14:53
> *To:* benicsbalazs at gmail.com; cfe-dev at lists.llvm.org
> *Subject:* Re: [cfe-dev] [analyzer] Questions about the null 
> dereference checker
>
> Hi,
>
> On 20/09/2021 13:33, via cfe-dev wrote:
>
>     Hi,
>
>     Let’s examine this code snippet:
>
>       void simply_deref_null() {
>
>         int *p = 0;
>
>         *p ; // no warning?
>
>         *p = 42; // warns!
>
>       }
>
>     Turns out the NullDereference checker treats the two pointer
>     derefs differently.
>
>     For simply reading through a null pointer is allowed but storing a
>     value is prohibited.
>
>     Why don't we prohibit reading through null pointers?
>
> Reads through null pointers do trigger the warning as well. However, 
> there is no read through a null pointer here. Dereferencing a pointer 
> produces an lvalue, not an rvalue, and discarding an lvalue expression 
> does not cause a load.
>
> If you change the example to, for example,
>
> int simply_deref_null() {
>    int *p = 0;
>    return *p;
> }
>
> you will see:
>
> test.cc:3:10: warning: Dereference of null pointer (loaded from variable 'p') [core.NullDereference]
>    return *p;
>           ^~
>
> Cheers,
> Harald van Dijk
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20210920/9e0f1f85/attachment-0001.html>


More information about the cfe-dev mailing list