mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
220 lines
12 KiB
Plaintext
220 lines
12 KiB
Plaintext
// RUN: %empty-directory(%t)
|
|
// RUN: %target-swift-frontend -emit-module -enable-library-evolution -I %t -o %t %S/../Inputs/resilient_struct.swift
|
|
// RUN: %target-swift-frontend -emit-module -enable-library-evolution -I %t -o %t %S/../Inputs/resilient_class.swift
|
|
|
|
// Note: we build fixed_layout_class without -enable-library-evolution, since with
|
|
// -enable-library-evolution even @_fixed_layout classes have resilient metadata, and
|
|
// we want to test the fragile access pattern here.
|
|
|
|
// RUN: %target-swift-frontend -emit-module -I %t -o %t %S/../Inputs/fixed_layout_class.swift
|
|
|
|
// RUN: %target-swift-frontend -Xllvm -sil-disable-pass=simplification -enable-library-evolution -parse-sil -parse-as-library -emit-ir -I %t %s | %FileCheck %s
|
|
|
|
// CHECK: %swift.type = type { [[INT:i32|i64]] }
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
import SwiftShims
|
|
import resilient_class
|
|
import fixed_layout_class
|
|
|
|
public class ChildToResilientParent : ResilientOutsideParent {
|
|
public override func method()
|
|
public override class func classMethod()
|
|
deinit
|
|
override init()
|
|
}
|
|
|
|
public class ChildToFixedParent : OutsideParent {
|
|
public override func method()
|
|
public override class func classMethod()
|
|
deinit
|
|
override init()
|
|
}
|
|
|
|
public extension ResilientOutsideChild {
|
|
public func callSuperMethod()
|
|
public class func callSuperClassMethod()
|
|
}
|
|
|
|
// resilient_class.ResilientOutsideParent.method () -> ()
|
|
sil @$s15resilient_class22ResilientOutsideParentC6methodyyF : $@convention(method) (@guaranteed ResilientOutsideParent) -> ()
|
|
|
|
// static resilient_class.ResilientOutsideParent.classMethod () -> ()
|
|
sil @$s15resilient_class22ResilientOutsideParentC0B6MethodyyFZ : $@convention(method) (@thick ResilientOutsideParent.Type) -> ()
|
|
|
|
// super.ChildToResilientParent.method () -> ()
|
|
sil @$s5super22ChildToResilientParentC6methodyyF : $@convention(method) (@guaranteed ChildToResilientParent) -> () {
|
|
// %0
|
|
bb0(%0 : $ChildToResilientParent):
|
|
debug_value %0 : $ChildToResilientParent, let, name "self", argno 1
|
|
strong_retain %0 : $ChildToResilientParent
|
|
%3 = upcast %0 : $ChildToResilientParent to $ResilientOutsideParent
|
|
%4 = super_method %0 : $ChildToResilientParent, #ResilientOutsideParent.method : (ResilientOutsideParent) -> () -> (), $@convention(method) (@guaranteed ResilientOutsideParent) -> ()
|
|
%5 = apply %4(%3) : $@convention(method) (@guaranteed ResilientOutsideParent) -> ()
|
|
strong_release %3 : $ResilientOutsideParent
|
|
%7 = tuple ()
|
|
return %7 : $()
|
|
}
|
|
|
|
// ChildToResilientParent is in our resilience domain - can load the superclass's metadata directly.
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s5super22ChildToResilientParentC6methodyyF"(ptr swiftself %0)
|
|
// CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s15resilient_class22ResilientOutsideParentCMa"([[INT]] 0)
|
|
// CHECK: [[SUPER_METADATA:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0
|
|
// CHECK: [[FN:%.*]] = call swiftcc ptr @"$s15resilient_class22ResilientOutsideParentCMu"(ptr [[SUPER_METADATA]], ptr @"$s15resilient_class22ResilientOutsideParentC6methodyyFTq")
|
|
// CHECK: call void
|
|
|
|
// static super.ChildToResilientParent.classMethod () -> ()
|
|
sil @$s5super22ChildToResilientParentC11classMethodyyFZ : $@convention(method) (@thick ChildToResilientParent.Type) -> () {
|
|
bb0(%0 : $@thick ChildToResilientParent.Type):
|
|
debug_value %0 : $@thick ChildToResilientParent.Type, let, name "self", argno 1
|
|
%2 = upcast %0 : $@thick ChildToResilientParent.Type to $@thick ResilientOutsideParent.Type
|
|
%3 = super_method %0 : $@thick ChildToResilientParent.Type, #ResilientOutsideParent.classMethod : (ResilientOutsideParent.Type) -> () -> (), $@convention(method) (@thick ResilientOutsideParent.Type) -> ()
|
|
%4 = apply %3(%2) : $@convention(method) (@thick ResilientOutsideParent.Type) -> ()
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// ChildToResilientParent is in our resilience domain - can load the superclass's metadata directly.
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s5super22ChildToResilientParentC11classMethodyyFZ"(ptr swiftself %0)
|
|
// CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s15resilient_class22ResilientOutsideParentCMa"([[INT]] 0)
|
|
// CHECK: [[SUPER_METADATA:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0
|
|
// CHECK: [[FN:%.*]] = call swiftcc ptr @"$s15resilient_class22ResilientOutsideParentCMu"(ptr [[SUPER_METADATA]], ptr @"$s15resilient_class22ResilientOutsideParentC0B6MethodyyFZTq")
|
|
// CHECK: call swiftcc void
|
|
|
|
// resilient_class.OutsideParent.method () -> ()
|
|
sil @$s15resilient_class13OutsideParentC6methodyyF : $@convention(method) (@guaranteed OutsideParent) -> ()
|
|
|
|
// static resilient_class.OutsideParent.classMethod () -> ()
|
|
sil @$s15resilient_class13OutsideParentC0B6MethodyyFZ : $@convention(thin) (@thick OutsideParent.Type) -> ()
|
|
|
|
// super.ChildToFixedParent.method () -> ()
|
|
sil @$s5super18ChildToFixedParentC6methodyyF : $@convention(method) (@guaranteed ChildToFixedParent) -> () {
|
|
// %0
|
|
bb0(%0 : $ChildToFixedParent):
|
|
debug_value %0 : $ChildToFixedParent, let, name "self", argno 1
|
|
strong_retain %0 : $ChildToFixedParent
|
|
%3 = upcast %0 : $ChildToFixedParent to $OutsideParent
|
|
%4 = super_method %0 : $ChildToFixedParent, #OutsideParent.method : (OutsideParent) -> () -> (), $@convention(method) (@guaranteed OutsideParent) -> ()
|
|
%5 = apply %4(%3) : $@convention(method) (@guaranteed OutsideParent) -> ()
|
|
strong_release %3 : $OutsideParent
|
|
%7 = tuple ()
|
|
return %7 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s5super18ChildToFixedParentC6methodyyF"(ptr swiftself %0)
|
|
// CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s18fixed_layout_class13OutsideParentCMa"([[INT]] 0)
|
|
// CHECK: [[SUPER_METADATA:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0
|
|
// CHECK: [[VTABLE_SLOT:%.*]] = getelementptr inbounds ptr, ptr [[SUPER_METADATA]]
|
|
// CHECK: [[FN_PTR:%.*]] = load ptr, ptr [[VTABLE_SLOT]]
|
|
// CHECK: call swiftcc void
|
|
|
|
// static super.ChildToFixedParent.classMethod () -> ()
|
|
sil @$s5super18ChildToFixedParentC11classMethodyyFZ : $@convention(method) (@thick ChildToFixedParent.Type) -> () {
|
|
// %0
|
|
bb0(%0 : $@thick ChildToFixedParent.Type):
|
|
debug_value %0 : $@thick ChildToFixedParent.Type, let, name "self", argno 1
|
|
%2 = upcast %0 : $@thick ChildToFixedParent.Type to $@thick OutsideParent.Type
|
|
%3 = super_method %0 : $@thick ChildToFixedParent.Type, #OutsideParent.classMethod : (OutsideParent.Type) -> () -> (), $@convention(method) (@thick OutsideParent.Type) -> ()
|
|
%4 = apply %3(%2) : $@convention(method) (@thick OutsideParent.Type) -> ()
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// ChildToFixedParent is in our resilience domain - load super metadata directly.
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s5super18ChildToFixedParentC11classMethodyyFZ"(ptr swiftself %0)
|
|
// CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s18fixed_layout_class13OutsideParentCMa"([[INT]] 0)
|
|
// CHECK: [[SUPER_METADATA:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0
|
|
// CHECK: [[VTABLE_SLOT:%.*]] = getelementptr inbounds ptr, ptr [[SUPER_METADATA]]
|
|
// CHECK: [[FN_PTR:%.*]] = load ptr, ptr [[VTABLE_SLOT]]
|
|
// CHECK: call swiftcc void
|
|
|
|
// ext.super.resilient_class.ResilientOutsideChild.callSuperMethod () -> ()
|
|
sil @$s15resilient_class21ResilientOutsideChildC5superE15callSuperMethodyyF : $@convention(method) (@guaranteed ResilientOutsideChild) -> () {
|
|
// %0
|
|
bb0(%0 : $ResilientOutsideChild):
|
|
debug_value %0 : $ResilientOutsideChild, let, name "self", argno 1
|
|
strong_retain %0 : $ResilientOutsideChild
|
|
%3 = upcast %0 : $ResilientOutsideChild to $ResilientOutsideParent
|
|
%4 = super_method %0 : $ResilientOutsideChild, #ResilientOutsideParent.method : (ResilientOutsideParent) -> () -> (), $@convention(method) (@guaranteed ResilientOutsideParent) -> ()
|
|
%5 = apply %4(%3) : $@convention(method) (@guaranteed ResilientOutsideParent) -> ()
|
|
strong_release %3 : $ResilientOutsideParent
|
|
%7 = tuple ()
|
|
return %7 : $()
|
|
}
|
|
|
|
// Extending a resilient class - load super metadata indirectly.
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s15resilient_class21ResilientOutsideChildC5superE15callSuperMethodyyF"(ptr swiftself %0)
|
|
// CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s15resilient_class21ResilientOutsideChildCMa"([[INT]] 0)
|
|
// CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0
|
|
// CHECK: [[SUPER_METADATA_PTR:%.*]] = getelementptr inbounds ptr, ptr [[METADATA]], i32 1
|
|
// CHECK: [[SUPER_METADATA:%.*]] = load ptr, ptr [[SUPER_METADATA_PTR]]
|
|
// CHECK: [[FN:%.*]] = call swiftcc ptr @"$s15resilient_class22ResilientOutsideParentCMu"(ptr [[SUPER_METADATA]], ptr @"$s15resilient_class22ResilientOutsideParentC6methodyyFTq")
|
|
// CHECK: call void
|
|
|
|
// static ext.super.resilient_class.ResilientOutsideChild.callSuperClassMethod () -> ()
|
|
sil @$s15resilient_class21ResilientOutsideChildC5superE20callSuperClassMethodyyFZ : $@convention(method) (@thick ResilientOutsideChild.Type) -> () {
|
|
// %0
|
|
bb0(%0 : $@thick ResilientOutsideChild.Type):
|
|
debug_value %0 : $@thick ResilientOutsideChild.Type, let, name "self", argno 1
|
|
%2 = upcast %0 : $@thick ResilientOutsideChild.Type to $@thick ResilientOutsideParent.Type
|
|
%3 = super_method %0 : $@thick ResilientOutsideChild.Type, #ResilientOutsideParent.classMethod : (ResilientOutsideParent.Type) -> () -> (), $@convention(method) (@thick ResilientOutsideParent.Type) -> ()
|
|
%4 = apply %3(%2) : $@convention(method) (@thick ResilientOutsideParent.Type) -> ()
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// Extending a resilient class - load super metadata indirectly.
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s15resilient_class21ResilientOutsideChildC5superE20callSuperClassMethodyyFZ"(ptr swiftself %0)
|
|
// CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s15resilient_class21ResilientOutsideChildCMa"([[INT]] 0)
|
|
// CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0
|
|
// CHECK: [[SUPER_METADATA_PTR:%.*]] = getelementptr inbounds ptr, ptr [[METADATA]], i32 1
|
|
// CHECK: [[SUPER_METADATA:%.*]] = load ptr, ptr [[SUPER_METADATA_PTR]]
|
|
// CHECK: [[FN:%.*]] = call swiftcc ptr @"$s15resilient_class22ResilientOutsideParentCMu"(ptr [[SUPER_METADATA]], ptr @"$s15resilient_class22ResilientOutsideParentC0B6MethodyyFZTq")
|
|
// CHECK: call swiftcc void
|
|
|
|
sil_vtable ChildToResilientParent {
|
|
#ResilientOutsideParent.method: @$s5super22ChildToResilientParentC6methodyyF [override] // super.ChildToResilientParent.method () -> ()
|
|
#ResilientOutsideParent.classMethod: @$s5super22ChildToResilientParentC11classMethodyyFZ [override] // static super.ChildToResilientParent.classMethod () -> ()
|
|
}
|
|
|
|
sil_vtable ChildToFixedParent {
|
|
#OutsideParent.method: @$s5super18ChildToFixedParentC6methodyyF [override] // super.ChildToFixedParent.method () -> ()
|
|
#OutsideParent.classMethod: @$s5super18ChildToFixedParentC11classMethodyyFZ [override] // static super.ChildToFixedParent.classMethod () -> ()
|
|
}
|
|
|
|
protocol Proto {
|
|
}
|
|
|
|
public class Base<T: Proto> {
|
|
func Method() { }
|
|
}
|
|
|
|
struct Str : Proto {
|
|
}
|
|
|
|
public class Derived : Base<Str> {
|
|
override func Method()
|
|
}
|
|
|
|
sil_vtable Base {
|
|
}
|
|
|
|
sil_vtable Derived {
|
|
}
|
|
|
|
// CHECK-LABEL: define{{.*}} @test_super_method_of_generic_base
|
|
// CHECK: [[METADATA:%.*]] = call {{.*}}@"$s5super4BaseCyAA3StrVGMD"
|
|
// CHECK: [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[METADATA]]
|
|
// CHECK: [[SUPERMT:%.*]] = load ptr, ptr [[GEP]]
|
|
// CHECK: ret void
|
|
sil @test_super_method_of_generic_base : $@convention(method) (@guaranteed Derived) -> () {
|
|
bb0(%0 : $Derived):
|
|
%4 = super_method %0 : $Derived, #Base.Method : <T where T : Proto> (Base<T>) -> () -> () , $@convention(method) <τ_0_0 where τ_0_0 : Proto> (@guaranteed Base<τ_0_0>) -> ()
|
|
%7 = tuple ()
|
|
return %7 : $()
|
|
}
|
|
|