Skip to content

Commit 0ce6de1

Browse files
committed
Sema: Explicitly check for 'inout' parameters on @objc functions
Previously we would produce a non-specific diagnostic about the parameter type not being representable in Objective-C because VarDecl::getType() wrapped the result in an InOutType. Now that this is no longer the case we have to check for inout independently of looking at the type. Fixes <rdar://problem/41129106>.
1 parent 10bf032 commit 0ce6de1

File tree

3 files changed

+20
-3
lines changed

3 files changed

+20
-3
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3522,6 +3522,9 @@ ERROR(objc_addressor, none,
35223522
ERROR(objc_invalid_on_func_variadic,none,
35233523
"method cannot be %" OBJC_ATTR_SELECT "0 because it has a variadic "
35243524
"parameter", (unsigned))
3525+
ERROR(objc_invalid_on_func_inout,none,
3526+
"method cannot be %" OBJC_ATTR_SELECT "0 because inout "
3527+
"parameters cannot be represented in Objective-C", (unsigned))
35253528
ERROR(objc_invalid_on_func_param_type,none,
35263529
"method cannot be %" OBJC_ATTR_SELECT "1 because the type of the "
35273530
"parameter %0 cannot be represented in Objective-C", (unsigned, unsigned))

lib/Sema/TypeCheckType.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3360,7 +3360,7 @@ static bool isParamListRepresentableInObjC(TypeChecker &TC,
33603360
unsigned NumParams = PL->size();
33613361
for (unsigned ParamIndex = 0; ParamIndex != NumParams; ParamIndex++) {
33623362
auto param = PL->get(ParamIndex);
3363-
3363+
33643364
// Swift Varargs are not representable in Objective-C.
33653365
if (param->isVariadic()) {
33663366
if (Diagnose && shouldDiagnoseObjCReason(Reason, TC.Context)) {
@@ -3369,10 +3369,22 @@ static bool isParamListRepresentableInObjC(TypeChecker &TC,
33693369
.highlight(param->getSourceRange());
33703370
describeObjCReason(TC, AFD, Reason);
33713371
}
3372-
3372+
33733373
return false;
33743374
}
3375-
3375+
3376+
// Swift inout parameters are not representable in Objective-C.
3377+
if (param->isInOut()) {
3378+
if (Diagnose && shouldDiagnoseObjCReason(Reason, TC.Context)) {
3379+
TC.diagnose(param->getStartLoc(), diag::objc_invalid_on_func_inout,
3380+
getObjCDiagnosticAttrKind(Reason))
3381+
.highlight(param->getSourceRange());
3382+
describeObjCReason(TC, AFD, Reason);
3383+
}
3384+
3385+
return false;
3386+
}
3387+
33763388
if (param->getType()->isRepresentableIn(
33773389
ForeignLanguage::ObjectiveC,
33783390
const_cast<AbstractFunctionDecl *>(AFD)))

test/attr/attr_objc.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,8 @@ class ConcreteContext3 {
354354

355355
typealias NSCodingExistential = NSCoding.Type
356356

357+
@objc func inoutFunc(a: inout Int) {}
358+
// expected-error@-1{{method cannot be marked @objc because inout parameters cannot be represented in Objective-C}}
357359
@objc func metatypeOfExistentialMetatypePram1(a: NSCodingExistential.Protocol) {}
358360
// expected-error@-1{{method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C}}
359361

0 commit comments

Comments
 (0)