Skip to content

Sema: Explicitly check for 'inout' parameters on @objc functions #17236

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -3515,16 +3515,16 @@ WARNING(witness_swift3_objc_inference,none,
(DescriptiveDeclKind, DeclName, Type))


ERROR(objc_invalid_on_func_curried,none,
"method cannot be %" OBJC_ATTR_SELECT "0 because curried functions "
"cannot be represented in Objective-C", (unsigned))
ERROR(objc_observing_accessor, none,
"observing accessors are not allowed to be marked @objc", ())
ERROR(objc_addressor, none,
"addressors are not allowed to be marked @objc", ())
ERROR(objc_invalid_on_func_variadic,none,
"method cannot be %" OBJC_ATTR_SELECT "0 because it has a variadic "
"parameter", (unsigned))
ERROR(objc_invalid_on_func_inout,none,
"method cannot be %" OBJC_ATTR_SELECT "0 because inout "
"parameters cannot be represented in Objective-C", (unsigned))
ERROR(objc_invalid_on_func_param_type,none,
"method cannot be %" OBJC_ATTR_SELECT "1 because the type of the "
"parameter %0 cannot be represented in Objective-C", (unsigned, unsigned))
Expand Down
32 changes: 15 additions & 17 deletions lib/Sema/TypeCheckType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3360,7 +3360,7 @@ static bool isParamListRepresentableInObjC(TypeChecker &TC,
unsigned NumParams = PL->size();
for (unsigned ParamIndex = 0; ParamIndex != NumParams; ParamIndex++) {
auto param = PL->get(ParamIndex);

// Swift Varargs are not representable in Objective-C.
if (param->isVariadic()) {
if (Diagnose && shouldDiagnoseObjCReason(Reason, TC.Context)) {
Expand All @@ -3369,10 +3369,22 @@ static bool isParamListRepresentableInObjC(TypeChecker &TC,
.highlight(param->getSourceRange());
describeObjCReason(TC, AFD, Reason);
}

return false;
}


// Swift inout parameters are not representable in Objective-C.
if (param->isInOut()) {
if (Diagnose && shouldDiagnoseObjCReason(Reason, TC.Context)) {
TC.diagnose(param->getStartLoc(), diag::objc_invalid_on_func_inout,
getObjCDiagnosticAttrKind(Reason))
.highlight(param->getSourceRange());
describeObjCReason(TC, AFD, Reason);
}

return false;
}

if (param->getType()->isRepresentableIn(
ForeignLanguage::ObjectiveC,
const_cast<AbstractFunctionDecl *>(AFD)))
Expand Down Expand Up @@ -3601,20 +3613,6 @@ bool TypeChecker::isRepresentableInObjC(
llvm_unreachable("bad kind");
}

if (auto *FD = dyn_cast<FuncDecl>(AFD)) {
unsigned ExpectedParamPatterns = 1;
if (FD->getImplicitSelfDecl())
ExpectedParamPatterns++;
if (FD->getParameterLists().size() != ExpectedParamPatterns) {
if (Diagnose) {
diagnose(AFD->getLoc(), diag::objc_invalid_on_func_curried,
getObjCDiagnosticAttrKind(Reason));
describeObjCReason(*this, AFD, Reason);
}
return false;
}
}

// As a special case, an initializer with a single, named parameter of type
// '()' is always representable in Objective-C. This allows us to cope with
// zero-parameter methods with selectors that are longer than "init". For
Expand Down
2 changes: 2 additions & 0 deletions test/attr/attr_objc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ class ConcreteContext3 {

typealias NSCodingExistential = NSCoding.Type

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

Expand Down