[PATCH] D110910: [analyzer][solver] Fix CmpOpTable handling bug
Gabor Marton via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 6 09:28:23 PDT 2021
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG792be5df92e8: [analyzer][solver] Fix CmpOpTable handling bug (authored by martong).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D110910/new/
https://reviews.llvm.org/D110910
Files:
clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
clang/test/Analysis/constraint_manager_conditions.cpp
Index: clang/test/Analysis/constraint_manager_conditions.cpp
===================================================================
--- clang/test/Analysis/constraint_manager_conditions.cpp
+++ clang/test/Analysis/constraint_manager_conditions.cpp
@@ -211,3 +211,17 @@
clang_analyzer_eval(y != x); // expected-warning{{FALSE}}
}
}
+
+// Test the logic of reaching the `Unknonw` tristate in CmpOpTable.
+void cmp_op_table_unknownX2(int x, int y, int z) {
+ if (x >= y) {
+ // x >= y [1, 1]
+ if (x + z < y)
+ return;
+ // x + z < y [0, 0]
+ if (z != 0)
+ return;
+ // x < y [0, 0]
+ clang_analyzer_eval(x > y); // expected-warning{{TRUE}} expected-warning{{FALSE}}
+ }
+}
Index: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -1112,7 +1112,7 @@
if (!SSE)
return llvm::None;
- BinaryOperatorKind CurrentOP = SSE->getOpcode();
+ const BinaryOperatorKind CurrentOP = SSE->getOpcode();
// We currently do not support <=> (C++20).
if (!BinaryOperator::isComparisonOp(CurrentOP) || (CurrentOP == BO_Cmp))
@@ -1126,7 +1126,12 @@
SymbolManager &SymMgr = State->getSymbolManager();
- int UnknownStates = 0;
+ // We use this variable to store the last queried operator (`QueriedOP`)
+ // for which the `getCmpOpState` returned with `Unknown`. If there are two
+ // different OPs that returned `Unknown` then we have to query the special
+ // `UnknownX2` column. We assume that `getCmpOpState(CurrentOP, CurrentOP)`
+ // never returns `Unknown`, so `CurrentOP` is a good initial value.
+ BinaryOperatorKind LastQueriedOpToUnknown = CurrentOP;
// Loop goes through all of the columns exept the last one ('UnknownX2').
// We treat `UnknownX2` column separately at the end of the loop body.
@@ -1163,15 +1168,18 @@
CmpOpTable.getCmpOpState(CurrentOP, QueriedOP);
if (BranchState == OperatorRelationsTable::Unknown) {
- if (++UnknownStates == 2)
- // If we met both Unknown states.
+ if (LastQueriedOpToUnknown != CurrentOP &&
+ LastQueriedOpToUnknown != QueriedOP) {
+ // If we got the Unknown state for both different operators.
// if (x <= y) // assume true
// if (x != y) // assume true
// if (x < y) // would be also true
// Get a state from `UnknownX2` column.
BranchState = CmpOpTable.getCmpOpStateForUnknownX2(CurrentOP);
- else
+ } else {
+ LastQueriedOpToUnknown = QueriedOP;
continue;
+ }
}
return (BranchState == OperatorRelationsTable::True) ? getTrueRange(T)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D110910.377571.patch
Type: text/x-patch
Size: 2915 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20211006/313a2fed/attachment-0001.bin>
More information about the cfe-commits
mailing list