diff options
author | dingfei <fding@feysh.com> | 2023-09-15 14:01:26 +0800 |
---|---|---|
committer | Balazs Benics <benicsbalazs@gmail.com> | 2023-09-15 15:07:39 +0200 |
commit | 7c9abbd8a41e85a7e82a454c62138ea72f981597 (patch) | |
tree | 8ba34376cef4513a6b38b76dbf56660ff564d3d0 | |
parent | b0f0aa852d074441fc4dafc138a9cffc3d083dbc (diff) | |
download | llvm-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.cpp | 3 | ||||
-rw-r--r-- | clang/test/Analysis/symbol-simplification-nonloc-loc.cpp | 28 |
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}} + } +} |