<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
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.<br>
<br>
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. <i>This
conversion is the dereference, not the operator* on its own.</i>
The operator simply converts rvalue to lvalue - it still represents
a location.<br>
<br>
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.<br>
<br>
You should read AST dumps of these expressions for more clarity, it
really helped me back in the day.<br>
<br>
<div class="moz-cite-prefix">On 9/20/21 6:44 AM, via cfe-dev wrote:<br>
</div>
<blockquote type="cite"
cite="mid:00d701d7ae25$9593e6c0$c0bbb440$@gmail.com">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="Generator" content="Microsoft Word 15 (filtered
medium)">
<style>@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}@font-face
{font-family:Consolas;
panose-1:2 11 6 9 2 2 4 3 2 4;}p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
font-size:11.0pt;
font-family:"Calibri",sans-serif;
mso-fareast-language:EN-US;}a:link, span.MsoHyperlink
{mso-style-priority:99;
color:#0563C1;
text-decoration:underline;}pre
{mso-style-priority:99;
mso-style-link:"HTML Preformatted Char";
margin:0cm;
font-size:10.0pt;
font-family:"Courier New";}span.HTMLPreformattedChar
{mso-style-name:"HTML Preformatted Char";
mso-style-priority:99;
mso-style-link:"HTML Preformatted";
font-family:Consolas;
mso-fareast-language:EN-US;}span.EmailStyle22
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}div.WordSection1
{page:WordSection1;}</style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US">Thanks Harald,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">I missed that.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">On the other hand, I
still think that we should be consistent. (Hereby thanks for
Deep for the unique_ptr case.)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">And, by definition we
dereferenced a null pointer, so the abstract machine should
halt.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">That being said, a
slightly modified version of the same code:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><a
href="https://godbolt.org/z/Eenavva8x"
moz-do-not-send="true">https://godbolt.org/z/Eenavva8x</a><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">constexpr void foo() {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"> int *p = 0;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"> *p = 44;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">}<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">This code won’t compile,
and reports an error:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">error: constexpr
function never produces a constant expression
[-Winvalid-constexpr]<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">note: assignment to
dereferenced null pointer is not allowed in a constant
expression<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">So, in this sense, the
abstract machine (aka. the analyzer) should recognize this
null dereference IMO.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">That way it would be
consistent with the users expectation, also with the store
(lvalue) case and with the unique_ptr case.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Balazs<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<div>
<div style="border:none;border-top:solid #E1E1E1
1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b><span
style="mso-fareast-language:HU" lang="EN-US">From:</span></b><span
style="mso-fareast-language:HU" lang="EN-US"> Harald van
Dijk <a class="moz-txt-link-rfc2396E" href="mailto:harald@gigawatt.nl"><harald@gigawatt.nl></a> <br>
<b>Sent:</b> 2021. szeptember 20., hétfő 14:53<br>
<b>To:</b> <a class="moz-txt-link-abbreviated" href="mailto:benicsbalazs@gmail.com">benicsbalazs@gmail.com</a>;
<a class="moz-txt-link-abbreviated" href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
<b>Subject:</b> Re: [cfe-dev] [analyzer] Questions about
the null dereference checker<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p>Hi,<o:p></o:p></p>
<div>
<p class="MsoNormal">On 20/09/2021 13:33, via cfe-dev wrote:<o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal"><span lang="EN-US">Hi,</span><o:p></o:p></p>
<p class="MsoNormal"><span lang="EN-US">Let’s examine this
code snippet:</span><o:p></o:p></p>
<p class="MsoNormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="MsoNormal"><span lang="EN-US"> void
simply_deref_null() {</span><o:p></o:p></p>
<p class="MsoNormal"><span lang="EN-US"> int *p = 0;</span><o:p></o:p></p>
<p class="MsoNormal"><span lang="EN-US"> *p ; // no
warning?</span><o:p></o:p></p>
<p class="MsoNormal"><span lang="EN-US"> *p = 42; // warns!</span><o:p></o:p></p>
<p class="MsoNormal"><span lang="EN-US"> }</span><o:p></o:p></p>
<p class="MsoNormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="MsoNormal"><span lang="EN-US">Turns out the
NullDereference checker treats the two pointer derefs
differently.</span><o:p></o:p></p>
<p class="MsoNormal"><span lang="EN-US">For simply reading
through a null pointer is allowed but storing a value is
prohibited.</span><o:p></o:p></p>
<p class="MsoNormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="MsoNormal"><span lang="EN-US">Why don't we prohibit
reading through null pointers?</span><o:p></o:p></p>
</blockquote>
<p>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.<o:p></o:p></p>
<p>If you change the example to, for example,<o:p></o:p></p>
<pre>int simply_deref_null() {<o:p></o:p></pre>
<pre> int *p = 0;<o:p></o:p></pre>
<pre> return *p;<o:p></o:p></pre>
<pre>}<o:p></o:p></pre>
<p>you will see:<o:p></o:p></p>
<pre>test.cc:3:10: warning: Dereference of null pointer (loaded from variable 'p') [core.NullDereference]<o:p></o:p></pre>
<pre> return *p;<o:p></o:p></pre>
<pre> ^~<o:p></o:p></pre>
<p>Cheers,<br>
Harald van Dijk<o:p></o:p></p>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<pre class="moz-quote-pre" wrap="">_______________________________________________
cfe-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a>
</pre>
</blockquote>
<br>
</body>
</html>