[clang][analyzer] Pointer cast after in-bounds arithmetic loses non-null constraint
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
**Description:**
Analyzer loses the non-null constraint when a pointer produced by in-bounds pointer arithmetic is cast to another object-pointer type. It correctly proves that the source pointer is non-null, but treats the cast result as both null and non-null. Because of that it explores an infeasible branch and emits a false `core.NullDereference` warning.
**Reproducer:**
```c
void clang_analyzer_eval(int);
void f(_Bool i)
{
unsigned char a[2];
unsigned char *q = a + i;
char *r = (char *)q;
clang_analyzer_eval(q != 0); // TRUE
clang_analyzer_eval(r != 0); // expected TRUE; actual TRUE and FALSE
if (!r)
*r = 0; // false positive
}
```
Both expressions should evaluate only to `TRUE`, and no null-dereference warning should be emitted. Because `i` has type `_Bool`, it is either zero or one. Therefore `q` points to either `a[0]` or `a[1]` and is non-null. Converting this properly aligned non-null object pointer from `unsigned char *` to `char *` shouldn't produce a null pointer.
Slightly complex example for which I think is related can be found [here](https://compiler-explorer.com/z/K77oK6753).
Contributor guide
Research direction
Start with the provided C reproducer and run it through Clang Static Analyzer, checking the clang_analyzer_eval results and whether core.NullDereference is emitted. Trace pointer casts after in-bounds arithmetic, then add a regression test covering the reproducer; done means both evaluations are only TRUE and no false warning appears.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100