<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/105560>105560</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
False positive: core.NullDereference on a const, non-null pointer member
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
GuB-42
</td>
</tr>
</table>
<pre>
With the following code
```C++
struct A {
void test(bool doSet, int v);
int *tPtr = nullptr;
int val = 0;
int * const nonNullPtr = &val;
};
#if 1
void A::test(bool doSet, int v) {
if (doSet) tPtr = nonNullPtr;
*(tPtr ? tPtr : nonNullPtr) = v;
}
#else
int main() {
A a;
a.test(false, 42);
return 0;
}
#endif
```
With options
```
--analyze --analyzer-output text -Xanalyzer -analyzer-checker=core.NullDereference -Xclang -analyzer-checker=core,debug.ExprInspection
```
I get
```
<source>:12:30: warning: Dereference of null pointer [core.NullDereference]
12 | *(tPtr ? tPtr : nonNullPtr) = v;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
<source>:11:6: note: Assuming 'doSet' is true
11 | if (doSet) tPtr = nonNullPtr;
| ^~~~~
<source>:11:2: note: Taking true branch
11 | if (doSet) tPtr = nonNullPtr;
| ^
<source>:12:4: note: Assuming field 'tPtr' is null
12 | *(tPtr ? tPtr : nonNullPtr) = v;
| ^~~~
<source>:12:4: note: '?' condition is false
<source>:12:30: note: Dereference of null pointer
12 | *(tPtr ? tPtr : nonNullPtr) = v;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
1 warning generated.
```
https://godbolt.org/z/vE7hWbWjh
There is no way for nonNullPtr to be NULL besides memory corruption , it is const and initialized to a valid target.
If A::test() is defined and used in the same translation unit, the warning disappears. It can be seen by removing the #else directive in the example code. For building a practical example that still shows the warning, have the A::test() definition and main() in different files.
Tested on various clang versions, including 11, 16, 18 and trunk. Also with clang-tidy.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0Vl2PmzgX_jXOzVEQmADJBRfMZPKqUlW90nbV3hp8CG6NjWzDdHoxv31lJ5mQNM12V90IETDn4zlffsysFXuFWJLsgWTbBRtdp035v_FhuaKLWvOX8pNwHbgOodVS6meh9tBojiTekrg63vP4cD0S-uCvsGqdGRsHFZDi4SS9mbTg4NA6Qte11hK4_gMdoY8glIOJ0A1Jz9J-jdDK_d8ZIOkW1Cjl4My1yMRk-Bzf0IVGK-tAafVhlPJkiNB8YvIsXmxnquFOU9FCMl8K0CuS-utuBBcBixYIXR9lNnAO5Q3QHDShFaHro9DuJF3Npb39dAvTBfhL5CjtRX08sJ4JRej6Gl4FbO6fRcfIWuZt0EdY0auaGHSjUfNc_-hfcdFetcZcJLSUHpzQysLNRjq8LpdMMfnyHeHtySz16IbRgcNvDpafT8twFmg6bL6iIem20QYjn7ctGmzRoGoQlp8bydT-pwqEPnKsx3309G0w75QdsPFA74TzDvbo7oRB0kerR9MgSZ9IWiWUpFUa-7I-M6OE2vvHOUTdhk6HQQvl0ADJHm6FQrJj4gEgoUCKRzj9_k0fHTVnVl7v_Ej29Pp6O76EpFV-8ObQ_1fWjr3fOAgtjpNQgLDgzIjnCJIL3_9gbi70Qgwe2z10dI7uI_vqsXkwUBummu53YHpLJsmeft4Gq5tpagVK7pPlQqFCrnxDXFf791T5lK9fREloQdKdR9VoxYWfDY_vsGH8Tb-fbNxp9v-mo3-xk5PTRMIeFRrmkEd3Br9zbrCeEOiO0N1e81pLF2mzJ3T3ndDd9FR0n-pPX7q50scODYaKanhmL9BqM2cnp6FG-PDn-_dQoxUcLfTYa_MCjTZmDJsmBLZx3siB3ZjiIJRwgknxHbk3wjwreq5lZo8uutiv2isa85kTFji2QiEP1kaL3mQgfst6BGeYspIF96MSgfD8x1PCuLBsGJAZG8E7Bw1TPg6LqKB-AYO9nsKUdQhHhgIujN9bJzw5wm-sHySG80UEO22gHoXkXo_BYFjjRMPkm5jrmAPrhJRgO_1s53g8vI5NGNZ-jDaEeuhdH-2MHIUCLtrQnA5aIdFe5O4jWocctIKJGaFHCwc2mdBYT2eHc0Ajx4A6Sfx7kof7OrhyZlRfI6ik1fDseTDoL53gL9GClynfpBu2wDIp6IrmabLJF11ZI9-s2DpO8qLI122e83yTrBsax8Uqq-tsIUoa01W8pklSZJssjzJEGmcM11ldr9tNS1Yx9kzISMqp9y26ENaOWCZxluXxQrIapQ2nQEoVPkP4Sij1h0JTeqVlPe4tWcVSWGfPZpxwEsudn34YtBW-nn4ub3KvT_ehZX1GlFbLC57rsa_RLEYjy6vREq4b66jRPaE77_r4txyM_oKNI3QXAFtCd8eIppL-FQAA__9xiDrN">