[PATCH] D97874: [analyzer] Improve SVal cast from integer to bool using known RangeSet
Denys Petrov via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 9 03:39:52 PST 2021
ASDenysPetrov updated this revision to Diff 329282.
ASDenysPetrov added a comment.
Updated due to discussion.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D97874/new/
https://reviews.llvm.org/D97874
Files:
clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
clang/test/Analysis/cast_symbolic_ints_to_bool.cpp
Index: clang/test/Analysis/cast_symbolic_ints_to_bool.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/cast_symbolic_ints_to_bool.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
+
+template <typename T>
+void clang_analyzer_dump(T);
+
+void test_int_to_bool(bool b, int x) {
+ clang_analyzer_dump(b); // expected-warning{{reg_$0<_Bool b>}}
+ b = x;
+ clang_analyzer_dump(b); // expected-warning{{reg_$1<int x>}}
+ if (x < 0) {
+ b = x;
+ clang_analyzer_dump(b); // expected-warning{{1 U1b}}
+ } else if (x > 0) {
+ b = x;
+ clang_analyzer_dump(b); // expected-warning{{1 U1b}}
+ } else {
+ b = x;
+ clang_analyzer_dump(b); // expected-warning{{0 U1b}}
+ }
+}
+
+void test_char_to_bool(char x) {
+ bool b = x;
+ clang_analyzer_dump(b); // expected-warning{{reg_$0<char x>}}
+ if (x < 0) {
+ bool b = x;
+ clang_analyzer_dump(b); // expected-warning{{1 U1b}}
+ } else if (x > 0) {
+ bool b = x;
+ clang_analyzer_dump(b); // expected-warning{{1 U1b}}
+ } else {
+ bool b = x;
+ clang_analyzer_dump(b); // expected-warning{{0 U1b}}
+ }
+}
+
+void test_unsigned_to_bool(bool b, unsigned x) {
+ clang_analyzer_dump(b); // expected-warning{{reg_$0<_Bool b>}}
+ b = x;
+ clang_analyzer_dump(b); // expected-warning{{reg_$1<unsigned int x>}}
+ if (x) {
+ b = x;
+ clang_analyzer_dump(b); // expected-warning{{1 U1b}}
+ } else {
+ b = x;
+ clang_analyzer_dump(b); // expected-warning{{0 U1b}}
+ }
+}
+
+void test_unsigned_to_bool(unsigned char x) {
+ bool b = x;
+ clang_analyzer_dump(b); // expected-warning{{reg_$0<unsigned char x>}}
+ if (x < 42) {
+ b = x;
+ clang_analyzer_dump(b); // expected-warning{{reg_$0<unsigned char x>}}
+ if (x) {
+ b = x;
+ clang_analyzer_dump(b); // expected-warning{{1 U1b}}
+ } else {
+ b = x;
+ clang_analyzer_dump(b); // expected-warning{{0 U1b}}
+ }
+ } else {
+ b = x;
+ clang_analyzer_dump(b); // expected-warning{{1 U1b}}
+ }
+}
Index: clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -871,12 +871,16 @@
// Symbol to bool.
if (!OriginalTy.isNull() && CastTy->isBooleanType()) {
- // Non-float to bool.
- if (Loc::isLocType(OriginalTy) ||
- OriginalTy->isIntegralOrEnumerationType() ||
- OriginalTy->isMemberPointerType()) {
- BasicValueFactory &BVF = getBasicValueFactory();
- return makeNonLoc(SE, BO_NE, BVF.getValue(0, SE->getType()), CastTy);
+ // Symbolic integer to bool.
+ if (OriginalTy->isIntegralOrEnumerationType()) {
+
+ // Integer is known to be non-zero or zero only.
+ auto truth = State->isNonNull(V);
+ if (truth.isConstrained())
+ return makeTruthVal(truth.isConstrainedTrue(), CastTy);
+
+ // Unconstrained integer to bool.
+ return V;
}
} else {
// Symbol to integer.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D97874.329282.patch
Type: text/x-patch
Size: 3106 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210309/c24096c5/attachment-0001.bin>
More information about the cfe-commits
mailing list