Skip to content

Commit 37e42d1

Browse files
committed
Handle inherited required inits in @objcImpl
Because `required init`s do not have the `override` keyword, they are always treated as member implementations (if they pass other checks). However, these methods sometimes actually are overrides, and when they are, they should not be treated as member implementations. This results in required inits being treated as candidates when there won’t be a requirement for them to match. Hack around this by separately checking for this situation and skipping the affected members. Fixes rdar://112910098.
1 parent ae76f51 commit 37e42d1

File tree

3 files changed

+22
-0
lines changed

3 files changed

+22
-0
lines changed

lib/Sema/TypeCheckDeclObjC.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3507,6 +3507,15 @@ class ObjCImplementationChecker {
35073507
for (auto &pair : unmatchedCandidates) {
35083508
auto cand = pair.first;
35093509

3510+
// `isObjCMemberImplementation()` incorrectly returns true for required
3511+
// inits that are overrides because checking in that accessor would create
3512+
// a cycle between override computations and access control. Don't
3513+
// diagnose such candidates.
3514+
// FIXME: Refactor around this so these methods are never made candidates.
3515+
if (auto ctor = dyn_cast<ConstructorDecl>(cand))
3516+
if (ctor->isRequired() && !ctor->getOverriddenDecls().empty())
3517+
continue;
3518+
35103519
diagnose(cand, diag::member_of_objc_implementation_not_objc_or_final,
35113520
cand, cand->getDeclContext()->getSelfClassDecl());
35123521

test/decl/ext/Inputs/objc_implementation.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,12 @@
157157

158158
@end
159159

160+
@interface ObjCImplSubclass : ObjCClass
161+
162+
@end
163+
164+
165+
160166
struct ObjCStruct {
161167
int foo;
162168
};

test/decl/ext/objc_implementation.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,13 @@ protocol EmptySwiftProto {}
386386
func nonPointerArgument(_: CInt!) {} // expected-error {{method cannot be implicitly @objc because the type of the parameter cannot be represented in Objective-C}}
387387
}
388388

389+
@_objcImplementation extension ObjCImplSubclass {
390+
@objc(initFromProtocol1:)
391+
required public init?(fromProtocol1: CInt) {
392+
// OK
393+
}
394+
}
395+
389396
@_objcImplementation extension ObjCClass {}
390397
// expected-error@-1 {{duplicate implementation of Objective-C class 'ObjCClass'}}
391398

0 commit comments

Comments
 (0)