[PATCH] D31982: [analyzer] Improve suppression for inlined defensive checks when operator& is involved.
Artem Dergachev via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 12 09:55:06 PDT 2017
NoQ created this revision.
In code
void foo(int *p) {
if (p) {}
}
void bar(int *p) {
foo(p);
*p = 5;
}
we suppress the null dereference warning in `*p = 5` because the state split within the inlined function is essentially irrelevant, as this is merely a defensive check that does not necessarily trigger in this caller context.
The suppression works by tracking the null pointer symbol in a bug report visitor and seeing if it was constrained to 0 inside a callee context. The fact that we have to rely on such manual suppressions is a downside of the inlining-based approach to interprocedural analysis.
The suppression gets confused when the null dereference becomes more complex, eg:
struct S {
int x;
}
void foo(struct S *s) {
if (s) {}
}
void bar(struct S *s) {
foo(s);
*(&(s->x)) = 5;
}
In this case `s` is `&SymRegion{reg_$0<s>}`, and `reg_$0<s>` is constrained to `[0, 0]`, similarly to the above. However, while computing `s->x` and then `&(s->x)`, the symbol is collapsed to a constant `0 (Loc)`, making it harder to track the symbol. The visitor is improved to handle this case.
While the fact that //offset of field `x` in struct `S` in our example is equal to 0// is purely accidental, with any other offset it'd still be a null dereference, worth suppressing. How does the analyzer handle the non-zero offset case and still see a null dereference? Simply and powerfully: it mis-computes the offset, incorrectly believing that all offsets are equal to 0 (woohoo!). I add a test case to document this behavior; even though it's trivial to fix, the positive side effects of this bug are for now too useful to discard.
https://reviews.llvm.org/D31982
Files:
lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
lib/StaticAnalyzer/Core/Store.cpp
test/Analysis/explain-svals.cpp
test/Analysis/inlining/inline-defensive-checks.c
test/Analysis/inlining/inline-defensive-checks.cpp
test/Analysis/uninit-const.cpp
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D31982.94986.patch
Type: text/x-patch
Size: 5803 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170412/4ffe84aa/attachment.bin>
More information about the cfe-commits
mailing list