summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-07-10 22:07:47 +0000
committerJordan Rose <jordan_rose@apple.com>2012-07-10 22:07:47 +0000
commit4ee71b8a18a9ba113e98bd26af3eb367bca81d5e (patch)
treef4187dec3457369f207d7748bbbe3d13d5c8ad99 /clang/lib/StaticAnalyzer
parent681cce9908500cad97cc3ce5c4a786e237399a9b (diff)
downloadbcm5719-llvm-4ee71b8a18a9ba113e98bd26af3eb367bca81d5e.tar.gz
bcm5719-llvm-4ee71b8a18a9ba113e98bd26af3eb367bca81d5e.zip
[analyzer] Add a CXXDestructorCall CallEvent.
While this work is still fairly tentative (destructors are still left out of the CFG by default), we now handle destructors in the same way as any other calls, instead of just automatically trying to inline them. llvm-svn: 160020
Diffstat (limited to 'clang/lib/StaticAnalyzer')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp1
-rw-r--r--clang/lib/StaticAnalyzer/Core/Calls.cpp6
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp26
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp22
4 files changed, 32 insertions, 23 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 32f7706bd94..541a8b7c157 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/clang/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/clang/lib/StaticAnalyzer/Core/Calls.cpp b/clang/lib/StaticAnalyzer/Core/Calls.cpp
index 7b86d442765..8ea1336bb7b 100644
--- a/clang/lib/StaticAnalyzer/Core/Calls.cpp
+++ b/clang/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/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index bac5b70f699..3fa052817c2 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/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/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index bf55ceb5fd4..cce55ea023b 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/clang/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,
OpenPOWER on IntegriCloud