diff options
Diffstat (limited to 'lib/Analysis')
-rw-r--r-- | lib/Analysis/BugReporter.cpp | 2 | ||||
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 16 | ||||
-rw-r--r-- | lib/Analysis/CMakeLists.txt | 3 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 67 | ||||
-rw-r--r-- | lib/Analysis/GRSimpleVals.cpp | 414 | ||||
-rw-r--r-- | lib/Analysis/GRTransferFuncs.cpp | 27 | ||||
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 2 | ||||
-rw-r--r-- | lib/Analysis/SVals.cpp | 24 |
8 files changed, 37 insertions, 518 deletions
diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp index 9c9029cfff..38ea458a65 100644 --- a/lib/Analysis/BugReporter.cpp +++ b/lib/Analysis/BugReporter.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // This file defines BugReporter, a utility class for generating -// PathDiagnostics for analyses based on GRSimpleVals. +// PathDiagnostics. // //===----------------------------------------------------------------------===// diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 5e542a3c48..f4a28e0c19 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -12,7 +12,6 @@ // //===----------------------------------------------------------------------===// -#include "GRSimpleVals.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceManager.h" #include "clang/Analysis/PathSensitive/GRExprEngineBuilders.h" @@ -22,6 +21,7 @@ #include "clang/Analysis/PathDiagnostic.h" #include "clang/Analysis/PathSensitive/BugReporter.h" #include "clang/Analysis/PathSensitive/SymbolManager.h" +#include "clang/Analysis/PathSensitive/GRTransferFuncs.h" #include "clang/AST/DeclObjC.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" @@ -1826,7 +1826,7 @@ static const GRState * SendAutorelease(const GRState *state, namespace { -class VISIBILITY_HIDDEN CFRefCount : public GRSimpleVals { +class VISIBILITY_HIDDEN CFRefCount : public GRTransferFuncs { public: class BindingsPrinter : public GRState::Printer { public: @@ -2789,10 +2789,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst, if (Summ.getArg(idx) == DoNothingByRef) continue; - // Invalidate the value of the variable passed by reference. - - // FIXME: Either this logic should also be replicated in GRSimpleVals - // or should be pulled into a separate "constraint engine." + // Invalidate the value of the variable passed by reference. // FIXME: We can have collisions on the conjured symbol if the // expression *I also creates conjured symbols. We probably want @@ -2941,11 +2938,10 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst, default: assert (false && "Unhandled RetEffect."); break; - case RetEffect::NoRet: { - + case RetEffect::NoRet: { // Make up a symbol for the return value (not reference counted). - // FIXME: This is basically copy-and-paste from GRSimpleVals. We - // should compose behavior, not copy it. + // FIXME: Most of this logic is not specific to the retain/release + // checker. // FIXME: We eventually should handle structs and other compound types // that are returned by value. diff --git a/lib/Analysis/CMakeLists.txt b/lib/Analysis/CMakeLists.txt index e064e3c71a..7d6a619736 100644 --- a/lib/Analysis/CMakeLists.txt +++ b/lib/Analysis/CMakeLists.txt @@ -18,15 +18,14 @@ add_clang_library(clangAnalysis GRCoreEngine.cpp GRExprEngine.cpp GRExprEngineInternalChecks.cpp - GRSimpleVals.cpp GRState.cpp - GRTransferFuncs.cpp LiveVariables.cpp MemRegion.cpp PathDiagnostic.cpp RangeConstraintManager.cpp RegionStore.cpp SimpleConstraintManager.cpp + SimpleSValuator.cpp Store.cpp SVals.cpp SymbolManager.cpp diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index d3df92df34..779d70661c 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -15,7 +15,6 @@ #include "clang/Analysis/PathSensitive/GRExprEngine.h" #include "clang/Analysis/PathSensitive/GRExprEngineBuilders.h" -#include "clang/Analysis/PathSensitive/BugReporter.h" #include "clang/AST/ParentMap.h" #include "clang/AST/StmtObjC.h" #include "clang/Basic/Builtins.h" @@ -126,6 +125,7 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, StateMgr(G.getContext(), SMC, CMC, G.getAllocator(), cfg, CD, L), SymMgr(StateMgr.getSymbolManager()), ValMgr(StateMgr.getValueManager()), + SVator(clang::CreateSimpleSValuator(ValMgr)), // FIXME: Generalize later. CurrentStmt(NULL), NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL), RaiseSel(GetNullarySelector("raise", G.getContext())), @@ -1296,9 +1296,8 @@ static bool EvalOSAtomicCompareAndSwap(ExplodedNodeSet<GRState>& Dst, SVal oldValueVal = stateLoad->getSVal(oldValueExpr); // Perform the comparison. - SVal Cmp = Engine.EvalBinOp(stateLoad, - BinaryOperator::EQ, theValueVal, oldValueVal, - Engine.getContext().IntTy); + SVal Cmp = Engine.EvalBinOp(stateLoad, BinaryOperator::EQ, theValueVal, + oldValueVal, Engine.getContext().IntTy); const GRState *stateEqual = stateLoad->assume(Cmp, true); @@ -2562,7 +2561,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, case UnaryOperator::Minus: // FIXME: Do we need to handle promotions? - state = state->bindExpr(U, EvalMinus(U, cast<NonLoc>(V))); + state = state->bindExpr(U, EvalMinus(cast<NonLoc>(V))); break; case UnaryOperator::LNot: @@ -2571,25 +2570,21 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, // // Note: technically we do "E == 0", but this is the same in the // transfer functions as "0 == E". + SVal Result; if (isa<Loc>(V)) { Loc X = ValMgr.makeNull(); - SVal Result = EvalBinOp(state,BinaryOperator::EQ, cast<Loc>(V), X, - U->getType()); - state = state->bindExpr(U, Result); + Result = EvalBinOp(state, BinaryOperator::EQ, cast<Loc>(V), X, + U->getType()); } else { nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType())); -#if 0 - SVal Result = EvalBinOp(BinaryOperator::EQ, cast<NonLoc>(V), X); - state = SetSVal(state, U, Result); -#else - EvalBinOp(Dst, U, BinaryOperator::EQ, cast<NonLoc>(V), X, *I, - U->getType()); - continue; -#endif + Result = EvalBinOp(BinaryOperator::EQ, cast<NonLoc>(V), X, + U->getType()); } + state = state->bindExpr(U, Result); + break; } @@ -2640,8 +2635,8 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, Builder->getCurrentBlockCount()); // If the value is a location, ++/-- should always preserve - // non-nullness. Check if the original value was non-null, and if so propagate - // that constraint. + // non-nullness. Check if the original value was non-null, and if so + // propagate that constraint. if (Loc::IsLocType(U->getType())) { SVal Constraint = EvalBinOp(state, BinaryOperator::EQ, V2, ValMgr.makeZeroVal(U->getType()), @@ -2907,9 +2902,8 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, if (B->isAssignmentOp()) break; - // Process non-assignements except commas or short-circuited - // logical expressions (LAnd and LOr). - + // Process non-assignments except commas or short-circuited + // logical expressions (LAnd and LOr). SVal Result = EvalBinOp(state, Op, LeftV, RightV, B->getType()); if (Result.isUnknown()) { @@ -3024,7 +3018,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, } // Compute the result of the operation. - SVal Result = EvalCast(EvalBinOp(state, Op, V, RightV, CTy), + SVal Result = EvalCast(EvalBinOp(state, Op, V, RightV, CTy), B->getType()); if (Result.isUndef()) { @@ -3073,26 +3067,6 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, // Transfer-function Helpers. //===----------------------------------------------------------------------===// -void GRExprEngine::EvalBinOp(ExplodedNodeSet<GRState>& Dst, Expr* Ex, - BinaryOperator::Opcode Op, - NonLoc L, NonLoc R, - ExplodedNode<GRState>* Pred, QualType T) { - - GRStateSet OStates; - EvalBinOp(OStates, GetState(Pred), Ex, Op, L, R, T); - - for (GRStateSet::iterator I=OStates.begin(), E=OStates.end(); I!=E; ++I) - MakeNode(Dst, Ex, Pred, *I); -} - -void GRExprEngine::EvalBinOp(GRStateSet& OStates, const GRState* state, - Expr* Ex, BinaryOperator::Opcode Op, - NonLoc L, NonLoc R, QualType T) { - - GRStateSet::AutoPopulate AP(OStates, state); - if (R.isValid()) getTF().EvalBinOpNN(OStates, *this, state, Ex, Op, L, R, T); -} - SVal GRExprEngine::EvalBinOp(const GRState* state, BinaryOperator::Opcode Op, SVal L, SVal R, QualType T) { @@ -3104,9 +3078,9 @@ SVal GRExprEngine::EvalBinOp(const GRState* state, BinaryOperator::Opcode Op, if (isa<Loc>(L)) { if (isa<Loc>(R)) - return getTF().EvalBinOp(*this, Op, cast<Loc>(L), cast<Loc>(R)); + return SVator->EvalBinOpLL(Op, cast<Loc>(L), cast<Loc>(R), T); else - return getTF().EvalBinOp(*this, state, Op, cast<Loc>(L), cast<NonLoc>(R)); + return SVator->EvalBinOpLN(state, Op, cast<Loc>(L), cast<NonLoc>(R), T); } if (isa<Loc>(R)) { @@ -3116,11 +3090,10 @@ SVal GRExprEngine::EvalBinOp(const GRState* state, BinaryOperator::Opcode Op, assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub); // Commute the operands. - return getTF().EvalBinOp(*this, state, Op, cast<Loc>(R), cast<NonLoc>(L)); + return SVator->EvalBinOpLN(state, Op, cast<Loc>(R), cast<NonLoc>(L), T); } else - return getTF().DetermEvalBinOpNN(*this, Op, cast<NonLoc>(L), - cast<NonLoc>(R), T); + return SVator->EvalBinOpNN(Op, cast<NonLoc>(L), cast<NonLoc>(R), T); } //===----------------------------------------------------------------------===// diff --git a/lib/Analysis/GRSimpleVals.cpp b/lib/Analysis/GRSimpleVals.cpp deleted file mode 100644 index 9a1b2fc05e..0000000000 --- a/lib/Analysis/GRSimpleVals.cpp +++ /dev/null @@ -1,414 +0,0 @@ -// GRSimpleVals.cpp - Transfer functions for tracking simple values -*- C++ -*-- -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines GRSimpleVals, a sub-class of GRTransferFuncs that -// provides transfer functions for performing simple value tracking with -// limited support for symbolics. -// -//===----------------------------------------------------------------------===// - -#include "GRSimpleVals.h" -#include "BasicObjCFoundationChecks.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Analysis/PathDiagnostic.h" -#include "clang/Analysis/PathSensitive/GRState.h" -#include "clang/Analysis/PathSensitive/BugReporter.h" -#include "clang/Analysis/LocalCheckers.h" -#include "clang/Analysis/PathSensitive/GRExprEngine.h" -#include "llvm/Support/Compiler.h" -#include <sstream> - -using namespace clang; - -//===----------------------------------------------------------------------===// -// Transfer Function creation for External clients. -//===----------------------------------------------------------------------===// - -GRTransferFuncs* clang::MakeGRSimpleValsTF() { return new GRSimpleVals(); } - -//===----------------------------------------------------------------------===// -// Transfer function for Casts. -//===----------------------------------------------------------------------===// - -SVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLoc X, QualType T) { - - if (!isa<nonloc::ConcreteInt>(X)) - return UnknownVal(); - - bool isLocType = Loc::IsLocType(T); - - // Only handle casts from integers to integers. - if (!isLocType && !T->isIntegerType()) - return UnknownVal(); - - BasicValueFactory& BasicVals = Eng.getBasicVals(); - - llvm::APSInt V = cast<nonloc::ConcreteInt>(X).getValue(); - V.setIsUnsigned(T->isUnsignedIntegerType() || Loc::IsLocType(T)); - V.extOrTrunc(Eng.getContext().getTypeSize(T)); - - if (isLocType) - return loc::ConcreteInt(BasicVals.getValue(V)); - else - return nonloc::ConcreteInt(BasicVals.getValue(V)); -} - -// Casts. - -SVal GRSimpleVals::EvalCast(GRExprEngine& Eng, Loc X, QualType T) { - - // Casts from pointers -> pointers, just return the lval. - // - // Casts from pointers -> references, just return the lval. These - // can be introduced by the frontend for corner cases, e.g - // casting from va_list* to __builtin_va_list&. - // - assert (!X.isUnknownOrUndef()); - - if (Loc::IsLocType(T) || T->isReferenceType()) - return X; - - // FIXME: Handle transparent unions where a value can be "transparently" - // lifted into a union type. - if (T->isUnionType()) - return UnknownVal(); - - assert (T->isIntegerType()); - BasicValueFactory& BasicVals = Eng.getBasicVals(); - unsigned BitWidth = Eng.getContext().getTypeSize(T); - - if (!isa<loc::ConcreteInt>(X)) - return Eng.getValueManager().makeLocAsInteger(X, BitWidth); - - llvm::APSInt V = cast<loc::ConcreteInt>(X).getValue(); - V.setIsUnsigned(T->isUnsignedIntegerType() || Loc::IsLocType(T)); - V.extOrTrunc(BitWidth); - return nonloc::ConcreteInt(BasicVals.getValue(V)); -} - -// Unary operators. - -SVal GRSimpleVals::EvalMinus(GRExprEngine& Eng, UnaryOperator* U, NonLoc X){ - - switch (X.getSubKind()) { - - case nonloc::ConcreteIntKind: - return cast<nonloc::ConcreteInt>(X).EvalMinus(Eng.getBasicVals(), U); - - default: - return UnknownVal(); - } -} - -SVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLoc X) { - - switch (X.getSubKind()) { - - case nonloc::ConcreteIntKind: - return cast<nonloc::ConcreteInt>(X).EvalComplement(Eng.getBasicVals()); - - default: - return UnknownVal(); - } -} - -// 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 */ -}; - -SVal GRSimpleVals::DetermEvalBinOpNN(GRExprEngine& Eng, - BinaryOperator::Opcode Op, - NonLoc L, NonLoc R, - QualType T) { - BasicValueFactory& BasicVals = Eng.getBasicVals(); - ValueManager& ValMgr = Eng.getValueManager(); - unsigned subkind = L.getSubKind(); - - while (1) { - - switch (subkind) { - default: - return UnknownVal(); - - case nonloc::LocAsIntegerKind: { - Loc LL = cast<nonloc::LocAsInteger>(L).getLoc(); - - switch (R.getSubKind()) { - case nonloc::LocAsIntegerKind: - return EvalBinOp(Eng, Op, LL, - cast<nonloc::LocAsInteger>(R).getLoc()); - - case nonloc::ConcreteIntKind: { - // Transform the integer into a location and compare. - ASTContext& Ctx = Eng.getContext(); - llvm::APSInt V = cast<nonloc::ConcreteInt>(R).getValue(); - V.setIsUnsigned(true); - V.extOrTrunc(Ctx.getTypeSize(Ctx.VoidPtrTy)); - return EvalBinOp(Eng, Op, LL, ValMgr.makeLoc(V)); - } - - default: - switch (Op) { - case BinaryOperator::EQ: - return ValMgr.makeTruthVal(false); - case BinaryOperator::NE: - return ValMgr.makeTruthVal(true); - default: - // This case also handles pointer arithmetic. - return UnknownVal(); - } - } - } - - case nonloc::SymExprValKind: { - // Logical not? - if (!(Op == BinaryOperator::EQ && R.isZeroConstant())) - return UnknownVal(); - - const SymExpr &SE=*cast<nonloc::SymExprVal>(L).getSymbolicExpression(); - - // Only handle ($sym op constant) for now. - if (const SymIntExpr *E = dyn_cast<SymIntExpr>(&SE)) { - BinaryOperator::Opcode Opc = E->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]; - assert(E->getType(Eng.getContext()) == T); - E = Eng.getSymbolManager().getSymIntExpr(E->getLHS(), Opc, - E->getRHS(), T); - return nonloc::SymExprVal(E); - } - - return UnknownVal(); - } - - case nonloc::ConcreteIntKind: - - if (isa<nonloc::ConcreteInt>(R)) { - const nonloc::ConcreteInt& L_CI = cast<nonloc::ConcreteInt>(L); - const nonloc::ConcreteInt& R_CI = cast<nonloc::ConcreteInt>(R); - return L_CI.EvalBinOp(BasicVals, Op, R_CI); - } - else { - subkind = R.getSubKind(); - NonLoc tmp = R; - R = L; - L = tmp; - - // Swap the operators. - switch (Op) { - case BinaryOperator::LT: Op = BinaryOperator::GT; break; - case BinaryOperator::GT: Op = BinaryOperator::LT; break; - case BinaryOperator::LE: Op = BinaryOperator::GE; break; - case BinaryOperator::GE: Op = BinaryOperator::LE; break; - default: break; - } - - continue; - } - - case nonloc::SymbolValKind: - if (isa<nonloc::ConcreteInt>(R)) { - ValueManager &ValMgr = Eng.getValueManager(); - return ValMgr.makeNonLoc(cast<nonloc::SymbolVal>(L).getSymbol(), Op, - cast<nonloc::ConcreteInt>(R).getValue(), T); - } - else - return UnknownVal(); - } - } -} - - -// Binary Operators (except assignments and comma). - -SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op, - Loc L, Loc R) { - - switch (Op) { - default: - return UnknownVal(); - case BinaryOperator::EQ: - case BinaryOperator::NE: - return EvalEquality(Eng, L, R, Op == BinaryOperator::EQ); - } -} - -SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, const GRState *state, - BinaryOperator::Opcode Op, Loc L, NonLoc R) { - - // Special case: 'R' is an integer that has the same width as a pointer and - // we are using the integer location in a comparison. Normally this cannot be - // triggered, but transfer functions like those for OSCommpareAndSwapBarrier32 - // can generate comparisons that trigger this code. - // FIXME: Are all locations guaranteed to have pointer width? - if (BinaryOperator::isEqualityOp(Op)) { - if (nonloc::ConcreteInt *RInt = dyn_cast<nonloc::ConcreteInt>(&R)) { - const llvm::APSInt *X = &RInt->getValue(); - ASTContext &C = Eng.getContext(); - if (C.getTypeSize(C.VoidPtrTy) == X->getBitWidth()) { - // Convert the signedness of the integer (if necessary). - if (X->isSigned()) - X = &Eng.getBasicVals().getValue(*X, true); - - return EvalBinOp(Eng, Op, L, loc::ConcreteInt(*X)); - } - } - } - - // Delegate pointer arithmetic to store manager. - return Eng.getStoreManager().EvalBinOp(state, Op, L, R); -} - -// Equality operators for Locs. -// FIXME: All this logic will be revamped when we have MemRegion::getLocation() -// implemented. - -SVal GRSimpleVals::EvalEquality(GRExprEngine& Eng, Loc L, Loc R, bool isEqual) { - - ValueManager& ValMgr = Eng.getValueManager(); - - switch (L.getSubKind()) { - - default: - assert(false && "EQ/NE not implemented for this Loc."); - return UnknownVal(); - - case loc::ConcreteIntKind: - - if (isa<loc::ConcreteInt>(R)) { - bool b = cast<loc::ConcreteInt>(L).getValue() == - cast<loc::ConcreteInt>(R).getValue(); - - // Are we computing '!='? Flip the result. - if (!isEqual) - b = !b; - - return ValMgr.makeTruthVal(b); - } - else if (SymbolRef Sym = R.getAsSymbol()) { - const SymIntExpr * SE = - Eng.getSymbolManager().getSymIntExpr(Sym, - isEqual ? BinaryOperator::EQ - : BinaryOperator::NE, - cast<loc::ConcreteInt>(L).getValue(), - Eng.getContext().IntTy); - return nonloc::SymExprVal(SE); - } - - break; - - case loc::MemRegionKind: { - if (SymbolRef LSym = L.getAsLocSymbol()) { - if (isa<loc::ConcreteInt>(R)) { - const SymIntExpr *SE = - Eng.getSymbolManager().getSymIntExpr(LSym, - isEqual ? BinaryOperator::EQ - : BinaryOperator::NE, - cast<loc::ConcreteInt>(R).getValue(), - Eng.getContext().IntTy); - - return nonloc::SymExprVal(SE); - } - } - } - - // Fall-through. - - case loc::GotoLabelKind: - return ValMgr.makeTruthVal(isEqual ? L == R : L != R); - } - - return ValMgr.makeTruthVal(isEqual ? false : true); -} - -//===----------------------------------------------------------------------===// -// Transfer function for function calls. -//===----------------------------------------------------------------------===// - -void GRSimpleVals::EvalCall(ExplodedNodeSet<GRState>& Dst, - GRExprEngine& Eng, - GRStmtNodeBuilder<GRState>& Builder, - CallExpr* CE, SVal L, - ExplodedNode<GRState>* Pred) { - - const GRState* state = Builder.GetState(Pred); - - // Invalidate all arguments passed in by reference (Locs). - - for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end(); - I != E; ++I) { - - SVal V = state->getSVal(*I); - - if (isa<loc::MemRegionVal>(V)) { - const MemRegion *R = cast<loc::MemRegionVal>(V).getRegion(); - - if (R->isBoundable()) - state = state->bindLoc(cast<Loc>(V), UnknownVal()); - } else if (isa<nonloc::LocAsInteger>(V)) - state = state->bindLoc(cast<nonloc::LocAsInteger>(V).getLoc(), - UnknownVal()); - } - - // Make up a symbol for the return value of this function. - // FIXME: We eventually should handle structs and other compound types - // that are returned by value. - QualType T = CE->getType(); - if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) { - unsigned Count = Builder.getCurrentBlockCount(); - SVal X = Eng.getValueManager().getConjuredSymbolVal(CE, Count); - state = state->bindExpr(CE, X, Eng.getCFG().isBlkExpr(CE), false); - } - - Builder.MakeNode(Dst, CE, Pred, state); -} - -//===----------------------------------------------------------------------===// -// Transfer function for Objective-C message expressions. -//===----------------------------------------------------------------------===// - -void GRSimpleVals::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst, - GRExprEngine& Eng, - GRStmtNodeBuilder<GRState>& Builder, - ObjCMessageExpr* ME, - ExplodedNode<GRState>* Pred) { - - - // The basic transfer function logic for message expressions does nothing. - // We just invalidate all arguments passed in by references. - const GRState *St = Builder.GetState(Pred); - - for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end(); - I != E; ++I) { - - SVal V = St->getSVal(*I); - - if (isa<Loc>(V)) - St = St->bindLoc(cast<Loc>(V), UnknownVal()); - } - - Builder.MakeNode(Dst, ME, Pred, St); -} diff --git a/lib/Analysis/GRTransferFuncs.cpp b/lib/Analysis/GRTransferFuncs.cpp deleted file mode 100644 index 3c14ee9ab5..0000000000 --- a/lib/Analysis/GRTransferFuncs.cpp +++ /dev/null @@ -1,27 +0,0 @@ -//== GRTransferFuncs.cpp - Path-Sens. Transfer Functions Interface -*- C++ -*--= -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines GRTransferFuncs, which provides a base-class that -// defines an interface for transfer functions used by GRExprEngine. -// -//===----------------------------------------------------------------------===// - -#include "clang/Analysis/PathSensitive/GRTransferFuncs.h" -#include "clang/Analysis/PathSensitive/GRExprEngine.h" - -using namespace clang; - -void GRTransferFuncs::EvalBinOpNN(GRStateSet& OStates, - GRExprEngine& Eng, - const GRState *St, Expr* Ex, - BinaryOperator::Opcode Op, - NonLoc L, NonLoc R, QualType T) { - - OStates.Add(St->bindExpr(Ex, DetermEvalBinOpNN(Eng, Op, L, R, T))); -} diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index e87245f9c2..82025877b6 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -780,7 +780,7 @@ SVal RegionStoreManager::EvalBinOp(const GRState *state, // nonloc::ConcreteInt OffConverted(getBasicVals().Convert(Base->getValue(), Offset->getValue())); - SVal NewIdx = Base->EvalBinOp(getBasicVals(), Op, OffConverted); + SVal NewIdx = Base->evalBinOp(ValMgr, Op, OffConverted); const MemRegion* NewER = MRMgr.getElementRegion(ER->getElementType(), NewIdx,ER->getSuperRegion(), getContext()); diff --git a/lib/Analysis/SVals.cpp b/lib/Analysis/SVals.cpp index a69b611cc3..7d1850d730 100644 --- a/lib/Analysis/SVals.cpp +++ b/lib/Analysis/SVals.cpp @@ -188,12 +188,11 @@ bool SVal::isZeroConstant() const { // Transfer function dispatch for Non-Locs. //===----------------------------------------------------------------------===// -SVal nonloc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals, - BinaryOperator::Opcode Op, - const nonloc::ConcreteInt& R) const { - +SVal nonloc::ConcreteInt::evalBinOp(ValueManager &ValMgr, + BinaryOperator::Opcode Op, + const nonloc::ConcreteInt& R) const { const llvm::APSInt* X = - BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue()); + ValMgr.getBasicValueFactory().EvaluateAPSInt(Op, getValue(), R.getValue()); if (X) return nonloc::ConcreteInt(*X); @@ -201,20 +200,13 @@ SVal nonloc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals, return UndefinedVal(); } - // Bitwise-Complement. - nonloc::ConcreteInt -nonloc::ConcreteInt::EvalComplement(BasicValueFactory& BasicVals) const { - return BasicVals.getValue(~getValue()); +nonloc::ConcreteInt::evalComplement(ValueManager &ValMgr) const { + return ValMgr.makeIntVal(~getValue()); } - // Unary Minus. - -nonloc::ConcreteInt -nonloc::ConcreteInt::EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const { - assert (U->getType() == U->getSubExpr()->getType()); - assert (U->getType()->isIntegerType()); - return BasicVals.getValue(-getValue()); +nonloc::ConcreteInt nonloc::ConcreteInt::evalMinus(ValueManager &ValMgr) const { + return ValMgr.makeIntVal(-getValue()); } //===----------------------------------------------------------------------===// |