diff options
-rw-r--r-- | Analysis/GRConstants.cpp | 17 | ||||
-rw-r--r-- | Analysis/RValues.cpp | 71 | ||||
-rw-r--r-- | Analysis/RValues.h | 14 | ||||
-rw-r--r-- | test/Makefile | 2 |
4 files changed, 89 insertions, 15 deletions
diff --git a/Analysis/GRConstants.cpp b/Analysis/GRConstants.cpp index 2229e473ef..895f0e1025 100644 --- a/Analysis/GRConstants.cpp +++ b/Analysis/GRConstants.cpp @@ -778,7 +778,22 @@ void GRConstants::Visit(Stmt* S, GRConstants::NodeTy* Pred, GRConstants::StateTy GRConstants::Assume(StateTy St, LValue Cond, bool Assumption, bool& isFeasible) { - return St; + + switch (Cond.getSubKind()) { + default: + assert (false && "'Assume' not implemented for this NonLValue."); + return St; + + case LValueDeclKind: + isFeasible = Assumption; + return St; + + case ConcreteIntLValueKind: { + bool b = cast<ConcreteIntLValue>(Cond).getValue() != 0; + isFeasible = b ? Assumption : !Assumption; + return St; + } + } } GRConstants::StateTy GRConstants::Assume(StateTy St, NonLValue Cond, bool Assumption, diff --git a/Analysis/RValues.cpp b/Analysis/RValues.cpp index 4008e765e0..f41051ed57 100644 --- a/Analysis/RValues.cpp +++ b/Analysis/RValues.cpp @@ -79,20 +79,56 @@ APSInt& ValueManager::getValue(uint64_t X, QualType T, SourceLocation Loc) { return getValue(V); } - //===----------------------------------------------------------------------===// -// Transfer function dispatch for Non-LValues. +// Transfer function for Casts. //===----------------------------------------------------------------------===// RValue RValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const { - switch (getSubKind()) { - case ConcreteIntKind: - return cast<ConcreteInt>(this)->Cast(ValMgr, CastExpr); - default: - return InvalidValue(); + switch (getBaseKind()) { + default: assert(false && "Invalid RValue."); break; + case LValueKind: return cast<LValue>(this)->Cast(ValMgr, CastExpr); + case NonLValueKind: return cast<NonLValue>(this)->Cast(ValMgr, CastExpr); + case UninitializedKind: case InvalidKind: break; } + + return *this; +} + +RValue LValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const { + if (CastExpr->getType()->isPointerType()) + return *this; + + assert (CastExpr->getType()->isIntegerType()); + + if (!isa<ConcreteIntLValue>(*this)) + return InvalidValue(); + + APSInt V = cast<ConcreteIntLValue>(this)->getValue(); + QualType T = CastExpr->getType(); + V.setIsUnsigned(T->isUnsignedIntegerType()); + V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart())); + return ConcreteInt(ValMgr.getValue(V)); } +RValue NonLValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const { + if (!isa<ConcreteInt>(this)) + return InvalidValue(); + + APSInt V = cast<ConcreteInt>(this)->getValue(); + QualType T = CastExpr->getType(); + V.setIsUnsigned(T->isUnsignedIntegerType()); + V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart())); + + if (CastExpr->getType()->isPointerType()) + return ConcreteIntLValue(ValMgr.getValue(V)); + else + return ConcreteInt(ValMgr.getValue(V)); +} + +//===----------------------------------------------------------------------===// +// Transfer function dispatch for Non-LValues. +//===----------------------------------------------------------------------===// + NonLValue NonLValue::UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const { switch (getSubKind()) { case ConcreteIntKind: @@ -162,6 +198,13 @@ NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const { default: assert(false && "EQ not implemented for this LValue."); return cast<NonLValue>(InvalidValue()); + + case ConcreteIntLValueKind: { + bool b = cast<ConcreteIntLValue>(this)->getValue() == + cast<ConcreteIntLValue>(RHS).getValue(); + + return NonLValue::GetIntTruthValue(ValMgr, b); + } case LValueDeclKind: { bool b = cast<LValueDecl>(*this) == cast<LValueDecl>(RHS); @@ -179,6 +222,13 @@ NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const { assert(false && "EQ not implemented for this LValue."); return cast<NonLValue>(InvalidValue()); + case ConcreteIntLValueKind: { + bool b = cast<ConcreteIntLValue>(this)->getValue() != + cast<ConcreteIntLValue>(RHS).getValue(); + + return NonLValue::GetIntTruthValue(ValMgr, b); + } + case LValueDeclKind: { bool b = cast<LValueDecl>(*this) != cast<LValueDecl>(RHS); return NonLValue::GetIntTruthValue(ValMgr, b); @@ -255,7 +305,12 @@ void NonLValue::print(std::ostream& Out) const { } void LValue::print(std::ostream& Out) const { - switch (getSubKind()) { + switch (getSubKind()) { + case ConcreteIntLValueKind: + Out << cast<ConcreteIntLValue>(this)->getValue().toString() + << " (LValue)"; + break; + case SymbolicLValueKind: Out << '$' << cast<SymbolicLValue>(this)->getSymbolID(); break; diff --git a/Analysis/RValues.h b/Analysis/RValues.h index 989c60bb3f..c5ad8a5327 100644 --- a/Analysis/RValues.h +++ b/Analysis/RValues.h @@ -187,6 +187,8 @@ protected: public: void print(std::ostream& Out) const; + RValue Cast(ValueManager& ValMgr, Expr* CastExpr) const; + // Arithmetic operators. NonLValue Add(ValueManager& ValMgr, const NonLValue& RHS) const; NonLValue Sub(ValueManager& ValMgr, const NonLValue& RHS) const; @@ -199,6 +201,7 @@ public: NonLValue EQ(ValueManager& ValMgr, const NonLValue& RHS) const; NonLValue NE(ValueManager& ValMgr, const NonLValue& RHS) const; + // Utility methods to create NonLValues. static NonLValue GetValue(ValueManager& ValMgr, uint64_t X, QualType T, SourceLocation Loc = SourceLocation()); @@ -223,6 +226,8 @@ protected: public: void print(std::ostream& Out) const; + RValue Cast(ValueManager& ValMgr, Expr* CastExpr) const; + // Equality operators. NonLValue EQ(ValueManager& ValMgr, const LValue& RHS) const; NonLValue NE(ValueManager& ValMgr, const LValue& RHS) const; @@ -237,8 +242,7 @@ public: // Subclasses of NonLValue. //==------------------------------------------------------------------------==// -enum NonLValueKind { SymbolicNonLValueKind, ConcreteIntKind, -NumNonLValueKind }; +enum NonLValueKind { SymbolicNonLValueKind, ConcreteIntKind, NumNonLValueKind }; class SymbolicNonLValue : public NonLValue { public: @@ -326,9 +330,9 @@ public: // Subclasses of LValue. //==------------------------------------------------------------------------==// -enum LValueKind { SymbolicLValueKind, LValueDeclKind, -ConcreteIntLValueKind, NumLValueKind }; - +enum LValueKind { SymbolicLValueKind, LValueDeclKind, ConcreteIntLValueKind, + NumLValueKind }; + class SymbolicLValue : public LValue { public: SymbolicLValue(unsigned SymID) diff --git a/test/Makefile b/test/Makefile index 91928cafb8..269ddfe497 100644 --- a/test/Makefile +++ b/test/Makefile @@ -3,6 +3,6 @@ include $(LEVEL)/Makefile.common all:: PATH=$$PATH:$(ToolDir):$(LLVM_SRC_ROOT)/test/Scripts find\ - CodeGen Lexer Preprocessor Parser Sema Analysis Serialization\ + Lexer Preprocessor Parser Sema Analysis Serialization\ \( -name '*.c' -or -name '*.cpp' -or -name '*.m' \)\ -print -exec ./TestRunner.sh {} \; |