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
diff --git a/lib/Analysis/GRSimpleVals.cpp b/lib/Analysis/GRSimpleVals.cpp
index cc31ddd..6cb714a 100644
--- a/lib/Analysis/GRSimpleVals.cpp
+++ b/lib/Analysis/GRSimpleVals.cpp
@@ -450,6 +450,15 @@
// 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 @@
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)) {