Index: lib/StaticAnalyzer/Core/PathDiagnostic.cpp
===================================================================
--- lib/StaticAnalyzer/Core/PathDiagnostic.cpp	(revision 189733)
+++ lib/StaticAnalyzer/Core/PathDiagnostic.cpp	(working copy)
@@ -559,6 +559,9 @@
     return PathDiagnosticLocation::createEnd(Dtor.getTriggerStmt(),
                                              SM, CallerCtx);
   }
+  case CFGElement::DeleteDtor: {
+    llvm_unreachable("not yet implemented!");
+  }
   case CFGElement::BaseDtor:
   case CFGElement::MemberDtor: {
     const AnalysisDeclContext *CallerInfo = CallerCtx->getAnalysisDeclContext();
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp	(revision 189733)
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp	(working copy)
@@ -287,6 +287,7 @@
       ProcessInitializer(E.castAs<CFGInitializer>().getInitializer(), Pred);
       return;
     case CFGElement::AutomaticObjectDtor:
+    case CFGElement::DeleteDtor:
     case CFGElement::BaseDtor:
     case CFGElement::MemberDtor:
     case CFGElement::TemporaryDtor:
@@ -535,6 +536,9 @@
   case CFGElement::TemporaryDtor:
     ProcessTemporaryDtor(D.castAs<CFGTemporaryDtor>(), Pred, Dst);
     break;
+  case CFGElement::DeleteDtor:
+    ProcessDeleteDtor(D.castAs<CFGDeleteDtor>(), Pred, Dst);
+    break;
   default:
     llvm_unreachable("Unexpected dtor kind.");
   }
@@ -562,6 +566,12 @@
                      Pred, Dst);
 }
 
+void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor,
+                                   ExplodedNode *Pred,
+                                   ExplodedNodeSet &Dst) { 
+  //TODO: Handle DeleteDtor
+}
+
 void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
                                  ExplodedNode *Pred, ExplodedNodeSet &Dst) {
   const LocationContext *LCtx = Pred->getLocationContext();
Index: lib/Analysis/CFG.cpp
===================================================================
--- lib/Analysis/CFG.cpp	(revision 189733)
+++ lib/Analysis/CFG.cpp	(working copy)
@@ -363,6 +363,7 @@
                                       AddStmtChoice asc);
   CFGBlock *VisitCXXCatchStmt(CXXCatchStmt *S);
   CFGBlock *VisitCXXConstructExpr(CXXConstructExpr *C, AddStmtChoice asc);
+  CFGBlock *VisitCXXDeleteExpr(CXXDeleteExpr *DE, AddStmtChoice asc);
   CFGBlock *VisitCXXForRangeStmt(CXXForRangeStmt *S);
   CFGBlock *VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E,
                                        AddStmtChoice asc);
@@ -470,6 +471,10 @@
   void appendAutomaticObjDtor(CFGBlock *B, VarDecl *VD, Stmt *S) {
     B->appendAutomaticObjDtor(VD, S, cfg->getBumpVectorContext());
   }
+  
+  void appendDeleteDtor(CFGBlock *B, CXXRecordDecl *RD, CXXDeleteExpr *DE) {
+    B->appendDeleteDtor(RD, DE, cfg->getBumpVectorContext());
+  }
 
   void prependAutomaticObjDtorsWithTerminator(CFGBlock *Blk,
       LocalScope::const_iterator B, LocalScope::const_iterator E);
@@ -1116,6 +1121,9 @@
 
     case Stmt::CXXConstructExprClass:
       return VisitCXXConstructExpr(cast<CXXConstructExpr>(S), asc);
+    
+    case Stmt::CXXDeleteExprClass:
+      return VisitCXXDeleteExpr(cast<CXXDeleteExpr>(S), asc);
 
     case Stmt::CXXFunctionalCastExprClass:
       return VisitCXXFunctionalCastExpr(cast<CXXFunctionalCastExpr>(S), asc);
@@ -3113,6 +3121,22 @@
   return VisitChildren(C);
 }
 
+
+CFGBlock *CFGBuilder::VisitCXXDeleteExpr(CXXDeleteExpr *DE,
+                                         AddStmtChoice asc) {
+  autoCreateBlock();
+  appendStmt(Block, DE);
+  QualType DTy = DE->getDestroyedType();
+  DTy = DTy.getNonReferenceType();
+  CXXRecordDecl *RD = Context->getBaseElementType(DTy)->getAsCXXRecordDecl();
+  if (RD) {
+    if (!RD->hasTrivialDestructor())
+      appendDeleteDtor(Block, RD, DE);
+  }
+
+  return VisitChildren(DE);
+}
+
 CFGBlock *CFGBuilder::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E,
                                                  AddStmtChoice asc) {
   if (asc.alwaysAdd(*this, E)) {
@@ -3413,6 +3437,14 @@
       cast<CXXRecordDecl>(recordType->getDecl());
       return classDecl->getDestructor();      
     }
+    case CFGElement::DeleteDtor: {
+      const CXXDeleteExpr *DE = castAs<CFGDeleteDtor>().getDeleteExpr();
+      QualType DTy = DE->getDestroyedType();
+      DTy = DTy.getNonReferenceType();
+      const CXXRecordDecl *classDecl =
+          astContext.getBaseElementType(DTy)->getAsCXXRecordDecl();
+      return classDecl->getDestructor();     
+    }
     case CFGElement::TemporaryDtor: {
       const CXXBindTemporaryExpr *bindExpr =
         castAs<CFGTemporaryDtor>().getBindTemporaryExpr();
@@ -3751,6 +3783,15 @@
     OS << ".~" << T->getAsCXXRecordDecl()->getName().str() << "()";
     OS << " (Implicit destructor)\n";
 
+  } else if (Optional<CFGDeleteDtor> DE = E.getAs<CFGDeleteDtor>()) {
+    const CXXRecordDecl *RD = DE->getCXXRecordDecl();
+    if (!RD)
+      return;
+    CXXDeleteExpr* DelExpr = 
+        const_cast<CXXDeleteExpr*>(DE->getDeleteExpr());
+    Helper->handledStmt(cast<Stmt>(DelExpr->getArgument()), OS);
+    OS << "->~" << RD->getName().str() << "()";
+    OS << "(Implicit destructor)\n";
   } else if (Optional<CFGBaseDtor> BE = E.getAs<CFGBaseDtor>()) {
     const CXXBaseSpecifier *BS = BE->getBaseSpecifier();
     OS << "~" << BS->getType()->getAsCXXRecordDecl()->getName() << "()";
Index: test/Analysis/delete-dtors-cfg-output.cpp
===================================================================
--- test/Analysis/delete-dtors-cfg-output.cpp	(revision 0)
+++ test/Analysis/delete-dtors-cfg-output.cpp	(revision 0)
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-checker=debug.DumpCFG %s > %t 2>&1
+// RUN: FileCheck --input-file=%t %s
+
+class A {
+public:
+  A() {}
+  ~A() {}
+};
+
+void test_deletedtor() {
+  A *a = new A();
+  delete a;
+}
+
+void test_deleteArraydtor() {
+  A *a = new A[5];
+  delete[] a;
+}
+
+// CHECK: [B1 (ENTRY)]
+// CHECK:   Succs (1): B0
+// CHECK: [B0 (EXIT)]
+// CHECK:   Preds (1): B1
+// CHECK: [B1 (ENTRY)]
+// CHECK:   Succs (1): B0
+// CHECK: [B0 (EXIT)]
+// CHECK:   Preds (1): B1
+// CHECK: [B2 (ENTRY)]
+// CHECK:   Succs (1): B1
+// CHECK: [B1]
+// CHECK:   1:  (CXXConstructExpr, class A)
+// CHECK:   2: new A([B1.1])
+// CHECK:   3: A *a = new A();
+// CHECK:   4: a
+// CHECK:   5: [B1.4] (ImplicitCastExpr, LValueToRValue, class A *)
+// CHECK:   6: [B1.5]->~A()(Implicit destructor)
+// CHECK:   7: delete [B1.5]
+// CHECK:   Preds (1): B2
+// CHECK:   Succs (1): B0
+// CHECK: [B0 (EXIT)]
+// CHECK:   Preds (1): B1
+// CHECK: [B2 (ENTRY)]
+// CHECK:   Succs (1): B1
+// CHECK: [B1]
+// CHECK:   1: 5
+// CHECK:   2:  (CXXConstructExpr, class A)
+// CHECK:   4: A *a = new A [5];
+// CHECK:   5: a
+// CHECK:   6: [B1.5] (ImplicitCastExpr, LValueToRValue, class A *)
+// CHECK:   7: [B1.6]->~A()(Implicit destructor)
+// CHECK:   8: delete [] [B1.6]
+// CHECK:   Preds (1): B2
+// CHECK:   Succs (1): B0
+// CHECK: [B0 (EXIT)]
+// CHECK:   Preds (1): B1
+
Index: include/clang/Analysis/CFG.h
===================================================================
--- include/clang/Analysis/CFG.h	(revision 189733)
+++ include/clang/Analysis/CFG.h	(working copy)
@@ -43,6 +43,8 @@
   class PrinterHelper;
   class LangOptions;
   class ASTContext;
+  class CXXRecordDecl;
+  class CXXDeleteExpr;
 
 /// CFGElement - Represents a top-level expression in a basic block.
 class CFGElement {
@@ -53,6 +55,7 @@
     Initializer,
     // dtor kind
     AutomaticObjectDtor,
+    DeleteDtor,
     BaseDtor,
     MemberDtor,
     TemporaryDtor,
@@ -185,6 +188,31 @@
   }
 };
 
+/// CFGDeleteDtor - Represents C++ object destructor  generated
+/// from a call to delete.
+class CFGDeleteDtor : public CFGImplicitDtor {
+public:
+  CFGDeleteDtor(const CXXRecordDecl *RD, const CXXDeleteExpr *DE)
+      : CFGImplicitDtor(DeleteDtor, RD, DE) {}
+
+  const CXXRecordDecl *getCXXRecordDecl() const {
+    return static_cast<CXXRecordDecl*>(Data1.getPointer());
+  }
+
+  // Get Delete expression which triggered the destructor call.
+  const CXXDeleteExpr *getDeleteExpr() {
+    return static_cast<CXXDeleteExpr *>(Data2.getPointer());
+  }
+
+
+private:
+  friend class CFGElement;
+  CFGDeleteDtor() {}
+  static bool isKind(const CFGElement &elem) {
+    return elem.getKind() == DeleteDtor;
+  }
+};
+
 /// CFGBaseDtor - Represents C++ object destructor implicitly generated for
 /// base object in destructor.
 class CFGBaseDtor : public CFGImplicitDtor {
@@ -563,6 +591,10 @@
   void appendAutomaticObjDtor(VarDecl *VD, Stmt *S, BumpVectorContext &C) {
     Elements.push_back(CFGAutomaticObjDtor(VD, S), C);
   }
+  
+  void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) {
+    Elements.push_back(CFGDeleteDtor(RD, DE), C);
+  }
 
   // Destructors must be inserted in reversed order. So insertion is in two
   // steps. First we prepare space for some number of elements, then we insert
Index: include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
===================================================================
--- include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h	(revision 189733)
+++ include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h	(working copy)
@@ -203,6 +203,8 @@
 
   void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, 
                                ExplodedNode *Pred, ExplodedNodeSet &Dst);
+  void ProcessDeleteDtor(const CFGDeleteDtor D, 
+                         ExplodedNode *Pred, ExplodedNodeSet &Dst);
   void ProcessBaseDtor(const CFGBaseDtor D,
                        ExplodedNode *Pred, ExplodedNodeSet &Dst);
   void ProcessMemberDtor(const CFGMemberDtor D,
