summaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
diff options
context:
space:
mode:
authorAnton Yartsev <anton.yartsev@gmail.com>2016-12-23 03:31:00 +0000
committerAnton Yartsev <anton.yartsev@gmail.com>2016-12-23 03:31:00 +0000
commitf090930ae29a82e8152fc64a3f539792da020cf5 (patch)
tree5f70962bfdc2c52680361ac7946003f25691bc5b /lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
parent5d286f24eaf4c0d4ed833cb379bfceefbe800a52 (diff)
downloadclang-f090930ae29a82e8152fc64a3f539792da020cf5.tar.gz
Fix for PR15623. The patch eliminates unwanted ProgramState checker data propagation from an operand of the logical operation to operation result.
The patch also simplifies an assume of a constraint of the form: "(exp comparison_op expr) != 0" to true into an assume of "exp comparison_op expr" to true. (And similarly, an assume of the form "(exp comparison_op expr) == 0" to true as an assume of exp comparison_op expr to false.) which improves precision overall. https://reviews.llvm.org/D22862 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@290413 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
index c5e0f9b862..ef2fcefb05 100644
--- a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
@@ -254,6 +254,21 @@ ProgramStateRef SimpleConstraintManager::assumeSymRel(ProgramStateRef State,
assert(BinaryOperator::isComparisonOp(Op) &&
"Non-comparison ops should be rewritten as comparisons to zero.");
+ SymbolRef Sym = LHS;
+
+ // Simplification: translate an assume of a constraint of the form
+ // "(exp comparison_op expr) != 0" to true into an assume of
+ // "exp comparison_op expr" to true. (And similarly, an assume of the form
+ // "(exp comparison_op expr) == 0" to true into an assume of
+ // "exp comparison_op expr" to false.)
+ if (Int == 0 && (Op == BO_EQ || Op == BO_NE)) {
+ if (const BinarySymExpr *SE = dyn_cast<BinarySymExpr>(Sym)) {
+ BinaryOperator::Opcode Op = SE->getOpcode();
+ if (BinaryOperator::isComparisonOp(Op))
+ return assume(State, nonloc::SymbolVal(Sym), (Op == BO_NE ? true : false));
+ }
+ }
+
// Get the type used for calculating wraparound.
BasicValueFactory &BVF = getBasicVals();
APSIntType WraparoundType = BVF.getAPSIntType(LHS->getType());
@@ -265,7 +280,6 @@ ProgramStateRef SimpleConstraintManager::assumeSymRel(ProgramStateRef State,
// x < 4 has the solution [0, 3]. x+2 < 4 has the solution [0-2, 3-2], which
// in modular arithmetic is [0, 1] U [UINT_MAX-1, UINT_MAX]. It's up to
// the subclasses of SimpleConstraintManager to handle the adjustment.
- SymbolRef Sym = LHS;
llvm::APSInt Adjustment = WraparoundType.getZeroValue();
computeAdjustment(Sym, Adjustment);