Skip to content

Commit 477933b

Browse files
committed
Fix @objc checking for optional value types.
We previously treated 'NSFoo?' as ObjC-compatible simply because 'NSFoo' was an imported type or was marked '@objc'.
1 parent 4d9e8d9 commit 477933b

File tree

2 files changed

+12
-7
lines changed

2 files changed

+12
-7
lines changed

lib/AST/Type.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2090,10 +2090,6 @@ getForeignRepresentable(Type type, ForeignLanguage language,
20902090

20912091
ASTContext &ctx = nominal->getASTContext();
20922092

2093-
// If the type is @objc, it is trivially representable in Objective-C.
2094-
if (nominal->isObjC() && language == ForeignLanguage::ObjectiveC)
2095-
return { ForeignRepresentableKind::Trivial, nullptr };
2096-
20972093
// Unmanaged<T> can be trivially represented in Objective-C if T
20982094
// is trivially represented in Objective-C.
20992095
if (language == ForeignLanguage::ObjectiveC &&
@@ -2113,14 +2109,17 @@ getForeignRepresentable(Type type, ForeignLanguage language,
21132109

21142110
// If the type was imported from Clang, check whether it is
21152111
// representable in the requested language.
2116-
if (nominal->hasClangNode()) {
2112+
if (nominal->hasClangNode() || nominal->isObjC()) {
21172113
switch (language) {
21182114
case ForeignLanguage::C:
21192115
// Imported structs and enums are trivially representable in C.
21202116
// FIXME: This is not entirely true; we need to check that
21212117
// all of the exposed parts are representable in C.
2122-
if (isa<StructDecl>(nominal) || isa<EnumDecl>(nominal))
2118+
if (isa<StructDecl>(nominal) || isa<EnumDecl>(nominal)) {
2119+
if (wasOptional)
2120+
break;
21232121
return { ForeignRepresentableKind::Trivial, nullptr };
2122+
}
21242123

21252124
// Imported classes and protocols are not.
21262125
if (isa<ClassDecl>(nominal) || isa<ProtocolDecl>(nominal))
@@ -2129,7 +2128,10 @@ getForeignRepresentable(Type type, ForeignLanguage language,
21292128
llvm_unreachable("Unhandled nominal type declaration");
21302129

21312130
case ForeignLanguage::ObjectiveC:
2132-
// Anything Clang imported is trivially representable in Objective-C.
2131+
if (isa<StructDecl>(nominal) || isa<EnumDecl>(nominal))
2132+
if (wasOptional)
2133+
break;
2134+
21332135
return { ForeignRepresentableKind::Trivial, nullptr };
21342136
}
21352137
}

test/attr/attr_objc.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,7 @@ class infer_instanceVar1 {
11061106
var var_Optional12: OpaquePointer?
11071107
var var_Optional13: UnsafeMutablePointer<Int>?
11081108
var var_Optional14: UnsafeMutablePointer<Class_ObjC1>?
1109+
var var_Optional15: NSRange? // another bridged struct
11091110

11101111
// CHECK-LABEL: @objc var var_Optional1: Class_ObjC1?
11111112
// CHECK-LABEL: @objc var var_Optional2: Protocol_ObjC1?
@@ -1121,6 +1122,7 @@ class infer_instanceVar1 {
11211122
// CHECK-LABEL: @objc var var_Optional12: OpaquePointer?
11221123
// CHECK-LABEL: @objc var var_Optional13: UnsafeMutablePointer<Int>?
11231124
// CHECK-LABEL: @objc var var_Optional14: UnsafeMutablePointer<Class_ObjC1>?
1125+
// CHECK-LABEL: @objc var var_Optional15: NSRange?
11241126

11251127

11261128
var var_ImplicitlyUnwrappedOptional1: Class_ObjC1!
@@ -1159,6 +1161,7 @@ class infer_instanceVar1 {
11591161
var var_Optional_fail14: CBool?
11601162
var var_Optional_fail20: AnyObject??
11611163
var var_Optional_fail21: AnyObject.Type??
1164+
var var_Optional_fail22: NSComparisonResult? // a non-bridged imported value type
11621165
// CHECK-NOT: @objc{{.*}}Optional_fail
11631166

11641167
// CHECK-LABEL: @objc var var_CFunctionPointer_1: @convention(c) () -> ()

0 commit comments

Comments
 (0)