Skip to content

Commit 4fa774d

Browse files
committed
Allow ObjC superclass to disable init inheritance
ObjC classes which have only factory and convenience initializers cannot allow their convenience inits to be inherited. To provide these classes with a reliable opt-out, tweak support for @_hasMissingDesignatedInitializers so that it affects ObjC classes even if they’re in the same module as one another. Fixes rdar://48511013.
1 parent b779351 commit 4fa774d

File tree

3 files changed

+20
-1
lines changed

3 files changed

+20
-1
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1231,7 +1231,8 @@ InheritsSuperclassInitializersRequest::evaluate(Evaluator &eval,
12311231

12321232
// If the superclass has known-missing designated initializers, inheriting
12331233
// is unsafe.
1234-
if (superclassDecl->getModuleContext() != decl->getParentModule() &&
1234+
if ((superclassDecl->hasClangNode() ||
1235+
superclassDecl->getModuleContext() != decl->getParentModule()) &&
12351236
superclassDecl->hasMissingDesignatedInitializers())
12361237
return false;
12371238

test/ClangImporter/Inputs/custom-modules/ObjCParseExtras.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,3 +260,10 @@ struct TrivialToCopy {
260260
@interface SuperclassWithDesignatedInitInCategory ()
261261
-(instancetype) initWithI:(NSInteger)i __attribute__((objc_designated_initializer));
262262
@end
263+
264+
__attribute__((swift_attr("@_hasMissingDesignatedInitializers")))
265+
@interface NoConvenienceInitInheritanceBase : NSObject
266+
@end
267+
268+
@interface NoConvenienceInitInheritance : NoConvenienceInitInheritanceBase
269+
@end

test/ClangImporter/objc_init.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,14 @@ extension SuperclassWithDesignatedInitInCategory {
210210
func testConvenienceInitInheritance() {
211211
_ = SubclassWithSwiftPrivateDesignatedInit(y: 5)
212212
}
213+
214+
// ...unless the superclass has been marked with
215+
// @_hasMissingDesignatedInitializers to disable this behavior.
216+
extension NoConvenienceInitInheritanceBase {
217+
convenience init(y: Int) { self.init() }
218+
}
219+
220+
func testNoConvenienceInitInheritance() {
221+
_ = NoConvenienceInitInheritanceBase(y: 42)
222+
_ = NoConvenienceInitInheritance(y: 42) // expected-error {{argument passed to call that takes no arguments}}
223+
}

0 commit comments

Comments
 (0)