[clang] [analyzer] Don't invalidate pointee of pointer-to-const on callback arguments (PR #225489)
Benedek Kaibas via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 24 06:28:19 PDT 2026
================
@@ -250,7 +313,7 @@ ProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount,
// Indexes of arguments whose values will be preserved by the call.
llvm::SmallSet<unsigned, 4> PreserveArgs;
- if (!argumentsMayEscape())
+ if (!escapingAPIs(*this) && !hasVoidPointerToNonConstArg())
----------------
benedekaibas wrote:
If I would remove the `!hasVoidPointerToNonConstArg()` gate then the following code example ends up as a false positive:
```cpp
struct S {
int n;
int m;
};
void op_fuggveny(const void *p, void *p2);
int caller() {
S s;
s.n = 0;
s.m = 0;
op_fuggveny(&s.n, &s.m);
int z = 10 / s.m; // warning: Division by zero [core.DivideZero]
return z / s.n;
}
```
This leads to a false positive in case of struct fields. With the gate on the false positive disappears, but the false negative would happen for `s.n`. However, the false negative happens on `main` as well: https://godbolt.org/z/5Wsxn4n4a
During working on the PR I had tested my changes without the gate since first it did not make sense for me to use it, but I got wrong values for:
```cpp
void useFirstConstSecondNonConst(const void *x, void *y);
void useFirstNonConstSecondConst(void *x, const void *y);
void testMixedConstNonConstCalls() {
PlainStruct s2;
s2.x = 1;
useFirstConstSecondNonConst(&(s2.x), &(s2.y));
clang_analyzer_eval(s2.x == 1); // expected-warning{{UNKNOWN}}
s2.x = 1;
useFirstNonConstSecondConst(&(s2.x), &(s2.y));
clang_analyzer_eval(s2.x == 1); // expected-warning{{UNKNOWN}}
s2.y = 1;
useFirstConstSecondNonConst(&(s2.x), &(s2.y));
clang_analyzer_eval(s2.y == 1); // expected-warning{{UNKNOWN}}
s2.y = 1;
useFirstNonConstSecondConst(&(s2.x), &(s2.y));
clang_analyzer_eval(s2.y == 1); // expected-warning{{UNKNOWN}}
}
```
Instead of `UNKOWN` every expected warning turned to `TRUE` which is why I started investigating into `struct` fields and wrote the code example you can see above. So excluding the gate would introduce false positives.
It would be great to currectly fix the struct fields cases (`FieldRegion`s), but that is out of scope of this PR.
https://github.com/llvm/llvm-project/pull/225489
More information about the cfe-commits
mailing list