// TODO: once the constraint manager is smart enough to handle non simplified
// symbolic expressions remove this function. Note that this can not be used in
// the constraint manager as is, since this does not handle overflows. It is
// safe to assume, however, that memory offsets will not overflow.
static std::pair<NonLoc, nonloc::ConcreteInt>
getSimplifiedOffsets(NonLoc offset, nonloc::ConcreteInt extent,
                     SValBuilder &svalBuilder) {
  Optional<nonloc::SymbolVal> SymVal = offset.getAs<nonloc::SymbolVal>();
  if (SymVal && SymVal->isExpression()) {
    if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SymVal->getSymbol())) {
      llvm::APSInt constant =
          APSIntType(extent.getValue()).convert(SIE->getRHS());
      switch (SIE->getOpcode()) {
      case BO_Mul:
        // The constant should never be 0 here, since it the result of scaling
        // based on the size of a type which is never 0.
        if ((extent.getValue() % constant) != 0)
          return std::pair<NonLoc, nonloc::ConcreteInt>(offset, extent);
        else
          return getSimplifiedOffsets(
              nonloc::SymbolVal(SIE->getLHS()),
              svalBuilder.makeIntVal(extent.getValue() / constant),
              svalBuilder);
      case BO_Add:
        return getSimplifiedOffsets(
            nonloc::SymbolVal(SIE->getLHS()),
            svalBuilder.makeIntVal(extent.getValue() - constant), svalBuilder);
      default:
        break;
      }
    }
  }

  return std::pair<NonLoc, nonloc::ConcreteInt>(offset, extent);
}
Example #2
0
SVal Environment::getSVal(const Stmt *E, SValBuilder& svalBuilder) const {
  for (;;) {
    switch (E->getStmtClass()) {
      case Stmt::AddrLabelExprClass:
        return svalBuilder.makeLoc(cast<AddrLabelExpr>(E));
      case Stmt::ParenExprClass:
        // ParenExprs are no-ops.
        E = cast<ParenExpr>(E)->getSubExpr();
        continue;
      case Stmt::CharacterLiteralClass: {
        const CharacterLiteral* C = cast<CharacterLiteral>(E);
        return svalBuilder.makeIntVal(C->getValue(), C->getType());
      }
      case Stmt::CXXBoolLiteralExprClass: {
        const SVal *X = ExprBindings.lookup(E);
        if (X) 
          return *X;
        else 
          return svalBuilder.makeIntVal(cast<CXXBoolLiteralExpr>(E));
      }
      case Stmt::IntegerLiteralClass: {
        // In C++, this expression may have been bound to a temporary object.
        SVal const *X = ExprBindings.lookup(E);
        if (X)
          return *X;
        else
          return svalBuilder.makeIntVal(cast<IntegerLiteral>(E));
      }
      case Stmt::ImplicitCastExprClass:
      case Stmt::CStyleCastExprClass: {
        // We blast through no-op casts to get the descendant
        // subexpression that has a value.
        const CastExpr* C = cast<CastExpr>(E);
        QualType CT = C->getType();
        if (CT->isVoidType())
          return UnknownVal();
        if (C->getCastKind() == CK_NoOp) {
          E = C->getSubExpr();
          continue;
        }
        break;
      }
      case Stmt::ExprWithCleanupsClass:
        E = cast<ExprWithCleanups>(E)->getSubExpr();
        continue;
      case Stmt::CXXBindTemporaryExprClass:
        E = cast<CXXBindTemporaryExpr>(E)->getSubExpr();
        continue;
      case Stmt::CXXFunctionalCastExprClass:
        E = cast<CXXFunctionalCastExpr>(E)->getSubExpr();
        continue;        
      // Handle all other Stmt* using a lookup.
      default:
        break;
    };
    break;
  }
  return lookupExpr(E);
}
Example #3
0
DefinedOrUnknownSVal TypedValueRegion::getExtent(SValBuilder &svalBuilder) const {
  ASTContext &Ctx = svalBuilder.getContext();
  QualType T = getDesugaredValueType(Ctx);

  if (isa<VariableArrayType>(T))
    return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
  if (isa<IncompleteArrayType>(T))
    return UnknownVal();

  CharUnits size = Ctx.getTypeSizeInChars(T);
  QualType sizeTy = svalBuilder.getArrayIndexType();
  return svalBuilder.makeIntVal(size.getQuantity(), sizeTy);
}
Example #4
0
// When checking for error code, we need to consider the following cases:
// 1) noErr / [0]
// 2) someErr / [1, inf]
// 3) unknown
// If noError, returns true iff (1).
// If !noError, returns true iff (2).
bool MacOSKeychainAPIChecker::definitelyReturnedError(SymbolRef RetSym,
                                                      ProgramStateRef State,
                                                      SValBuilder &Builder,
                                                      bool noError) const {
  DefinedOrUnknownSVal NoErrVal = Builder.makeIntVal(NoErr,
    Builder.getSymbolManager().getType(RetSym));
  DefinedOrUnknownSVal NoErr = Builder.evalEQ(State, NoErrVal,
                                                     nonloc::SymbolVal(RetSym));
  ProgramStateRef ErrState = State->assume(NoErr, noError);
  if (ErrState == State) {
    return true;
  }

  return false;
}
Example #5
0
DefinedOrUnknownSVal StringRegion::getExtent(SValBuilder &svalBuilder) const {
  return svalBuilder.makeIntVal(getStringLiteral()->getByteLength()+1,
                                svalBuilder.getArrayIndexType());
}
Example #6
0
nonloc::ConcreteInt
nonloc::ConcreteInt::evalMinus(SValBuilder &svalBuilder) const {
  return svalBuilder.makeIntVal(-getValue());
}
Example #7
0
nonloc::ConcreteInt
nonloc::ConcreteInt::evalComplement(SValBuilder &svalBuilder) const {
  return svalBuilder.makeIntVal(~getValue());
}
Example #8
0
SVal Environment::getSVal(const EnvironmentEntry &Entry,
                          SValBuilder& svalBuilder,
                          bool useOnlyDirectBindings) const {

  if (useOnlyDirectBindings) {
    // This branch is rarely taken, but can be exercised by
    // checkers that explicitly bind values to arbitrary
    // expressions.  It is crucial that we do not ignore any
    // expression here, and do a direct lookup.
    return lookupExpr(Entry);
  }

  const Stmt *E = Entry.getStmt();
  const LocationContext *LCtx = Entry.getLocationContext();
  
  for (;;) {
    if (const Expr *Ex = dyn_cast<Expr>(E))
      E = Ex->IgnoreParens();

    switch (E->getStmtClass()) {
      case Stmt::AddrLabelExprClass:
        return svalBuilder.makeLoc(cast<AddrLabelExpr>(E));
      case Stmt::OpaqueValueExprClass: {
        const OpaqueValueExpr *ope = cast<OpaqueValueExpr>(E);
        E = ope->getSourceExpr();
        continue;        
      }        
      case Stmt::ParenExprClass:
      case Stmt::GenericSelectionExprClass:
        llvm_unreachable("ParenExprs and GenericSelectionExprs should "
                         "have been handled by IgnoreParens()");
      case Stmt::CharacterLiteralClass: {
        const CharacterLiteral* C = cast<CharacterLiteral>(E);
        return svalBuilder.makeIntVal(C->getValue(), C->getType());
      }
      case Stmt::CXXBoolLiteralExprClass: {
        const SVal *X = ExprBindings.lookup(EnvironmentEntry(E, LCtx));
        if (X) 
          return *X;
        else 
          return svalBuilder.makeBoolVal(cast<CXXBoolLiteralExpr>(E));
      }
      case Stmt::IntegerLiteralClass: {
        // In C++, this expression may have been bound to a temporary object.
        SVal const *X = ExprBindings.lookup(EnvironmentEntry(E, LCtx));
        if (X)
          return *X;
        else
          return svalBuilder.makeIntVal(cast<IntegerLiteral>(E));
      }
      // For special C0xx nullptr case, make a null pointer SVal.
      case Stmt::CXXNullPtrLiteralExprClass:
        return svalBuilder.makeNull();
      case Stmt::ExprWithCleanupsClass:
        E = cast<ExprWithCleanups>(E)->getSubExpr();
        continue;
      case Stmt::CXXBindTemporaryExprClass:
        E = cast<CXXBindTemporaryExpr>(E)->getSubExpr();
        continue;
      case Stmt::ObjCPropertyRefExprClass:
        return loc::ObjCPropRef(cast<ObjCPropertyRefExpr>(E));
      case Stmt::ReturnStmtClass: {
        const ReturnStmt *RS = cast<ReturnStmt>(E);
        if (const Expr *RE = RS->getRetValue()) {
          E = RE;
          continue;
        }
        return UndefinedVal();        
      }
        
      // Handle all other Stmt* using a lookup.
      default:
        break;
    };
    break;
  }
  return lookupExpr(EnvironmentEntry(E, LCtx));
}
Example #9
0
SVal Environment::getSVal(const EnvironmentEntry &Entry,
                          SValBuilder& svalBuilder) const {
  const Stmt *S = Entry.getStmt();
  const LocationContext *LCtx = Entry.getLocationContext();

  switch (S->getStmtClass()) {
  case Stmt::CXXBindTemporaryExprClass:
  case Stmt::ExprWithCleanupsClass:
  case Stmt::GenericSelectionExprClass:
  case Stmt::OpaqueValueExprClass:
  case Stmt::ParenExprClass:
  case Stmt::SubstNonTypeTemplateParmExprClass:
    llvm_unreachable("Should have been handled by ignoreTransparentExprs");

  case Stmt::AddrLabelExprClass:
    return svalBuilder.makeLoc(cast<AddrLabelExpr>(S));

  case Stmt::CharacterLiteralClass: {
    const CharacterLiteral *C = cast<CharacterLiteral>(S);
    return svalBuilder.makeIntVal(C->getValue(), C->getType());
  }

  case Stmt::CXXBoolLiteralExprClass:
    return svalBuilder.makeBoolVal(cast<CXXBoolLiteralExpr>(S));

  case Stmt::CXXScalarValueInitExprClass:
  case Stmt::ImplicitValueInitExprClass: {
    QualType Ty = cast<Expr>(S)->getType();
    return svalBuilder.makeZeroVal(Ty);
  }

  case Stmt::IntegerLiteralClass:
    return svalBuilder.makeIntVal(cast<IntegerLiteral>(S));

  case Stmt::ObjCBoolLiteralExprClass:
    return svalBuilder.makeBoolVal(cast<ObjCBoolLiteralExpr>(S));

  // For special C0xx nullptr case, make a null pointer SVal.
  case Stmt::CXXNullPtrLiteralExprClass:
    return svalBuilder.makeNull();

  case Stmt::ObjCStringLiteralClass: {
    MemRegionManager &MRMgr = svalBuilder.getRegionManager();
    const ObjCStringLiteral *SL = cast<ObjCStringLiteral>(S);
    return svalBuilder.makeLoc(MRMgr.getObjCStringRegion(SL));
  }

  case Stmt::StringLiteralClass: {
    MemRegionManager &MRMgr = svalBuilder.getRegionManager();
    const StringLiteral *SL = cast<StringLiteral>(S);
    return svalBuilder.makeLoc(MRMgr.getStringRegion(SL));
  }

  case Stmt::ReturnStmtClass: {
    const ReturnStmt *RS = cast<ReturnStmt>(S);
    if (const Expr *RE = RS->getRetValue())
      return getSVal(EnvironmentEntry(RE, LCtx), svalBuilder);
    return UndefinedVal();        
  }
    
  // Handle all other Stmt* using a lookup.
  default:
    break;
  }
  
  return lookupExpr(EnvironmentEntry(S, LCtx));
}