[PATCH] D126481: [analyzer] Handle SymbolCast in SValBuilder
Gabor Marton via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue May 31 23:42:26 PDT 2022
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
martong marked an inline comment as done.
Closed by commit rG160798ab9be8: [analyzer] Handle SymbolCast in SValBuilder (authored by martong).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D126481/new/
https://reviews.llvm.org/D126481
Files:
clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
clang/test/Analysis/svalbuilder-casts.cpp
Index: clang/test/Analysis/svalbuilder-casts.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/svalbuilder-casts.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=debug.ExprInspection \
+// RUN: -analyzer-config support-symbolic-integer-casts=true \
+// RUN: -analyzer-config eagerly-assume=false \
+// RUN: -triple x86_64-unknown-linux-gnu \
+// RUN: -verify
+
+// Test that the SValBuilder is able to look up and use a constraint for an
+// operand of a SymbolCast, when the operand is constrained to a const value.
+
+void clang_analyzer_eval(bool);
+
+extern void abort() __attribute__((__noreturn__));
+#define assert(expr) ((expr) ? (void)(0) : abort())
+
+void test(int x) {
+ // Constrain a SymSymExpr to a constant value.
+ assert(x * x == 1);
+ // It is expected to be able to get the constraint for the operand of the
+ // cast.
+ clang_analyzer_eval((char)(x * x) == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval((long)(x * x) == 1); // expected-warning{{TRUE}}
+}
+
+void test1(int x, int y) {
+ // Even if two lower bytes of `x` equal to zero, it doesn't mean that
+ // the entire `x` is zero. We are not able to know the exact value of x.
+ // It can be one of 65536 possible values like
+ // [0, 65536, -65536, 131072, -131072, ...]. To avoid huge range sets we
+ // still assume `x` in the range [INT_MIN, INT_MAX].
+ assert((short)x == 0); // Lower two bytes are set to 0.
+
+ static_assert((short)65536 == 0, "");
+ static_assert((short)-65536 == 0, "");
+ static_assert((short)131072 == 0, "");
+ static_assert((short)-131072 == 0, "");
+ clang_analyzer_eval(x == 0); // expected-warning{{UNKNOWN}}
+
+ // These are not truncated to short as zero.
+ static_assert((short)1 != 0, "");
+ clang_analyzer_eval(x == 1); // expected-warning{{FALSE}}
+ static_assert((short)-1 != 0, "");
+ clang_analyzer_eval(x == -1); // expected-warning{{FALSE}}
+ static_assert((short)65537 != 0, "");
+ clang_analyzer_eval(x == 65537); // expected-warning{{FALSE}}
+ static_assert((short)-65537 != 0, "");
+ clang_analyzer_eval(x == -65537); // expected-warning{{FALSE}}
+ static_assert((short)131073 != 0, "");
+ clang_analyzer_eval(x == 131073); // expected-warning{{FALSE}}
+ static_assert((short)-131073 != 0, "");
+ clang_analyzer_eval(x == -131073); // expected-warning{{FALSE}}
+
+ // Check for implicit cast.
+ short s = y;
+ assert(s == 0);
+ clang_analyzer_eval(y == 0); // expected-warning{{UNKNOWN}}
+}
Index: clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -1278,8 +1278,6 @@
return SVB.makeSymbolVal(S);
}
- // TODO: Support SymbolCast.
-
SVal VisitSymIntExpr(const SymIntExpr *S) {
auto I = Cached.find(S);
if (I != Cached.end())
@@ -1349,7 +1347,17 @@
S, SVB.evalBinOp(State, S->getOpcode(), LHS, RHS, S->getType()));
}
- // FIXME add VisitSymbolCast
+ SVal VisitSymbolCast(const SymbolCast *S) {
+ auto I = Cached.find(S);
+ if (I != Cached.end())
+ return I->second;
+ const SymExpr *OpSym = S->getOperand();
+ SVal OpVal = getConstOrVisit(OpSym);
+ if (isUnchanged(OpSym, OpVal))
+ return skip(S);
+
+ return cache(S, SVB.evalCast(OpVal, S->getType(), OpSym->getType()));
+ }
SVal VisitUnarySymExpr(const UnarySymExpr *S) {
auto I = Cached.find(S);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D126481.433298.patch
Type: text/x-patch
Size: 3678 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220601/ef5f5c36/attachment-0001.bin>
More information about the cfe-commits
mailing list