// RUN: %empty-directory(%t) // RUN: %target-swift-frontend -I %t -emit-module -emit-module-path=%t/resilient_struct.swiftmodule %S/../Inputs/resilient_struct.swift // RUN: %target-swift-frontend -I %t -emit-module -emit-module-path=%t/resilient_class.swiftmodule %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-emit-silgen -Xllvm -sil-print-types -module-name super -parse-as-library -I %t %s | %FileCheck %s import resilient_class import fixed_layout_class public class Parent { public final var finalProperty: String { return "Parent.finalProperty" } public var property: String { return "Parent.property" } public final class var finalClassProperty: String { return "Parent.finalProperty" } public class var classProperty: String { return "Parent.property" } public func methodOnlyInParent() {} public final func finalMethodOnlyInParent() {} public func method() {} public final class func finalClassMethodOnlyInParent() {} public class func classMethod() {} } public class Child : Parent { // CHECK-LABEL: sil [ossa] @$s5super5ChildC8propertySSvg : $@convention(method) (@guaranteed Child) -> @owned String { // CHECK: bb0([[SELF:%.*]] : @guaranteed $Child): // CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] // CHECK: [[CAST_SELF_COPY:%[0-9]+]] = upcast [[SELF_COPY]] : $Child to $Parent // CHECK: [[CAST_SELF_BORROW:%[0-9]+]] = begin_borrow [[CAST_SELF_COPY]] // CHECK: [[SUPER_METHOD:%[0-9]+]] = function_ref @$s5super6ParentC8propertySSvg : $@convention(method) (@guaranteed Parent) -> @owned String // CHECK: [[RESULT:%.*]] = apply [[SUPER_METHOD]]([[CAST_SELF_BORROW]]) // CHECK: end_borrow [[CAST_SELF_BORROW]] // CHECK: destroy_value [[CAST_SELF_COPY]] // CHECK: return [[RESULT]] public override var property: String { return super.property } // CHECK-LABEL: sil [ossa] @$s5super5ChildC13otherPropertySSvg : $@convention(method) (@guaranteed Child) -> @owned String { // CHECK: bb0([[SELF:%.*]] : @guaranteed $Child): // CHECK: [[COPIED_SELF:%.*]] = copy_value [[SELF]] // CHECK: [[CAST_SELF_COPY:%[0-9]+]] = upcast [[COPIED_SELF]] : $Child to $Parent // CHECK: [[CAST_SELF_BORROW:%[0-9]+]] = begin_borrow [[CAST_SELF_COPY]] // CHECK: [[SUPER_METHOD:%[0-9]+]] = function_ref @$s5super6ParentC13finalPropertySSvg // CHECK: [[RESULT:%.*]] = apply [[SUPER_METHOD]]([[CAST_SELF_BORROW]]) // CHECK: end_borrow [[CAST_SELF_BORROW]] // CHECK: destroy_value [[CAST_SELF_COPY]] // CHECK: return [[RESULT]] public var otherProperty: String { return super.finalProperty } } public class Grandchild : Child { // CHECK-LABEL: sil [ossa] @$s5super10GrandchildC06onlyInB0yyF public func onlyInGrandchild() { // CHECK: function_ref @$s5super6ParentC012methodOnlyInB0yyF : $@convention(method) (@guaranteed Parent) -> () super.methodOnlyInParent() // CHECK: function_ref @$s5super6ParentC017finalMethodOnlyInB0yyF super.finalMethodOnlyInParent() } // CHECK-LABEL: sil [ossa] @$s5super10GrandchildC6methodyyF public override func method() { // CHECK: function_ref @$s5super6ParentC6methodyyF : $@convention(method) (@guaranteed Parent) -> () super.method() } } public class GreatGrandchild : Grandchild { // CHECK-LABEL: sil [ossa] @$s5super15GreatGrandchildC6methodyyF public override func method() { // CHECK: function_ref @$s5super10GrandchildC6methodyyF : $@convention(method) (@guaranteed Grandchild) -> () super.method() } } public class ChildToResilientParent : ResilientOutsideParent { // CHECK-LABEL: sil [ossa] @$s5super22ChildToResilientParentC6methodyyF : $@convention(method) (@guaranteed ChildToResilientParent) -> () public override func method() { // CHECK: bb0([[SELF:%.*]] : @guaranteed $ChildToResilientParent): // CHECK: [[COPY_SELF:%.*]] = copy_value [[SELF]] // CHECK: [[UPCAST_SELF:%.*]] = upcast [[COPY_SELF]] // CHECK: [[BORROW_UPCAST_SELF:%.*]] = begin_borrow [[UPCAST_SELF]] // CHECK: [[CAST_BORROW_BACK_TO_BASE:%.*]] = unchecked_ref_cast [[BORROW_UPCAST_SELF]] // CHECK: [[FUNC:%.*]] = super_method [[CAST_BORROW_BACK_TO_BASE]] : $ChildToResilientParent, #ResilientOutsideParent.method : (ResilientOutsideParent) -> () -> (), $@convention(method) (@guaranteed ResilientOutsideParent) -> () // CHECK: end_borrow [[BORROW_UPCAST_SELF]] // CHECK: apply [[FUNC]]([[UPCAST_SELF]]) super.method() } // CHECK: } // end sil function '$s5super22ChildToResilientParentC6methodyyF' // CHECK-LABEL: sil [ossa] @$s5super22ChildToResilientParentC11classMethodyyFZ : $@convention(method) (@thick ChildToResilientParent.Type) -> () public override class func classMethod() { // CHECK: bb0([[METASELF:%.*]] : $@thick ChildToResilientParent.Type): // CHECK: [[UPCAST_METASELF:%.*]] = upcast [[METASELF]] // CHECK: [[FUNC:%.*]] = super_method [[SELF]] : $@thick ChildToResilientParent.Type, #ResilientOutsideParent.classMethod : (ResilientOutsideParent.Type) -> () -> (), $@convention(method) (@thick ResilientOutsideParent.Type) -> () // CHECK: apply [[FUNC]]([[UPCAST_METASELF]]) super.classMethod() } // CHECK: } // end sil function '$s5super22ChildToResilientParentC11classMethodyyFZ' // CHECK-LABEL: sil [ossa] @$s5super22ChildToResilientParentC11returnsSelfACXDyFZ : $@convention(method) (@thick ChildToResilientParent.Type) -> @owned ChildToResilientParent public class func returnsSelf() -> Self { // CHECK: bb0([[METASELF:%.*]] : $@thick ChildToResilientParent.Type): // CHECK: [[CAST_METASELF:%.*]] = unchecked_trivial_bit_cast [[METASELF]] : $@thick ChildToResilientParent.Type to $@thick @dynamic_self ChildToResilientParent.Type // CHECK: [[UPCAST_CAST_METASELF:%.*]] = upcast [[CAST_METASELF]] : $@thick @dynamic_self ChildToResilientParent.Type to $@thick ResilientOutsideParent.Type // CHECK: [[FUNC:%.*]] = super_method [[METASELF]] : $@thick ChildToResilientParent.Type, #ResilientOutsideParent.classMethod : (ResilientOutsideParent.Type) -> () -> () // CHECK: apply [[FUNC]]([[UPCAST_CAST_METASELF]]) // CHECK: unreachable _ = 0 super.classMethod() } // CHECK: } // end sil function '$s5super22ChildToResilientParentC11returnsSelfACXDyFZ' } public class ChildToFixedParent : OutsideParent { // CHECK-LABEL: sil [ossa] @$s5super18ChildToFixedParentC6methodyyF : $@convention(method) (@guaranteed ChildToFixedParent) -> () public override func method() { // CHECK: bb0([[SELF:%.*]] : @guaranteed $ChildToFixedParent): // CHECK: [[COPY_SELF:%.*]] = copy_value [[SELF]] // CHECK: [[UPCAST_COPY_SELF:%.*]] = upcast [[COPY_SELF]] // CHECK: [[BORROWED_UPCAST_COPY_SELF:%.*]] = begin_borrow [[UPCAST_COPY_SELF]] // CHECK: [[DOWNCAST_BORROWED_UPCAST_COPY_SELF:%.*]] = unchecked_ref_cast [[BORROWED_UPCAST_COPY_SELF]] : $OutsideParent to $ChildToFixedParent // CHECK: [[FUNC:%.*]] = super_method [[DOWNCAST_BORROWED_UPCAST_COPY_SELF]] : $ChildToFixedParent, #OutsideParent.method : (OutsideParent) -> () -> (), $@convention(method) (@guaranteed OutsideParent) -> () // CHECK: end_borrow [[BORROWED_UPCAST_COPY_SELF]] // CHECK: apply [[FUNC]]([[UPCAST_COPY_SELF]]) super.method() } // CHECK: } // end sil function '$s5super18ChildToFixedParentC6methodyyF' // CHECK-LABEL: sil [ossa] @$s5super18ChildToFixedParentC11classMethodyyFZ : $@convention(method) (@thick ChildToFixedParent.Type) -> () public override class func classMethod() { // CHECK: bb0([[SELF:%.*]] : $@thick ChildToFixedParent.Type): // CHECK: [[UPCAST_SELF:%.*]] = upcast [[SELF]] // CHECK: [[FUNC:%.*]] = super_method [[SELF]] : $@thick ChildToFixedParent.Type, #OutsideParent.classMethod : (OutsideParent.Type) -> () -> (), $@convention(method) (@thick OutsideParent.Type) -> () // CHECK: apply [[FUNC]]([[UPCAST_SELF]]) super.classMethod() } // CHECK: } // end sil function '$s5super18ChildToFixedParentC11classMethodyyFZ' // CHECK-LABEL: sil [ossa] @$s5super18ChildToFixedParentC11returnsSelfACXDyFZ : $@convention(method) (@thick ChildToFixedParent.Type) -> @owned ChildToFixedParent public class func returnsSelf() -> Self { // CHECK: bb0([[SELF:%.*]] : $@thick ChildToFixedParent.Type): // CHECK: [[FIRST_CAST:%.*]] = unchecked_trivial_bit_cast [[SELF]] // CHECK: [[SECOND_CAST:%.*]] = upcast [[FIRST_CAST]] // CHECK: [[FUNC:%.*]] = super_method [[SELF]] : $@thick ChildToFixedParent.Type, #OutsideParent.classMethod : (OutsideParent.Type) -> () -> () // CHECK: apply [[FUNC]]([[SECOND_CAST]]) // CHECK: unreachable _ = 0 super.classMethod() } // CHECK: } // end sil function '$s5super18ChildToFixedParentC11returnsSelfACXDyFZ' } // https://github.com/apple/swift/issues/52660 // 'super.foo()' call across a module boundary from a subclass that does // not override 'foo()'. public class SuperCallToNonOverriddenMethod : OutsideParent { public func newMethod() { super.method() } } public extension ResilientOutsideChild { public func callSuperMethod() { super.method() } public class func callSuperClassMethod() { super.classMethod() } } public class GenericBase { public func method() {} } public class GenericDerived : GenericBase { public override func method() { // CHECK-LABEL: sil private [ossa] @$s5super14GenericDerivedC6methodyyFyyXEfU_ : $@convention(thin) (@guaranteed GenericDerived) -> () // CHECK: upcast {{.*}} : $GenericDerived to $GenericBase // CHECK: return { super.method() }() // CHECK: } // end sil function '$s5super14GenericDerivedC6methodyyFyyXEfU_' // CHECK-LABEL: sil private [ossa] @$s5super14GenericDerivedC6methodyyF13localFunctionL_yylF : $@convention(thin) (@guaranteed GenericDerived) -> () // CHECK: upcast {{.*}} : $GenericDerived to $GenericBase // CHECK: return // CHECK: } // end sil function '$s5super14GenericDerivedC6methodyyF13localFunctionL_yylF' func localFunction() { super.method() } localFunction() // CHECK-LABEL: sil private [ossa] @$s5super14GenericDerivedC6methodyyF15genericFunctionL_yyqd__r__lF : $@convention(thin) (@in_guaranteed U, @guaranteed GenericDerived) -> () // CHECK: upcast {{.*}} : $GenericDerived to $GenericBase // CHECK: return func genericFunction(_: U) { super.method() } // CHECK: } // end sil function '$s5super14GenericDerivedC6methodyyF15genericFunctionL_yyqd__r__lF' genericFunction(0) } }