diff options
Diffstat (limited to 'lib/Checker/GRExprEngine.cpp')
-rw-r--r-- | lib/Checker/GRExprEngine.cpp | 70 |
1 files changed, 65 insertions, 5 deletions
diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index 7f86319..ad229c7 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -37,6 +37,15 @@ using llvm::dyn_cast_or_null; using llvm::cast; using llvm::APSInt; +namespace { + // Trait class for recording returned expression in the state. + struct ReturnExpr { + static int TagInt; + typedef const Stmt *data_type; + }; + int ReturnExpr::TagInt; +} + //===----------------------------------------------------------------------===// // Utility functions. //===----------------------------------------------------------------------===// @@ -318,6 +327,8 @@ static void RegisterInternalChecks(GRExprEngine &Eng) { RegisterNoReturnFunctionChecker(Eng); RegisterBuiltinFunctionChecker(Eng); RegisterOSAtomicChecker(Eng); + RegisterUnixAPIChecker(Eng); + RegisterMacOSXAPIChecker(Eng); } GRExprEngine::GRExprEngine(AnalysisManager &mgr, GRTransferFuncs *tf) @@ -458,7 +469,7 @@ void GRExprEngine::ProcessStmt(CFGElement CE, GRStmtNodeBuilder& builder) { "Error evaluating statement"); Builder = &builder; - EntryNode = builder.getLastNode(); + EntryNode = builder.getBasePredecessor(); // Set up our simple checks. if (BatchAuditor) @@ -1288,6 +1299,37 @@ void GRExprEngine::ProcessSwitch(GRSwitchNodeBuilder& builder) { if (defaultIsFeasible) builder.generateDefaultCaseNode(DefaultSt); } +void GRExprEngine::ProcessCallEnter(GRCallEnterNodeBuilder &B) { + const FunctionDecl *FD = B.getCallee(); + const StackFrameContext *LocCtx = AMgr.getStackFrame(FD, + B.getLocationContext(), + B.getCallExpr(), + B.getBlock(), + B.getIndex()); + + const GRState *state = B.getState(); + state = getStoreManager().EnterStackFrame(state, LocCtx); + + B.GenerateNode(state, LocCtx); +} + +void GRExprEngine::ProcessCallExit(GRCallExitNodeBuilder &B) { + const GRState *state = B.getState(); + const ExplodedNode *Pred = B.getPredecessor(); + const StackFrameContext *LocCtx = + cast<StackFrameContext>(Pred->getLocationContext()); + const Stmt *CE = LocCtx->getCallSite(); + + // If the callee returns an expression, bind its value to CallExpr. + const Stmt *ReturnedExpr = state->get<ReturnExpr>(); + if (ReturnedExpr) { + SVal RetVal = state->getSVal(ReturnedExpr); + state = state->BindExpr(CE, RetVal); + } + + B.GenerateNode(state); +} + //===----------------------------------------------------------------------===// // Transfer functions: logical operations ('&&', '||'). //===----------------------------------------------------------------------===// @@ -2316,8 +2358,9 @@ void GRExprEngine::VisitDeclStmt(DeclStmt *DS, ExplodedNode *Pred, // Recover some path-sensitivity if a scalar value evaluated to // UnknownVal. - if (InitVal.isUnknown() || - !getConstraintManager().canReasonAbout(InitVal)) { + if ((InitVal.isUnknown() || + !getConstraintManager().canReasonAbout(InitVal)) && + !VD->getType()->isReferenceType()) { InitVal = ValMgr.getConjuredSymbolVal(NULL, InitEx, Builder->getCurrentBlockCount()); } @@ -2855,10 +2898,19 @@ void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A, void GRExprEngine::VisitReturnStmt(ReturnStmt *RS, ExplodedNode *Pred, ExplodedNodeSet &Dst) { - ExplodedNodeSet Src; if (Expr *RetE = RS->getRetValue()) { - Visit(RetE, Pred, Src); + // Record the returned expression in the state. + { + static int Tag = 0; + SaveAndRestore<const void *> OldTag(Builder->Tag, &Tag); + const GRState *state = GetState(Pred); + state = state->set<ReturnExpr>(RetE); + Pred = Builder->generateNode(RetE, state, Pred); + } + // We may get a NULL Pred because we generated a cached node. + if (Pred) + Visit(RetE, Pred, Src); } else { Src.Add(Pred); @@ -3139,6 +3191,14 @@ struct DOTGraphTraits<ExplodedNode*> : assert (false); break; + case ProgramPoint::CallEnterKind: + Out << "CallEnter"; + break; + + case ProgramPoint::CallExitKind: + Out << "CallExit"; + break; + default: { if (StmtPoint *L = dyn_cast<StmtPoint>(&Loc)) { const Stmt* S = L->getStmt(); |