]> granicus.if.org Git - clang/commitdiff
Handle CFGAutomaticObjDtor.
authorZhongxing Xu <xuzhongxing@gmail.com>
Sat, 20 Nov 2010 06:53:12 +0000 (06:53 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Sat, 20 Nov 2010 06:53:12 +0000 (06:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119897 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Checker/PathSensitive/GRExprEngine.h
lib/Checker/GRCXXExprEngine.cpp
lib/Checker/GRExprEngine.cpp
lib/Checker/RegionStore.cpp
test/Analysis/dtor.cpp [new file with mode: 0644]

index d49fd85e6f952abf0556a99c4b739b660cda66bd..bb0c0680573c60b66107ce66a8bb60ed3f975f2b 100644 (file)
@@ -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);
 
index 642c26e2408c07d7e41bca847a39c4573dcdb5e1..ecc1490ce6a5f450f6ee5e4a5cffdc3b05d2c16a 100644 (file)
@@ -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) {
index ddd3d50fe56bbc9e8b9af5c65a063cf913e203fc..4483cdb76c4b9f3092ca3144e228463db893105c 100644 (file)
@@ -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<CFGAutomaticObjDtor>(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<loc::MemRegionVal>(Dest).getRegion(),
+                     D.getTriggerStmt(), Pred, Dst);
 }
 
 void GRExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
index 7808872f5dd630d09dba85157003e45e234be754..144c925b8c15daf0ac51b6a8db40bbcef12c5122 100644 (file)
@@ -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<CXXDestructorDecl>(frame->getDecl()));
 
   return store;
 }
diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp
new file mode 100644 (file)
index 0000000..ea5b046
--- /dev/null
@@ -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;
+}