Skip to content

Commit 5ef25e7

Browse files
authored
Merge pull request #64623 from hyp/eng/fix-record-des-visit
[interop] do not assume we need to IRGen destructors of fields inside…
2 parents d900706 + b5766fd commit 5ef25e7

File tree

2 files changed

+36
-10
lines changed

2 files changed

+36
-10
lines changed

lib/IRGen/GenClangDecl.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -228,18 +228,20 @@ void IRGenModule::emitClangDecl(const clang::Decl *decl) {
228228
// Unfortunately, implicitly defined CXXDestructorDecls don't have a real
229229
// body, so we need to traverse these manually.
230230
if (auto *dtor = dyn_cast<clang::CXXDestructorDecl>(next)) {
231-
auto cxxRecord = dtor->getParent();
231+
if (dtor->isImplicit() || dtor->hasBody()) {
232+
auto cxxRecord = dtor->getParent();
232233

233-
for (auto field : cxxRecord->fields()) {
234-
if (auto fieldCxxRecord = field->getType()->getAsCXXRecordDecl())
235-
if (auto *fieldDtor = fieldCxxRecord->getDestructor())
236-
callback(fieldDtor);
237-
}
234+
for (auto field : cxxRecord->fields()) {
235+
if (auto fieldCxxRecord = field->getType()->getAsCXXRecordDecl())
236+
if (auto *fieldDtor = fieldCxxRecord->getDestructor())
237+
callback(fieldDtor);
238+
}
238239

239-
for (auto base : cxxRecord->bases()) {
240-
if (auto baseCxxRecord = base.getType()->getAsCXXRecordDecl())
241-
if (auto *baseDtor = baseCxxRecord->getDestructor())
242-
callback(baseDtor);
240+
for (auto base : cxxRecord->bases()) {
241+
if (auto baseCxxRecord = base.getType()->getAsCXXRecordDecl())
242+
if (auto *baseDtor = baseCxxRecord->getDestructor())
243+
callback(baseDtor);
244+
}
243245
}
244246
}
245247

test/Interop/Cxx/class/delete-operator-destructor-ref-irgen.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,29 @@ private:
3333
BaseClass *pointer;
3434
};
3535

36+
class ForwardClassDecl;
37+
38+
template<class T>
39+
class ContainerWithForward {
40+
public:
41+
inline ~ContainerWithForward() {
42+
if (sizeof(T) > 0)
43+
referencedSymbol();
44+
}
45+
};
46+
47+
class ClassWithOutOfLineDestructor {
48+
public:
49+
~ClassWithOutOfLineDestructor();
50+
51+
ContainerWithForward<ForwardClassDecl> field;
52+
};
53+
54+
ClassWithOutOfLineDestructor *getClassWithOutOfLineDestructorValue();
55+
56+
inline void testMethodDestructorFwdDecl() {
57+
delete getClassWithOutOfLineDestructorValue();
58+
}
3659

3760
//--- test.swift
3861

@@ -41,6 +64,7 @@ import DestroyedUsingDelete
4164
public func test() {
4265
let i = Container()
4366
i.method()
67+
testMethodDestructorFwdDecl()
4468
}
4569

4670
// Make sure we reach destructor accessible from `delete` statement.

0 commit comments

Comments
 (0)