[PATCH] D110625: [analyzer] canonicalize special case of structure/pointer deref
Vince Bridgers via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 1 02:09:08 PDT 2021
vabridgers updated this revision to Diff 376453.
vabridgers added a comment.
add const test case
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D110625/new/
https://reviews.llvm.org/D110625
Files:
clang/lib/StaticAnalyzer/Core/Store.cpp
clang/test/Analysis/ptr-arith.c
Index: clang/test/Analysis/ptr-arith.c
===================================================================
--- clang/test/Analysis/ptr-arith.c
+++ clang/test/Analysis/ptr-arith.c
@@ -2,6 +2,7 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -Wno-pointer-to-int-cast -verify -triple i686-apple-darwin9 -Wno-tautological-pointer-compare -analyzer-config eagerly-assume=false %s
void clang_analyzer_eval(int);
+void clang_analyzer_dump(int);
void f1() {
int a[10];
@@ -330,3 +331,59 @@
simd_float2 x = {0, 1};
return x[1]; // no-warning
}
+
+struct s {
+ int v;
+};
+
+// These three expressions should produce the same sym vals.
+void struct_pointer_canon(struct s *ps) {
+ struct s ss = *ps;
+ clang_analyzer_dump((*ps).v);
+ // expected-warning-re at -1{{reg_${{[[:digit:]]+}}<int SymRegion{reg_${{[[:digit:]]+}}<struct s * ps>}.v>}}
+ clang_analyzer_dump(ps[0].v);
+ // expected-warning-re at -1{{reg_${{[[:digit:]]+}}<int SymRegion{reg_${{[[:digit:]]+}}<struct s * ps>}.v>}}
+ clang_analyzer_dump(ps->v);
+ // expected-warning-re at -1{{reg_${{[[:digit:]]+}}<int SymRegion{reg_${{[[:digit:]]+}}<struct s * ps>}.v>}}
+ clang_analyzer_eval((*ps).v == ps[0].v); // expected-warning{{TRUE}}
+ clang_analyzer_eval((*ps).v == ps->v); // expected-warning{{TRUE}}
+ clang_analyzer_eval(ps[0].v == ps->v); // expected-warning{{TRUE}}
+}
+
+void struct_pointer_canon_bidim(struct s **ps) {
+ struct s ss = **ps;
+ clang_analyzer_eval(&(ps[0][0].v) == &((*ps)->v)); // expected-warning{{TRUE}}
+}
+
+typedef struct s T1;
+typedef struct s T2;
+void struct_pointer_canon_typedef(T1 *ps) {
+ T2 ss = *ps;
+ clang_analyzer_dump((*ps).v);
+ // expected-warning-re at -1{{reg_${{[[:digit:]]+}}<int SymRegion{reg_${{[[:digit:]]+}}<T1 * ps>}.v>}}
+ clang_analyzer_dump(ps[0].v);
+ // expected-warning-re at -1{{reg_${{[[:digit:]]+}}<int SymRegion{reg_${{[[:digit:]]+}}<T1 * ps>}.v>}}
+ clang_analyzer_dump(ps->v);
+ // expected-warning-re at -1{{reg_${{[[:digit:]]+}}<int SymRegion{reg_${{[[:digit:]]+}}<T1 * ps>}.v>}}
+ clang_analyzer_eval((*ps).v == ps[0].v); // expected-warning{{TRUE}}
+ clang_analyzer_eval((*ps).v == ps->v); // expected-warning{{TRUE}}
+ clang_analyzer_eval(ps[0].v == ps->v); // expected-warning{{TRUE}}
+}
+
+void struct_pointer_canon_bidim_typedef(T1 **ps) {
+ T2 ss = **ps;
+ clang_analyzer_eval(&(ps[0][0].v) == &((*ps)->v)); // expected-warning{{TRUE}}
+}
+
+void struct_pointer_canon_const(const struct s *ps) {
+ struct s ss = *ps;
+ clang_analyzer_dump((*ps).v);
+ // expected-warning-re at -1{{reg_${{[[:digit:]]+}}<int SymRegion{reg_${{[[:digit:]]+}}<const struct s * ps>}.v>}}
+ clang_analyzer_dump(ps[0].v);
+ // expected-warning-re at -1{{reg_${{[[:digit:]]+}}<int SymRegion{reg_${{[[:digit:]]+}}<const struct s * ps>}.v>}}
+ clang_analyzer_dump(ps->v);
+ // expected-warning-re at -1{{reg_${{[[:digit:]]+}}<int SymRegion{reg_${{[[:digit:]]+}}<const struct s * ps>}.v>}}
+ clang_analyzer_eval((*ps).v == ps[0].v); // expected-warning{{TRUE}}
+ clang_analyzer_eval((*ps).v == ps->v); // expected-warning{{TRUE}}
+ clang_analyzer_eval(ps[0].v == ps->v); // expected-warning{{TRUE}}
+}
Index: clang/lib/StaticAnalyzer/Core/Store.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/Store.cpp
+++ clang/lib/StaticAnalyzer/Core/Store.cpp
@@ -442,6 +442,15 @@
SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
SVal Base) {
+
+ // Special case, if index is 0, return the same type as if
+ // this was not an array dereference.
+ if (Offset.isZeroConstant()) {
+ QualType BT = Base.getType(this->Ctx);
+ if (!BT.isNull() && BT->getPointeeType() == elementType)
+ return Base;
+ }
+
// If the base is an unknown or undefined value, just return it back.
// FIXME: For absolute pointer addresses, we just return that value back as
// well, although in reality we should return the offset added to that
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D110625.376453.patch
Type: text/x-patch
Size: 4101 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20211001/d9e3b345/attachment.bin>
More information about the cfe-commits
mailing list