static void addParameterValuesToBindings(const StackFrameContext *CalleeCtx, CallEvent::BindingsTy &Bindings, SValBuilder &SVB, const CallEvent &Call, CallEvent::param_iterator I, CallEvent::param_iterator E) { MemRegionManager &MRMgr = SVB.getRegionManager(); // If the function has fewer parameters than the call has arguments, we simply // do not bind any values to them. unsigned NumArgs = Call.getNumArgs(); unsigned Idx = 0; for (; I != E && Idx < NumArgs; ++I, ++Idx) { const ParmVarDecl *ParamDecl = *I; assert(ParamDecl && "Formal parameter has no decl?"); SVal ArgVal = Call.getArgSVal(Idx); if (!ArgVal.isUnknown()) { Loc ParamLoc = SVB.makeLoc(MRMgr.getVarRegion(ParamDecl, CalleeCtx)); Bindings.push_back(std::make_pair(ParamLoc, ArgVal)); } } // FIXME: Variadic arguments are not handled at all right now. }
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); }
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)); }
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)); }