diff options
Diffstat (limited to 'lib/StaticAnalyzer/Core/SValBuilder.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/SValBuilder.cpp | 76 |
1 files changed, 54 insertions, 22 deletions
diff --git a/lib/StaticAnalyzer/Core/SValBuilder.cpp b/lib/StaticAnalyzer/Core/SValBuilder.cpp index 9e97f5e..d1936cd 100644 --- a/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ b/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "clang/AST/ExprCXX.h" +#include "clang/AST/DeclCXX.h" #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" @@ -61,7 +62,6 @@ NonLoc SValBuilder::makeNonLoc(const llvm::APSInt& lhs, NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType type) { assert(lhs && rhs); - assert(haveSameType(lhs->getType(Context), rhs->getType(Context)) == true); assert(!Loc::isLocType(type)); return nonloc::SymbolVal(SymMgr.getSymSymExpr(lhs, op, rhs, type)); } @@ -149,6 +149,18 @@ SValBuilder::getConjuredSymbolVal(const Stmt *stmt, return nonloc::SymbolVal(sym); } +DefinedOrUnknownSVal +SValBuilder::getConjuredHeapSymbolVal(const Expr *E, + const LocationContext *LCtx, + unsigned VisitCount) { + QualType T = E->getType(); + assert(Loc::isLocType(T)); + assert(SymbolManager::canSymbolicate(T)); + + SymbolRef sym = SymMgr.getConjuredSymbol(E, LCtx, T, VisitCount); + return loc::MemRegionVal(MemMgr.getSymbolicHeapRegion(sym)); +} + DefinedSVal SValBuilder::getMetadataSymbolVal(const void *symbolTag, const MemRegion *region, const Expr *expr, QualType type, @@ -193,31 +205,48 @@ DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block, return loc::MemRegionVal(BD); } +/// Return a memory region for the 'this' object reference. +loc::MemRegionVal SValBuilder::getCXXThis(const CXXMethodDecl *D, + const StackFrameContext *SFC) { + return loc::MemRegionVal(getRegionManager(). + getCXXThisRegion(D->getThisType(getContext()), SFC)); +} + +/// Return a memory region for the 'this' object reference. +loc::MemRegionVal SValBuilder::getCXXThis(const CXXRecordDecl *D, + const StackFrameContext *SFC) { + const Type *T = D->getTypeForDecl(); + QualType PT = getContext().getPointerType(QualType(T, 0)); + return loc::MemRegionVal(getRegionManager().getCXXThisRegion(PT, SFC)); +} + //===----------------------------------------------------------------------===// -SVal SValBuilder::makeGenericVal(ProgramStateRef State, - BinaryOperator::Opcode Op, - NonLoc LHS, NonLoc RHS, - QualType ResultTy) { - // If operands are tainted, create a symbol to ensure that we propagate taint. - if (State->isTainted(RHS) || State->isTainted(LHS)) { - const SymExpr *symLHS; - const SymExpr *symRHS; - - if (const nonloc::ConcreteInt *rInt = dyn_cast<nonloc::ConcreteInt>(&RHS)) { - symLHS = LHS.getAsSymExpr(); +SVal SValBuilder::makeSymExprValNN(ProgramStateRef State, + BinaryOperator::Opcode Op, + NonLoc LHS, NonLoc RHS, + QualType ResultTy) { + if (!State->isTainted(RHS) && !State->isTainted(LHS)) + return UnknownVal(); + + const SymExpr *symLHS = LHS.getAsSymExpr(); + const SymExpr *symRHS = RHS.getAsSymExpr(); + // TODO: When the Max Complexity is reached, we should conjure a symbol + // instead of generating an Unknown value and propagate the taint info to it. + const unsigned MaxComp = 10000; // 100000 28X + + if (symLHS && symRHS && + (symLHS->computeComplexity() + symRHS->computeComplexity()) < MaxComp) + return makeNonLoc(symLHS, Op, symRHS, ResultTy); + + if (symLHS && symLHS->computeComplexity() < MaxComp) + if (const nonloc::ConcreteInt *rInt = dyn_cast<nonloc::ConcreteInt>(&RHS)) return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy); - } - if (const nonloc::ConcreteInt *lInt = dyn_cast<nonloc::ConcreteInt>(&LHS)) { - symRHS = RHS.getAsSymExpr(); + if (symRHS && symRHS->computeComplexity() < MaxComp) + if (const nonloc::ConcreteInt *lInt = dyn_cast<nonloc::ConcreteInt>(&LHS)) return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy); - } - symLHS = LHS.getAsSymExpr(); - symRHS = RHS.getAsSymExpr(); - return makeNonLoc(symLHS, Op, symRHS, ResultTy); - } return UnknownVal(); } @@ -324,7 +353,7 @@ SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) { // Are we casting from an array to a pointer? If so just pass on // the decayed value. - if (castTy->isPointerType()) + if (castTy->isPointerType() || castTy->isReferenceType()) return val; // Are we casting from an array to an integer? If so, cast the decayed @@ -340,9 +369,12 @@ SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) { // Check for casts from a region to a specific type. if (const MemRegion *R = val.getAsRegion()) { + // Handle other casts of locations to integers. + if (castTy->isIntegerType()) + return evalCastFromLoc(loc::MemRegionVal(R), castTy); + // FIXME: We should handle the case where we strip off view layers to get // to a desugared type. - if (!Loc::isLocType(castTy)) { // FIXME: There can be gross cases where one casts the result of a function // (that returns a pointer) to some other value that happens to fit |