aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordingfei <fding@feysh.com>2023-09-15 14:01:26 +0800
committerBalazs Benics <benicsbalazs@gmail.com>2023-09-15 15:07:39 +0200
commit7c9abbd8a41e85a7e82a454c62138ea72f981597 (patch)
tree8ba34376cef4513a6b38b76dbf56660ff564d3d0
parentb0f0aa852d074441fc4dafc138a9cffc3d083dbc (diff)
downloadllvm-7c9abbd8a41e85a7e82a454c62138ea72f981597.zip
llvm-7c9abbd8a41e85a7e82a454c62138ea72f981597.tar.gz
llvm-7c9abbd8a41e85a7e82a454c62138ea72f981597.tar.bz2
Reapply [analyzer] Simplify SVal for simple NonLoc->Loc casts
Reapply after fixing the test by enabling the `debug.ExprInspection` checker. ----- NonLoc symbolic SVal to Loc casts are not supported except for nonloc::ConcreteInt. This change simplifies the source SVals so that the more casts can go through nonloc::ConcreteInt->loc::ConcreteInt path. For example: void test_simplified_before_cast_add(long long t1) { long long t2 = t1 + 3; if (!t2) { int *p = (int *) t2; clang_analyzer_eval(p == 0); // expected-warning{{TRUE}} } } If simplified, 't2' is 0, resulting 'p' is nullptr, otherwise 'p' is unknown. Fixes #62232
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp3
-rw-r--r--clang/test/Analysis/symbol-simplification-nonloc-loc.cpp28
2 files changed, 29 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 2a47116..7e431f7 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -264,7 +264,8 @@ ProgramStateRef ExprEngine::handleLValueBitCast(
}
// Delegate to SValBuilder to process.
SVal OrigV = state->getSVal(Ex, LCtx);
- SVal V = svalBuilder.evalCast(OrigV, T, ExTy);
+ SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);
+ SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);
// Negate the result if we're treating the boolean as a signed i1
if (CastE->getCastKind() == CK_BooleanToSignedIntegral && V.isValid())
V = svalBuilder.evalMinus(V.castAs<NonLoc>());
diff --git a/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp b/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp
index 485f68d9a..6cfe8da 100644
--- a/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp
+++ b/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp
@@ -1,6 +1,8 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core %s \
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection %s \
// RUN: -triple x86_64-pc-linux-gnu -verify
+void clang_analyzer_eval(int);
+
#define BINOP(OP) [](auto x, auto y) { return x OP y; }
template <typename BinOp>
@@ -73,3 +75,27 @@ void zoo1backwards() {
*(0 + p) = nullptr; // warn
**(0 + p) = 'a'; // no-warning: this should be unreachable
}
+
+void test_simplified_before_cast_add(long t1) {
+ long t2 = t1 + 3;
+ if (!t2) {
+ int *p = (int *) t2;
+ clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+ }
+}
+
+void test_simplified_before_cast_sub(long t1) {
+ long t2 = t1 - 3;
+ if (!t2) {
+ int *p = (int *) t2;
+ clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+ }
+}
+
+void test_simplified_before_cast_mul(long t1) {
+ long t2 = t1 * 3;
+ if (!t2) {
+ int *p = (int *) t2;
+ clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+ }
+}