aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
diff options
context:
space:
mode:
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