<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/113821>113821</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[ExprConst] Field access resulting in null pointer is diagnosed at compile time
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang:frontend,
constexpr
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
tbaederr
</td>
</tr>
</table>
<pre>
Sorry for the clunky title.
Consider this code:
```c++
constexpr struct C {int a[2];} *c = nullptr;
static_assert(&c->a[1] - &c->a[0] == 1);
```
The output is:
```console
./array.cpp:141:17: error: static assertion expression is not an integral constant expression
141 | static_assert(&c->a[1] - &c->a[0] == 1);
| ^~~~~~~~~~~~~~~~~~~~~~~~
./array.cpp:141:21: note: cannot access field of null pointer
141 | static_assert(&c->a[1] - &c->a[0] == 1);
| ^
```
We diagnose this here: https://github.com/llvm/llvm-project/blob/7fe149cdf09d04fb8390b97c91bd9214c968cd3e/clang/lib/AST/ExprConstant.cpp#L1715-L1720
Because `IsNullPtr` is true here: https://github.com/llvm/llvm-project/blob/7fe149cdf09d04fb8390b97c91bd9214c968cd3e/clang/lib/AST/ExprConstant.cpp#L1702-L1712
However, if the field we're talking about coincidentally doesn't start at offset 0 (and thus `c->a` isn't `0`), we don't diagnose at all and this example just works:
```
constexpr struct C {char pad; int a[2];} *c = nullptr;
static_assert(&c->a[1] - &c->a[0] == 1);
```
https://godbolt.org/z/vzTr6sEMo
As you can see in the godbolt link, GCC rejects this as well.
I'm wondering that is right here. Should the code work in both cases or in neither case?
CC @zygoloid @AaronBallman
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMVU9v47YT_TTjyyCGSEmWdfDBf6Lfb4FtUSABeiwocmRxQ5MCScVxDv3sBSUndRZpgQJ7WEGg6SE54pv3ZkaEoI-WaAPlDsrDQoyxd34TW0GKvF-0Tl02D877C3bOY-wJpRnt0wWjjoaWkB0g287j3tmgFaVdOqB0iiC_LsEqm18JfJfeyYoonQ2RXgaPIfpRRtwjVDttIwoodxzKA-Q7qA4IfCsR8gPa0Zgh-mS--ghRRC3_ECGQj8DXwFfyDvL75IFBecA7vDVlyQT5ITljwOt3T-93nP8-9oRujMMYUYdPgDgbnKHZugTeCO_FZSmHAfItK1gaK8i3SN47nybzPXG-p3YWE24KIU11QOsiCovaRjp6YebQCBtvtr0hZgVDqPY_DDlOT_II5f2fnz__BpSnIQFIhKMUdsIiJYWAnSaj0HUTcTi4hM9_D-THkfgByqe8zuPvhEqLo3WBZrn25Kfb9zEOE928Ad4cdezHdindCXhjzPPbz93g3TeSEXjTGtcCb6qOWFFL1WW1yoquXed11taVrFmras4KWa_WUuUEvJFG2GNypNPB7cMj8Ob-ZfD7K-NTbHn-lVWsvPvKKv7h5juSYgyEsMq-hF9HY36LHlZZklD0I_2cQDKegDB-C-T_7kzP5IHvUXdTZZm1cibglSeMwjxpe0TRujGidNpKrchGYcwFlaNggVcxKcdHFBFd1wWKmCHwtbAKYz-GFKWraKYQzUdglU164HX6-JlQuXnhXRIiojAGZzc6IL2I02AIv40h4tn5p5uK8JnI_qmyyV54HISCfIc_RZX7TiVOtc7EpfOJ1lfgzfPro1-F-1_cLdhtwIsbU6JjIEJtJ_auh9Fo-5Ti-r_9Hj0lcYU5iCLgmYz50DO-AK9OeHZWkU9kx16keoteH_s4aXmJD70bjZp7j1M0xT99tHWxRykCBXQ-GSzp2JOfbJA3H3rTHqHIXi9HZ5xWab4V3tmdMOYkLM6bFmqTqzqvxYI2rMqzrCiqmi_6DStlpVa8qNZVVnK2Xney47XKC8qqgmi10Bue8YJlvGJlWZd8mXWyLjpq8yIvWEcMioxOQptlSroU34UOYaQNY_mas4URLZkwNWHO57TKt513NpJVwDnwfVp401SylIeF30wp3I7HAEVmdIjhb_9Tf04e3zMySaKZUuxamz2F0cQU9hS8m_qcGHjLBZWSQbrToA1h1CdajN5s_nN1meAG4M0V8fOG_xUAAP__02mJhQ">