// First destroy member objects.
for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
FE = RD->field_end(); FI != FE; ++FI) {
- if (const CXXRecordDecl *CD = FI->getType()->getAsCXXRecordDecl())
+ // Check for constant size array. Set type to array element type.
+ QualType QT = FI->getType();
+ if (const ConstantArrayType *AT = Context->getAsConstantArrayType(QT)) {
+ if (AT->getSize() == 0)
+ continue;
+ QT = AT->getElementType();
+ }
+
+ if (const CXXRecordDecl *CD = QT->getAsCXXRecordDecl())
if (!CD->hasTrivialDestructor()) {
autoCreateBlock();
appendMemberDtor(Block, *FI);
} else if (CFGMemberDtor ME = E.getAs<CFGMemberDtor>()) {
FieldDecl *FD = ME.getFieldDecl();
+
+ const Type *T = FD->getType().getTypePtr();
+ if (const Type *ET = T->getArrayElementTypeNoTypeQual())
+ T = ET;
+
OS << "this->" << FD->getName();
- OS << ".~" << FD->getType()->getAsCXXRecordDecl()->getName() << "()";
+ OS << ".~" << T->getAsCXXRecordDecl()->getName() << "()";
OS << " (Member object destructor)\n";
}
}
TestOrder::~TestOrder() {}
+class TestArray {
+ A a[2];
+ A b[0];
+public:
+ ~TestArray();
+};
+
+TestArray::~TestArray() {}
+
// CHECK: [ B2 (ENTRY) ]
// CHECK: Predecessors (0):
// CHECK: Successors (1): B1
// CHECK: [ B0 (EXIT) ]
// CHECK: Predecessors (1): B1
// CHECK: Successors (0):
+// CHECK: [ B2 (ENTRY) ]
+// CHECK: Predecessors (0):
+// CHECK: Successors (1): B1
+// CHECK: [ B1 ]
+// CHECK: 1: this->a.~A() (Member object destructor)
+// CHECK: Predecessors (1): B2
+// CHECK: Successors (1): B0
+// CHECK: [ B0 (EXIT) ]
+// CHECK: Predecessors (1): B1
+// CHECK: Successors (0):