Skip to content

Commit ff7bfa8

Browse files
committed
[Type checker] Handle inferred @objc for all accessor kinds.
Due to the wanton use of 'if' rather than 'switch', non-observing, non-get/set ccessors that got marked '@objc' would cause an assertion. Fix the materializeForSet case from the bug report as well as the addressor case. Fixes SR-5025 / rdar://problem/32426538.
1 parent 8def4d8 commit ff7bfa8

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3296,6 +3296,8 @@ ERROR(objc_invalid_on_func_curried,none,
32963296
"cannot be represented in Objective-C", (unsigned))
32973297
ERROR(objc_observing_accessor, none,
32983298
"observing accessors are not allowed to be marked @objc", ())
3299+
ERROR(objc_addressor, none,
3300+
"addressors are not allowed to be marked @objc", ())
32993301
ERROR(objc_invalid_on_func_variadic,none,
33003302
"method cannot be %" OBJC_ATTR_SELECT "0 because it has a variadic "
33013303
"parameter", (unsigned))

lib/Sema/TypeCheckType.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3515,17 +3515,36 @@ bool TypeChecker::isRepresentableInObjC(
35153515
return false;
35163516
}
35173517

3518-
// willSet/didSet implementations are never exposed to objc, they are
3519-
// always directly dispatched from the synthesized setter.
3520-
if (FD->isObservingAccessor()) {
3518+
switch (FD->getAccessorKind()) {
3519+
case AccessorKind::NotAccessor:
3520+
llvm_unreachable("already checking for accessor-ness");
3521+
3522+
case AccessorKind::IsDidSet:
3523+
case AccessorKind::IsWillSet:
3524+
// willSet/didSet implementations are never exposed to objc, they are
3525+
// always directly dispatched from the synthesized setter.
35213526
if (Diagnose) {
35223527
diagnose(AFD->getLoc(), diag::objc_observing_accessor);
35233528
describeObjCReason(*this, AFD, Reason);
35243529
}
35253530
return false;
3531+
3532+
case AccessorKind::IsGetter:
3533+
case AccessorKind::IsSetter:
3534+
return true;
3535+
3536+
case AccessorKind::IsMaterializeForSet:
3537+
// materializeForSet is synthesized, so never complain about it
3538+
return false;
3539+
3540+
case AccessorKind::IsAddressor:
3541+
case AccessorKind::IsMutableAddressor:
3542+
if (Diagnose) {
3543+
diagnose(AFD->getLoc(), diag::objc_addressor);
3544+
describeObjCReason(*this, AFD, Reason);
3545+
}
3546+
return false;
35263547
}
3527-
assert(FD->isGetterOrSetter() && "missing diags for other accessors");
3528-
return true;
35293548
}
35303549

35313550
unsigned ExpectedParamPatterns = 1;

test/attr/attr_objc.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2262,3 +2262,23 @@ extension SubclassInfersFromProtocol2 {
22622262
@objc class NeverReturningMethod {
22632263
@objc func doesNotReturn() -> Never {}
22642264
}
2265+
2266+
// SR-5025
2267+
class User: NSObject {
2268+
}
2269+
2270+
@objc extension User {
2271+
var name: String {
2272+
get {
2273+
return "No name"
2274+
}
2275+
set {
2276+
// Nothing
2277+
}
2278+
}
2279+
2280+
var other: String {
2281+
unsafeAddress { // expected-error{{addressors are not allowed to be marked @objc}}
2282+
}
2283+
}
2284+
}

0 commit comments

Comments
 (0)