Skip to content

Commit d0a056f

Browse files
lilyballKevin Ballard
authored andcommitted
[PrintAsObjC] Add unavailable initializers for private overrides
When a public initializer is overridden with a private one, we need to mark these as unavailable to Obj-C as they're not supposed to be callable even though they do exist.
1 parent 99be45f commit d0a056f

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

lib/PrintAsObjC/PrintAsObjC.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,19 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
137137
visit(const_cast<Decl *>(D));
138138
}
139139

140-
bool shouldInclude(const ValueDecl *VD) {
141-
return (VD->isObjC() || VD->getAttrs().hasAttribute<CDeclAttr>()) &&
142-
VD->getFormalAccess() >= minRequiredAccess;
140+
bool shouldInclude(const ValueDecl *VD, bool checkParent = true) {
141+
if (!(VD->isObjC() || VD->getAttrs().hasAttribute<CDeclAttr>()))
142+
return false;
143+
if (VD->getFormalAccess() >= minRequiredAccess) {
144+
return true;
145+
} else if (checkParent) {
146+
if (auto ctor = dyn_cast<ConstructorDecl>(VD)) {
147+
// Check if we're overriding an initializer that is visible to obj-c
148+
if (auto parent = ctor->getOverriddenDecl())
149+
return shouldInclude(parent, false);
150+
}
151+
}
152+
return false;
143153
}
144154

145155
private:
@@ -477,7 +487,10 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
477487

478488
// Swift designated initializers are Objective-C designated initializers.
479489
if (auto ctor = dyn_cast<ConstructorDecl>(AFD)) {
480-
if (ctor->hasStubImplementation()) {
490+
if (ctor->hasStubImplementation()
491+
|| ctor->getFormalAccess() < minRequiredAccess) {
492+
// This will only be reached if the overridden initializer has the
493+
// required access
481494
os << " SWIFT_UNAVAILABLE";
482495
} else if (ctor->isDesignatedInit() &&
483496
!isa<ProtocolDecl>(ctor->getDeclContext())) {

test/PrintAsObjC/classes.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ class ClassWithCustomNameSub : ClassWithCustomName {}
108108
// CHECK-NEXT: - (nonnull instancetype)initWithString:(NSString * _Nonnull)s boolean:(BOOL)b;
109109
// CHECK-NEXT: - (nullable instancetype)initWithBoolean:(BOOL)b;
110110
// CHECK-NEXT: - (nonnull instancetype)initForFun OBJC_DESIGNATED_INITIALIZER;
111+
// CHECK-NEXT: - (nonnull instancetype)initWithMoreFun OBJC_DESIGNATED_INITIALIZER;
112+
// CHECK-NEXT: - (nonnull instancetype)initWithEvenMoreFun OBJC_DESIGNATED_INITIALIZER;
111113
// CHECK-NEXT: @end
112114
@objc class Initializers {
113115
init() {}
@@ -120,25 +122,39 @@ class ClassWithCustomNameSub : ClassWithCustomName {}
120122
convenience init?(boolean b: ObjCBool) { self.init() }
121123

122124
init(forFun: ()) { }
125+
126+
init(moreFun: ()) { }
127+
128+
init(evenMoreFun: ()) { }
123129
}
124130

125131
// CHECK-LABEL: @interface InheritedInitializers
126132
// CHECK-NEXT: - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
133+
// CHECK-NEXT: - (nonnull instancetype)initWithFloat:(float)f SWIFT_UNAVAILABLE;
134+
// CHECK-NEXT: - (nonnull instancetype)initWithMoreFun SWIFT_UNAVAILABLE;
127135
// CHECK-NEXT: - (nonnull instancetype)initForFun SWIFT_UNAVAILABLE;
136+
// CHECK-NEXT: - (nonnull instancetype)initWithEvenMoreFun SWIFT_UNAVAILABLE;
128137
// CHECK-NEXT: @end
129138
@objc class InheritedInitializers : Initializers {
130139
override init() {
131140
super.init()
132141
}
142+
143+
private convenience init(float f: Float) { self.init() }
144+
145+
private override init(moreFun: ()) { super.init() }
133146
}
134147

135148
// CHECK-LABEL: @interface InheritedInitializersAgain
136149
// CHECK-NEXT: - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
150+
// CHECK-NEXT: - (nonnull instancetype)initWithEvenMoreFun OBJC_DESIGNATED_INITIALIZER;
137151
// CHECK-NEXT: @end
138152
@objc class InheritedInitializersAgain : InheritedInitializers {
139153
override init() {
140154
super.init()
141155
}
156+
157+
init(evenMoreFun: ()) { super.init() }
142158
}
143159

144160
// NEGATIVE-NOT: NotObjC

0 commit comments

Comments
 (0)