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 9e97f5e7d12d..d1936cd3603e 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  | 
