aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-03-23 01:21:23 +0000
committerJordan Rose <jordan_rose@apple.com>2013-03-23 01:21:23 +0000
commit281698935f62ac1d35ddd3533a562c1589aadc8b (patch)
treeebdcb3eb404f96dc1b251a994db95a5574109d2e /lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
parent8569281fb7ce9b5ca164a0528b876acbb45eb989 (diff)
[analyzer] Also transform "a < b" to "(b - a) > 0" in the constraint manager.
We can support the full range of comparison operations between two locations by canonicalizing them as subtraction, as in the previous commit. This won't work (well) if either location includes an offset, or (again) if the comparisons are not consistent about which region comes first. <rdar://problem/13239003> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177803 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp32
1 files changed, 17 insertions, 15 deletions
diff --git a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
index d87c51fed3..4ff248785a 100644
--- a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
@@ -50,7 +50,7 @@ bool SimpleConstraintManager::canReasonAbout(SVal X) const {
}
if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) {
- if (SSE->getOpcode() == BO_EQ || SSE->getOpcode() == BO_NE)
+ if (BinaryOperator::isComparisonOp(SSE->getOpcode()))
return true;
}
@@ -180,26 +180,28 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
}
} else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(sym)) {
- BinaryOperator::Opcode Op = SSE->getOpcode();
-
// Translate "a != b" to "(b - a) != 0".
// We invert the order of the operands as a heuristic for how loop
// conditions are usually written ("begin != end") as compared to length
// calculations ("end - begin"). The more correct thing to do would be to
// canonicalize "a - b" and "b - a", which would allow us to treat
// "a != b" and "b != a" the same.
- if (BinaryOperator::isEqualityOp(Op)) {
- SymbolManager &SymMgr = getSymbolManager();
-
- assert(Loc::isLocType(SSE->getLHS()->getType()));
- assert(Loc::isLocType(SSE->getRHS()->getType()));
- QualType DiffTy = SymMgr.getContext().getPointerDiffType();
- SymbolRef Subtraction = SymMgr.getSymSymExpr(SSE->getRHS(), BO_Sub,
- SSE->getLHS(), DiffTy);
-
- Assumption ^= (SSE->getOpcode() == BO_EQ);
- return assumeAuxForSymbol(state, Subtraction, Assumption);
- }
+ SymbolManager &SymMgr = getSymbolManager();
+ BinaryOperator::Opcode Op = SSE->getOpcode();
+ assert(BinaryOperator::isComparisonOp(Op));
+
+ // For now, we only support comparing pointers.
+ assert(Loc::isLocType(SSE->getLHS()->getType()));
+ assert(Loc::isLocType(SSE->getRHS()->getType()));
+ QualType DiffTy = SymMgr.getContext().getPointerDiffType();
+ SymbolRef Subtraction = SymMgr.getSymSymExpr(SSE->getRHS(), BO_Sub,
+ SSE->getLHS(), DiffTy);
+
+ const llvm::APSInt &Zero = getBasicVals().getValue(0, DiffTy);
+ Op = BinaryOperator::reverseComparisonOp(Op);
+ if (!Assumption)
+ Op = BinaryOperator::negateComparisonOp(Op);
+ return assumeSymRel(state, Subtraction, Op, Zero);
}
// If we get here, there's nothing else we can do but treat the symbol as