1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
// RUN: %target-swift-frontend -O -Xllvm -sil-inline-generics=false -Xllvm -sil-disable-pass=ObjectOutliner %s -emit-sil -sil-verify-all | %FileCheck %s
// Make sure that we completely inline/devirtualize/substitute all the way down
// to unknown1.
// CHECK-LABEL: sil {{.*}}@main
// CHECK: bb0({{.*}}):
// CHECK: function_ref @unknown1
// CHECK: apply
// CHECK: apply
// CHECK: return
struct Int32 {}
@_silgen_name("unknown1")
func unknown1() -> ()
protocol P {
func doSomething(_ x : Int32)
}
struct X {}
class B<T> : P {
func doSomething(_ x : Int32) {
unknown1()
}
}
func doSomething(_ p : P, _ x : Int32) {
p.doSomething(x)
}
func doSomething2<T : P>(_ t : T, _ x : Int32) {
t.doSomething(x)
}
func driver() {
var b2 = B<X>()
var x = Int32()
doSomething(b2, x)
doSomething2(b2, x)
}
driver()
// <rdar://problem/46322928> Failure to devirtualize a protocol method
// applied to an opened existential blocks implementation of
// DataProtocol.
public protocol ContiguousBytes {
func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R
}
extension Array : ContiguousBytes {}
extension ContiguousArray : ContiguousBytes {}
@inline(never)
func takesPointer(_ p: UnsafeRawBufferPointer) {}
// In specialized testWithUnsafeBytes<A>(_:), the conditional case and call to withUnsafeBytes must be eliminated.
// Normally, we expect Array.withUnsafeBytes to be inlined so we would see:
// [[TAKES_PTR:%.*]] = function_ref @$s30devirt_specialized_conformance12takesPointeryySWF : $@convention(thin) (UnsafeRawBufferPointer) -> ()
// apply [[TAKES_PTR]](%{{.*}}) : $@convention(thin) (UnsafeRawBufferPointer) -> ()
// But the inlining isn't consistent across builds with and without debug info.
//
// CHECK-LABEL: sil shared [noinline] @$s30devirt_specialized_conformance19testWithUnsafeBytesyyxlFSayypG_Tg5 : $@convention(thin) (@guaranteed Array<Any>) -> () {
// CHECK: bb0
// CHECK-NOT: witness_method
// CHECK-LABEL: } // end sil function '$s30devirt_specialized_conformance19testWithUnsafeBytesyyxlFSayypG_Tg5'
@inline(never)
func testWithUnsafeBytes<T>(_ t: T) {
if let cb = t as? ContiguousBytes {
cb.withUnsafeBytes { takesPointer($0) }
}
}
testWithUnsafeBytes([])
|