aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/GRSimpleVals.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-07-18 15:46:06 +0000
committerTed Kremenek <kremenek@apple.com>2008-07-18 15:46:06 +0000
commit1e38f85dc0ee7a6af439a268c7ce2c12fbd29441 (patch)
treebf5b7347cadec12e129f99b14050adce4e1e205d /lib/Analysis/GRSimpleVals.cpp
parentad8329e58df5b0b2c44dca1447b324467a6c5da1 (diff)
Improve path-sensitivity when using the logical not operator.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53752 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/GRSimpleVals.cpp')
-rw-r--r--lib/Analysis/GRSimpleVals.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/Analysis/GRSimpleVals.cpp b/lib/Analysis/GRSimpleVals.cpp
index cc31ddddef..6cb714a86e 100644
--- a/lib/Analysis/GRSimpleVals.cpp
+++ b/lib/Analysis/GRSimpleVals.cpp
@@ -450,6 +450,15 @@ RVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLVal X) {
// Binary operators.
+static unsigned char LNotOpMap[] = {
+ (unsigned char) BinaryOperator::GE, /* LT => GE */
+ (unsigned char) BinaryOperator::LE, /* GT => LE */
+ (unsigned char) BinaryOperator::GT, /* LE => GT */
+ (unsigned char) BinaryOperator::LT, /* GE => LT */
+ (unsigned char) BinaryOperator::NE, /* EQ => NE */
+ (unsigned char) BinaryOperator::EQ /* NE => EQ */
+};
+
RVal GRSimpleVals::DetermEvalBinOpNN(ValueStateManager& StateMgr,
BinaryOperator::Opcode Op,
NonLVal L, NonLVal R) {
@@ -462,6 +471,31 @@ RVal GRSimpleVals::DetermEvalBinOpNN(ValueStateManager& StateMgr,
default:
return UnknownVal();
+ case nonlval::SymIntConstraintValKind: {
+ const SymIntConstraint& C =
+ cast<nonlval::SymIntConstraintVal>(L).getConstraint();
+
+ BinaryOperator::Opcode Opc = C.getOpcode();
+
+ if (Opc < BinaryOperator::LT || Opc > BinaryOperator::NE)
+ return UnknownVal();
+
+ // For comparison operators, translate the constraint by
+ // changing the opcode.
+
+ int idx = (unsigned) Opc - (unsigned) BinaryOperator::LT;
+
+ assert (idx >= 0 &&
+ (unsigned) idx < sizeof(LNotOpMap)/sizeof(unsigned char));
+
+ Opc = (BinaryOperator::Opcode) LNotOpMap[idx];
+
+ const SymIntConstraint& CNew =
+ BasicVals.getConstraint(C.getSymbol(), Opc, C.getInt());
+
+ return nonlval::SymIntConstraintVal(CNew);
+ }
+
case nonlval::ConcreteIntKind:
if (isa<nonlval::ConcreteInt>(R)) {