From 52e4bc1fede9b96bf6caec8fe6138e675ea14146 Mon Sep 17 00:00:00 2001 From: Marcin Swiderski Date: Mon, 25 Oct 2010 07:00:40 +0000 Subject: [PATCH] Added generation of destructors for constant size arrays. There's only one destructor call generated for each not empty array (at least for now this should be enough). llvm-svn: 117251 --- clang/lib/Analysis/CFG.cpp | 12 ++++++++++-- .../test/Analysis/auto-obj-dtors-cfg-output.cpp | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 6f7be9a252ce..1026035b3bbd 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -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()) T = RT->getPointeeType().getTypePtr(); + else if (const Type *ET = T->getArrayElementTypeNoTypeQual()) + T = ET; OS << ".~" << T->getAsCXXRecordDecl()->getName().str() << "()"; OS << " (Implicit destructor)\n"; diff --git a/clang/test/Analysis/auto-obj-dtors-cfg-output.cpp b/clang/test/Analysis/auto-obj-dtors-cfg-output.cpp index 8a6c55b60be8..129a0c2616e1 100644 --- a/clang/test/Analysis/auto-obj-dtors-cfg-output.cpp +++ b/clang/test/Analysis/auto-obj-dtors-cfg-output.cpp @@ -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 ]