Skip to content

Commit 859d0a7

Browse files
committed
[TBDGen] The non-deallocating destructor applies to some @objc classes.
The non-deallocating destructor doesn't exists when dealloc can be overriden, which means any class that inherits from a class defined in Objective-C. This isn't necessarily all @objc classes, because of the -disable-objc-attr-requires-foundation-module flag. Fixes rdar://problem/40542246.
1 parent 24abeca commit 859d0a7

File tree

4 files changed

+54
-38
lines changed

4 files changed

+54
-38
lines changed

lib/TBDGen/TBDGen.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@
2424
#include "swift/IRGen/Linking.h"
2525
#include "swift/SIL/FormalLinkage.h"
2626
#include "swift/SIL/SILDeclRef.h"
27-
#include "swift/SIL/SILWitnessTable.h"
27+
#include "swift/SIL/SILModule.h"
2828
#include "swift/SIL/SILVTableVisitor.h"
29+
#include "swift/SIL/SILWitnessTable.h"
2930
#include "swift/SIL/TypeLowering.h"
3031
#include "llvm/ADT/StringSet.h"
3132

@@ -233,13 +234,6 @@ void TBDGenVisitor::visitClassDecl(ClassDecl *CD) {
233234
auto hasFieldOffset = var && var->hasStorage() && !var->isStatic();
234235
if (hasFieldOffset)
235236
addSymbol(LinkEntity::forFieldOffset(var));
236-
237-
// The non-allocating forms of the destructors.
238-
if (auto dtor = dyn_cast<DestructorDecl>(value)) {
239-
// ObjC classes don't have a symbol for their destructor.
240-
if (!isObjC)
241-
addSymbol(SILDeclRef(dtor, SILDeclRef::Kind::Destroyer));
242-
}
243237
}
244238

245239
visitNominalTypeDecl(CD);
@@ -300,6 +294,19 @@ void TBDGenVisitor::visitConstructorDecl(ConstructorDecl *CD) {
300294
visitAbstractFunctionDecl(CD);
301295
}
302296

297+
void TBDGenVisitor::visitDestructorDecl(DestructorDecl *DD) {
298+
// Class destructors come in two forms (deallocating and non-deallocating),
299+
// like constructors above. This is the deallocating one:
300+
visitAbstractFunctionDecl(DD);
301+
302+
auto parentClass = DD->getParent()->getAsClassOrClassExtensionContext();
303+
304+
// But the non-deallocating one doesn't apply to some @objc classes.
305+
if (!Lowering::usesObjCAllocator(parentClass)) {
306+
addSymbol(SILDeclRef(DD, SILDeclRef::Kind::Destroyer));
307+
}
308+
}
309+
303310
void TBDGenVisitor::visitExtensionDecl(ExtensionDecl *ED) {
304311
if (!ED->getExtendedType()->isExistentialType()) {
305312
addConformances(ED);

lib/TBDGen/TBDGenVisitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
102102

103103
void visitConstructorDecl(ConstructorDecl *CD);
104104

105+
void visitDestructorDecl(DestructorDecl *DD);
106+
105107
void visitExtensionDecl(ExtensionDecl *ED);
106108

107109
void visitProtocolDecl(ProtocolDecl *PD);

test/TBD/class_objc.swift

Lines changed: 0 additions & 30 deletions
This file was deleted.

test/TBD/class_objc.swift.gyb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %gyb %s > %t/main.swift
3+
4+
// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -import-objc-header %S/Inputs/objc_class_header.h -validate-tbd-against-ir=all %t/main.swift -disable-objc-attr-requires-foundation-module
5+
6+
// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -import-objc-header %S/Inputs/objc_class_header.h -validate-tbd-against-ir=all %t/main.swift -disable-objc-attr-requires-foundation-module
7+
8+
// REQUIRES: objc_interop
9+
10+
import Foundation
11+
12+
% names = ["Public", "Internal", "Private"]
13+
14+
% for i, name in enumerate(names):
15+
% access = name.lower()
16+
17+
// a class by itself
18+
${access} class ${name}Empty: NSObject {}
19+
20+
// subclasses of that
21+
% for subname in names[i:]:
22+
% subaccess = subname.lower()
23+
${subaccess} class ${subname}Sub${name}Empty: ${name}Empty {}
24+
%end
25+
26+
${access} class ${name}InheritObjCProtocol: NSObject, ObjCProtocol {}
27+
28+
// some bugs were revealed when there's @objc without inheriting from
29+
// NSObject.
30+
@objc ${access} class ${name}ObjCOnly {}
31+
32+
%end
33+
34+
@usableFromInline
35+
@objc
36+
internal class InternalObjCOnlyUsableFromInline {}
37+

0 commit comments

Comments
 (0)