Migrated transfer functions for binary operators for simple value tracking
from RValues to GRTransferFuncs/GRSimpleVals.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47131 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Analysis/GRSimpleVals.cpp b/Analysis/GRSimpleVals.cpp
index a2711c7..200c9a3 100644
--- a/Analysis/GRSimpleVals.cpp
+++ b/Analysis/GRSimpleVals.cpp
@@ -79,3 +79,161 @@
return cast<NonLValue>(UnknownVal());
}
}
+
+// Binary operators.
+
+NonLValue GRSimpleVals::EvalBinaryOp(ValueManager& ValMgr,
+ BinaryOperator::Opcode Op,
+ NonLValue LHS, NonLValue RHS) {
+
+ if (isa<UnknownVal>(LHS) || isa<UnknownVal>(RHS))
+ return cast<NonLValue>(UnknownVal());
+
+ if (isa<UninitializedVal>(LHS) || isa<UninitializedVal>(RHS))
+ return cast<NonLValue>(UninitializedVal());
+
+ while(1) {
+
+ switch (LHS.getSubKind()) {
+ default:
+ return cast<NonLValue>(UnknownVal());
+
+ case nonlval::ConcreteIntKind:
+
+ if (isa<nonlval::ConcreteInt>(RHS)) {
+ const nonlval::ConcreteInt& LHS_CI = cast<nonlval::ConcreteInt>(LHS);
+ const nonlval::ConcreteInt& RHS_CI = cast<nonlval::ConcreteInt>(RHS);
+ return LHS_CI.EvalBinaryOp(ValMgr, Op, RHS_CI);
+ }
+ else if(isa<UnknownVal>(RHS))
+ return cast<NonLValue>(UnknownVal());
+ else {
+ NonLValue tmp = RHS;
+ RHS = LHS;
+ LHS = tmp;
+ continue;
+ }
+
+ case nonlval::SymbolValKind: {
+ if (isa<nonlval::ConcreteInt>(RHS)) {
+ const SymIntConstraint& C =
+ ValMgr.getConstraint(cast<nonlval::SymbolVal>(LHS).getSymbol(), Op,
+ cast<nonlval::ConcreteInt>(RHS).getValue());
+
+ return nonlval::SymIntConstraintVal(C);
+ }
+ else
+ return cast<NonLValue>(UnknownVal());
+ }
+ }
+ }
+}
+
+// Equality operators for LValues.
+
+
+NonLValue GRSimpleVals::EvalEQ(ValueManager& ValMgr, LValue LHS, LValue RHS) {
+
+ switch (LHS.getSubKind()) {
+ default:
+ assert(false && "EQ not implemented for this LValue.");
+ return cast<NonLValue>(UnknownVal());
+
+ case lval::ConcreteIntKind:
+ if (isa<lval::ConcreteInt>(RHS)) {
+ bool b = cast<lval::ConcreteInt>(LHS).getValue() ==
+ cast<lval::ConcreteInt>(RHS).getValue();
+
+ return NonLValue::GetIntTruthValue(ValMgr, b);
+ }
+ else if (isa<lval::SymbolVal>(RHS)) {
+
+ const SymIntConstraint& C =
+ ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
+ BinaryOperator::EQ,
+ cast<lval::ConcreteInt>(LHS).getValue());
+
+ return nonlval::SymIntConstraintVal(C);
+ }
+
+ break;
+
+ case lval::SymbolValKind: {
+ if (isa<lval::ConcreteInt>(RHS)) {
+ const SymIntConstraint& C =
+ ValMgr.getConstraint(cast<lval::SymbolVal>(LHS).getSymbol(),
+ BinaryOperator::EQ,
+ cast<lval::ConcreteInt>(RHS).getValue());
+
+ return nonlval::SymIntConstraintVal(C);
+ }
+
+ assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement unification.");
+
+ break;
+ }
+
+ case lval::DeclValKind:
+
+ if (isa<lval::DeclVal>(RHS)) {
+ bool b = cast<lval::DeclVal>(LHS) == cast<lval::DeclVal>(RHS);
+ return NonLValue::GetIntTruthValue(ValMgr, b);
+ }
+
+ break;
+ }
+
+ return NonLValue::GetIntTruthValue(ValMgr, false);
+}
+
+NonLValue GRSimpleVals::EvalNE(ValueManager& ValMgr, LValue LHS, LValue RHS) {
+
+ switch (LHS.getSubKind()) {
+ default:
+ assert(false && "NE not implemented for this LValue.");
+ return cast<NonLValue>(UnknownVal());
+
+ case lval::ConcreteIntKind:
+ if (isa<lval::ConcreteInt>(RHS)) {
+ bool b = cast<lval::ConcreteInt>(LHS).getValue() !=
+ cast<lval::ConcreteInt>(RHS).getValue();
+
+ return NonLValue::GetIntTruthValue(ValMgr, b);
+ }
+ else if (isa<lval::SymbolVal>(RHS)) {
+ const SymIntConstraint& C =
+ ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
+ BinaryOperator::NE,
+ cast<lval::ConcreteInt>(LHS).getValue());
+
+ return nonlval::SymIntConstraintVal(C);
+ }
+
+ break;
+
+ case lval::SymbolValKind: {
+ if (isa<lval::ConcreteInt>(RHS)) {
+ const SymIntConstraint& C =
+ ValMgr.getConstraint(cast<lval::SymbolVal>(LHS).getSymbol(),
+ BinaryOperator::NE,
+ cast<lval::ConcreteInt>(RHS).getValue());
+
+ return nonlval::SymIntConstraintVal(C);
+ }
+
+ assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement sym !=.");
+
+ break;
+ }
+
+ case lval::DeclValKind:
+ if (isa<lval::DeclVal>(RHS)) {
+ bool b = cast<lval::DeclVal>(LHS) == cast<lval::DeclVal>(RHS);
+ return NonLValue::GetIntTruthValue(ValMgr, b);
+ }
+
+ break;
+ }
+
+ return NonLValue::GetIntTruthValue(ValMgr, true);
+}