aboutsummaryrefslogtreecommitdiff
path: root/Analysis/ValueManager.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-02-28 20:32:03 +0000
committerTed Kremenek <kremenek@apple.com>2008-02-28 20:32:03 +0000
commit8cc13ea74fea1c04042a2f4087665bc5182e8408 (patch)
tree996f3f92d5bb864a909f3a75bd85979de9865ea0 /Analysis/ValueManager.cpp
parentf9ce5b049e4d31b1ff45767bf7b813fba37f0305 (diff)
Added checking for undefined results of '<<' and '>>' (shifting by too many bits, etc.)
This current implementation only works when both operands are concrete values; later we will add support for symbolic values. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47726 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Analysis/ValueManager.cpp')
-rw-r--r--Analysis/ValueManager.cpp68
1 files changed, 49 insertions, 19 deletions
diff --git a/Analysis/ValueManager.cpp b/Analysis/ValueManager.cpp
index 64f4b27d3f..2a8d23d02c 100644
--- a/Analysis/ValueManager.cpp
+++ b/Analysis/ValueManager.cpp
@@ -76,7 +76,7 @@ ValueManager::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
return *C;
}
-const llvm::APSInt&
+const llvm::APSInt*
ValueManager::EvaluateAPSInt(BinaryOperator::Opcode Op,
const llvm::APSInt& V1, const llvm::APSInt& V2) {
@@ -85,53 +85,83 @@ ValueManager::EvaluateAPSInt(BinaryOperator::Opcode Op,
assert (false && "Invalid Opcode.");
case BinaryOperator::Mul:
- return getValue( V1 * V2 );
+ return &getValue( V1 * V2 );
case BinaryOperator::Div:
- return getValue( V1 / V2 );
+ return &getValue( V1 / V2 );
case BinaryOperator::Rem:
- return getValue( V1 % V2 );
+ return &getValue( V1 % V2 );
case BinaryOperator::Add:
- return getValue( V1 + V2 );
+ return &getValue( V1 + V2 );
case BinaryOperator::Sub:
- return getValue( V1 - V2 );
+ return &getValue( V1 - V2 );
- case BinaryOperator::Shl:
- return getValue( V1.operator<<( (unsigned) V2.getZExtValue() ));
+ case BinaryOperator::Shl: {
+
+ // FIXME: This logic should probably go higher up, where we can
+ // test these conditions symbolically.
+
+ // FIXME: Expand these checks to include all undefined behavior.
+
+ if (V2.isSigned() && V2.isNegative())
+ return NULL;
+
+ uint64_t Amt = V2.getZExtValue();
+
+ if (Amt > V1.getBitWidth())
+ return NULL;
+
+ return &getValue( V1.operator<<( (unsigned) Amt ));
+ }
+
+ case BinaryOperator::Shr: {
+
+ // FIXME: This logic should probably go higher up, where we can
+ // test these conditions symbolically.
+
+ // FIXME: Expand these checks to include all undefined behavior.
+
+ if (V2.isSigned() && V2.isNegative())
+ return NULL;
+
+ uint64_t Amt = V2.getZExtValue();
+
+ if (Amt > V1.getBitWidth())
+ return NULL;
- case BinaryOperator::Shr:
- return getValue( V1.operator>>( (unsigned) V2.getZExtValue() ));
+ return &getValue( V1.operator>>( (unsigned) Amt ));
+ }
case BinaryOperator::LT:
- return getTruthValue( V1 < V2 );
+ return &getTruthValue( V1 < V2 );
case BinaryOperator::GT:
- return getTruthValue( V1 > V2 );
+ return &getTruthValue( V1 > V2 );
case BinaryOperator::LE:
- return getTruthValue( V1 <= V2 );
+ return &getTruthValue( V1 <= V2 );
case BinaryOperator::GE:
- return getTruthValue( V1 >= V2 );
+ return &getTruthValue( V1 >= V2 );
case BinaryOperator::EQ:
- return getTruthValue( V1 == V2 );
+ return &getTruthValue( V1 == V2 );
case BinaryOperator::NE:
- return getTruthValue( V1 != V2 );
+ return &getTruthValue( V1 != V2 );
// Note: LAnd, LOr, Comma are handled specially by higher-level logic.
case BinaryOperator::And:
- return getValue( V1 & V2 );
+ return &getValue( V1 & V2 );
case BinaryOperator::Or:
- return getValue( V1 | V2 );
+ return &getValue( V1 | V2 );
case BinaryOperator::Xor:
- return getValue( V1 ^ V2 );
+ return &getValue( V1 ^ V2 );
}
}