]> granicus.if.org Git - clang/commitdiff
Added generation of destructors for constant size arrays.
authorMarcin Swiderski <marcin.sfider@gmail.com>
Mon, 25 Oct 2010 07:00:40 +0000 (07:00 +0000)
committerMarcin Swiderski <marcin.sfider@gmail.com>
Mon, 25 Oct 2010 07:00:40 +0000 (07:00 +0000)
There's only one destructor call generated for each not empty array (at least for now this should be enough).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117251 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/CFG.cpp
test/Analysis/auto-obj-dtors-cfg-output.cpp

index 6f7be9a252ce198622ca890ffd6712445c99c80e..1026035b3bbdc2f178aef9f3c25eb77ef802baf7 100644 (file)
@@ -641,8 +641,14 @@ LocalScope* CFGBuilder::addLocalScopeForVarDecl(VarDecl* VD,
       return Scope;
   }
 
-  // Check if type is a C++ class with non-trivial destructor.
+  // Check for constant size array. Set type to array element type.
+  if (const ConstantArrayType *AT = Context->getAsConstantArrayType(QT)) {
+    if (AT->getSize() == 0)
+      return Scope;
+    QT = AT->getElementType();
+  }
 
+  // Check if type is a C++ class with non-trivial destructor.
   if (const CXXRecordDecl* CD = QT->getAsCXXRecordDecl())
     if (!CD->hasTrivialDestructor()) {
       // Add the variable to scope
@@ -2707,9 +2713,11 @@ static void print_elem(llvm::raw_ostream &OS, StmtPrinterHelper* Helper,
     VarDecl* VD = DE.getVarDecl();
     Helper->handleDecl(VD, OS);
 
-    Type* T = VD->getType().getTypePtr();
+    const Type* T = VD->getType().getTypePtr();
     if (const ReferenceType* RT = T->getAs<ReferenceType>())
       T = RT->getPointeeType().getTypePtr();
+    else if (const Type *ET = T->getArrayElementTypeNoTypeQual())
+      T = ET;
 
     OS << ".~" << T->getAsCXXRecordDecl()->getName().str() << "()";
     OS << " (Implicit destructor)\n";
index 8a6c55b60be8839dc7b2293bbc449e06aade9d6b..129a0c2616e1c1c8dd3fc36f93184b3b35b88e08 100644 (file)
@@ -16,6 +16,11 @@ void test_const_ref() {
   const A& c = A();
 }
 
+void test_array() {
+  A a[2];
+  A b[0];
+}
+
 void test_scope() {
   A a;
   { A c;
@@ -165,6 +170,18 @@ void test_catch_copy() {
 // CHECK:     Predecessors (1): B1
 // CHECK:     Successors (0):
 // CHECK:  [ B2 (ENTRY) ]
+// CHECK:    Predecessors (0):
+// CHECK:    Successors (1): B1
+// CHECK:  [ B1 ]
+// CHECK:      1: A a[2];
+// CHECK:      2: A b[0];
+// CHECK:      3: [B1.1].~A() (Implicit destructor)
+// CHECK:    Predecessors (1): B2
+// CHECK:    Successors (1): B0
+// CHECK:  [ B0 (EXIT) ]
+// CHECK:    Predecessors (1): B1
+// CHECK:    Successors (0):
+// CHECK:  [ B2 (ENTRY) ]
 // CHECK:     Predecessors (0):
 // CHECK:     Successors (1): B1
 // CHECK:  [ B1 ]