diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp | 1 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/Calls.cpp | 6 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 26 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp | 22 |
4 files changed, 32 insertions, 23 deletions
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp index 32f7706bd9..541a8b7c15 100644 --- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp @@ -948,6 +948,7 @@ RetainSummaryManager::getSummary(const CallEvent &Call, case CE_CXXMemberOperator: case CE_Block: case CE_CXXConstructor: + case CE_CXXDestructor: case CE_CXXAllocator: // FIXME: These calls are currently unsupported. return getPersistentStopSummary(); diff --git a/lib/StaticAnalyzer/Core/Calls.cpp b/lib/StaticAnalyzer/Core/Calls.cpp index 7b86d44276..8ea1336bb7 100644 --- a/lib/StaticAnalyzer/Core/Calls.cpp +++ b/lib/StaticAnalyzer/Core/Calls.cpp @@ -372,6 +372,12 @@ void CXXConstructorCall::addExtraInvalidatedRegions(RegionList &Regions) const { } +void CXXDestructorCall::addExtraInvalidatedRegions(RegionList &Regions) const { + if (Target) + Regions.push_back(Target); +} + + CallEvent::param_iterator ObjCMethodCall::param_begin() const { const ObjCMethodDecl *D = getDecl(); if (!D) diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index bac5b70f69..3fa052817c 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -75,21 +75,21 @@ void ExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD, const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst) { - StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); - if (!(DD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall())) - return; + CXXDestructorCall Call(DD, S, Dest, Pred->getState(), + Pred->getLocationContext()); - // Create the context for 'this' region. - const StackFrameContext *SFC = - AnalysisDeclContexts.getContext(DD)-> - getStackFrame(Pred->getLocationContext(), S, - currentBuilderContext->getBlock(), currentStmtIdx); + ExplodedNodeSet DstPreCall; + getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, + Call, *this); - CallEnter PP(S, SFC, Pred->getLocationContext()); - ProgramStateRef state = Pred->getState(); - state = state->bindLoc(svalBuilder.getCXXThis(DD->getParent(), SFC), - loc::MemRegionVal(Dest)); - Bldr.generateNode(PP, Pred, state); + ExplodedNodeSet DstInvalidated; + for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); + I != E; ++I) + defaultEvalCall(DstInvalidated, *I, Call); + + ExplodedNodeSet DstPostCall; + getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated, + Call, *this); } void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index bf55ceb5fd..cce55ea023 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -292,7 +292,8 @@ bool ExprEngine::inlineCall(ExplodedNodeSet &Dst, // enterStackFrame as well. return false; case CE_CXXConstructor: - // Do not inline constructors until we can model destructors. + case CE_CXXDestructor: + // Do not inline constructors until we can really model destructors. // This is unfortunate, but basically necessary for smart pointers and such. return false; case CE_CXXAllocator: @@ -430,7 +431,7 @@ void ExprEngine::defaultEvalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred, return; // If we can't inline it, handle the return value and invalidate the regions. - StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); + NodeBuilder Bldr(Pred, Dst, *currentBuilderContext); // Invalidate any regions touched by the call. unsigned Count = currentBuilderContext->getCurrentBlockCount(); @@ -439,16 +440,17 @@ void ExprEngine::defaultEvalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred, state = Call.invalidateRegions(Count, state); // Conjure a symbol value to use as the result. - assert(Call.getOriginExpr() && "Must have an expression to bind the result"); - QualType ResultTy = Call.getResultType(); - SValBuilder &SVB = getSValBuilder(); - const LocationContext *LCtx = Pred->getLocationContext(); - SVal RetVal = SVB.getConjuredSymbolVal(0, Call.getOriginExpr(), LCtx, - ResultTy, Count); + if (E) { + QualType ResultTy = Call.getResultType(); + SValBuilder &SVB = getSValBuilder(); + const LocationContext *LCtx = Pred->getLocationContext(); + SVal RetVal = SVB.getConjuredSymbolVal(0, E, LCtx, ResultTy, Count); + + state = state->BindExpr(E, LCtx, RetVal); + } // And make the result node. - state = state->BindExpr(Call.getOriginExpr(), LCtx, RetVal); - Bldr.generateNode(Call.getOriginExpr(), Pred, state); + Bldr.generateNode(Call.getProgramPoint(), state, Pred); } void ExprEngine::VisitReturnStmt(const ReturnStmt *RS, ExplodedNode *Pred, |