From: Zhongxing Xu Date: Sat, 20 Nov 2010 06:53:12 +0000 (+0000) Subject: Handle CFGAutomaticObjDtor. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b13453bd8a91f331d0910ca95ad52aa41b52f648;p=clang Handle CFGAutomaticObjDtor. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119897 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Checker/PathSensitive/GRExprEngine.h b/include/clang/Checker/PathSensitive/GRExprEngine.h index d49fd85e6f..bb0c068057 100644 --- a/include/clang/Checker/PathSensitive/GRExprEngine.h +++ b/include/clang/Checker/PathSensitive/GRExprEngine.h @@ -428,6 +428,10 @@ public: void VisitCXXConstructExpr(const CXXConstructExpr *E, const MemRegion *Dest, ExplodedNode *Pred, ExplodedNodeSet &Dst); + void VisitCXXDestructor(const CXXDestructorDecl *DD, + const MemRegion *Dest, const Stmt *S, + ExplodedNode *Pred, ExplodedNodeSet &Dst); + void VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, ExplodedNode *Pred, ExplodedNodeSet &Dst); diff --git a/lib/Checker/GRCXXExprEngine.cpp b/lib/Checker/GRCXXExprEngine.cpp index 642c26e240..ecc1490ce6 100644 --- a/lib/Checker/GRCXXExprEngine.cpp +++ b/lib/Checker/GRCXXExprEngine.cpp @@ -143,6 +143,30 @@ void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, } } +void GRExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD, + const MemRegion *Dest, + const Stmt *S, + ExplodedNode *Pred, + ExplodedNodeSet &Dst) { + if (!(DD->isThisDeclarationADefinition() && AMgr.shouldInlineCall())) + return; + // Create the context for 'this' region. + const StackFrameContext *SFC = AMgr.getStackFrame(DD, + Pred->getLocationContext(), + S, Builder->getBlock(), + Builder->getIndex()); + + const CXXThisRegion *ThisR = getCXXThisRegion(DD->getParent(), SFC); + + CallEnter PP(S, SFC->getAnalysisContext(), Pred->getLocationContext()); + + const GRState *state = Pred->getState(); + state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest)); + ExplodedNode *N = Builder->generateNode(PP, state, Pred); + if (N) + Dst.Add(N); +} + void GRExprEngine::VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, ExplodedNode *Pred, ExplodedNodeSet &Dst) { diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index ddd3d50fe5..4483cdb76c 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -718,6 +718,8 @@ void GRExprEngine::ProcessInitializer(const CFGInitializer Init, void GRExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D, GRStmtNodeBuilder &builder) { + Builder = &builder; + switch (D.getDtorKind()) { case CFGElement::AutomaticObjectDtor: ProcessAutomaticObjDtor(cast(D), builder); @@ -738,6 +740,17 @@ void GRExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D, void GRExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, GRStmtNodeBuilder &builder) { + ExplodedNode *Pred = builder.getBasePredecessor(); + const GRState *state = Pred->getState(); + const VarDecl *VD = D.getVarDecl(); + const CXXRecordDecl *CD = VD->getType()->getAsCXXRecordDecl(); + const CXXDestructorDecl *DD = CD->getDestructor(); + + Loc Dest = state->getLValue(VD, Pred->getLocationContext()); + + ExplodedNodeSet Dst; + VisitCXXDestructor(DD, cast(Dest).getRegion(), + D.getTriggerStmt(), Pred, Dst); } void GRExprEngine::ProcessBaseDtor(const CFGBaseDtor D, diff --git a/lib/Checker/RegionStore.cpp b/lib/Checker/RegionStore.cpp index 7808872f5d..144c925b8c 100644 --- a/lib/Checker/RegionStore.cpp +++ b/lib/Checker/RegionStore.cpp @@ -1828,7 +1828,7 @@ Store RegionStoreManager::EnterStackFrame(const GRState *state, store = Bind(store, ValMgr.makeLoc(MRMgr.getVarRegion(*PI,frame)),ArgVal); } } else - llvm_unreachable("Unhandled call expression."); + assert(isa(frame->getDecl())); return store; } diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp new file mode 100644 index 0000000000..ea5b04684d --- /dev/null +++ b/test/Analysis/dtor.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store region -analyzer-inline-call -cfg-add-implicit-dtors -verify %s + +class A { +public: + ~A() { + int *x = 0; + *x = 3; // expected-warning{{Dereference of null pointer}} + } +}; + +int main() { + A a; +}