Skip to content

Commit 25d380c

Browse files
authored
[test] @objc optional should always use a dynamic dispatch (#20487)
Right now we're not being careful about 'optional' in witness tables for parseable interfaces; we're listing the requirement as the implementation even if the requirement is optional. As long as we don't optimize based on that information, though, we should be okay.
1 parent 2863b6c commit 25d380c

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

test/ParseableInterface/Conformances.swiftinterface

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
// swift-module-flags:
33

44
// RUN: %empty-directory(%t)
5-
// RUN: %target-swift-frontend -emit-module-path %t/Conformances.swiftmodule -enable-resilience -emit-sil -o %t/Conformances.sil %s
5+
// RUN: %target-swift-frontend -emit-module-path %t/Conformances.swiftmodule -enable-resilience -emit-sil -o %t/Conformances.sil -enable-objc-interop -disable-objc-attr-requires-foundation-module %s
66
// RUN: %FileCheck -check-prefix CHECK-MODULE %s < %t/Conformances.sil
77
// RUN: %FileCheck -check-prefix NEGATIVE-MODULE %s < %t/Conformances.sil
8-
// RUN: %target-swift-frontend -emit-sil -I %t %S/Inputs/ConformancesUser.swift -O | %FileCheck %s
8+
// RUN: %target-swift-frontend -enable-objc-interop -emit-sil -I %t %S/Inputs/ConformancesUser.swift -O | %FileCheck %s
99

1010
public protocol MyProto {
1111
init()
@@ -59,3 +59,24 @@ public struct ResilientStructImpl: MyProto {
5959
// CHECK: witness_method $ResilientStructImpl, #MyProto.prop!setter.1
6060
// CHECK: witness_method $ResilientStructImpl, #MyProto.subscript!getter.1
6161
// CHECK: end sil function '$s16ConformancesUser13testResilientSiyF'
62+
63+
64+
@objc public protocol OptionalReqs {
65+
@objc optional func method()
66+
}
67+
@_fixed_layout
68+
public final class OptionalReqsPresent: OptionalReqs {
69+
public func method () {}
70+
}
71+
@_fixed_layout
72+
public final class OptionalReqsAbsent: OptionalReqs {}
73+
74+
// It would be okay if this one got optimized...
75+
// CHECK-LABEL: sil @$s16ConformancesUser19testOptionalPresentySb0A00d4ReqsE0CF
76+
// CHECK: dynamic_method_br %0 : $OptionalReqsPresent, #OptionalReqs.method!1.foreign
77+
// CHECK: end sil function '$s16ConformancesUser19testOptionalPresentySb0A00d4ReqsE0CF'
78+
79+
// ...but not this one, because the method that's currently absent might get added.
80+
// CHECK-LABEL: sil @$s16ConformancesUser18testOptionalAbsentySb0A00d4ReqsE0CF
81+
// CHECK: dynamic_method_br %0 : $OptionalReqsAbsent, #OptionalReqs.method!1.foreign
82+
// CHECK: end sil function '$s16ConformancesUser18testOptionalAbsentySb0A00d4ReqsE0CF'

test/ParseableInterface/Inputs/ConformancesUser.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,16 @@ public func testOpaque() -> Int {
1818
public func testResilient() -> Int {
1919
return testGeneric(ResilientStructImpl.self)
2020
}
21+
22+
23+
func testOptionalGeneric<T: OptionalReqs>(_ obj: T) -> Bool {
24+
return obj.method?() != nil
25+
}
26+
27+
public func testOptionalPresent(_ obj: OptionalReqsPresent) -> Bool {
28+
return testOptionalGeneric(obj)
29+
}
30+
31+
public func testOptionalAbsent(_ obj: OptionalReqsAbsent) -> Bool {
32+
return testOptionalGeneric(obj)
33+
}

0 commit comments

Comments
 (0)