mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Type annotations for instruction operands are omitted, e.g. ``` %3 = struct $S(%1, %2) ``` Operand types are redundant anyway and were only used for sanity checking in the SIL parser. But: operand types _are_ printed if the definition of the operand value was not printed yet. This happens: * if the block with the definition appears after the block where the operand's instruction is located * if a block or instruction is printed in isolation, e.g. in a debugger The old behavior can be restored with `-Xllvm -sil-print-types`. This option is added to many existing test files which check for operand types in their check-lines.
282 lines
11 KiB
Plaintext
282 lines
11 KiB
Plaintext
// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -definite-init -raw-sil-inst-lowering -verify | %FileCheck %s
|
|
|
|
// This test only tests mark_uninitialized [derivedself]
|
|
|
|
sil_stage raw
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
/////////////////
|
|
// Definitions //
|
|
/////////////////
|
|
|
|
sil @takes_Int_inout : $@convention(thin) (@inout Int) -> ()
|
|
sil @makesInt : $@convention(thin) () -> Int
|
|
|
|
class RootClassWithIVars {
|
|
var x: Int
|
|
var y: Int
|
|
var z: (Int, Int)
|
|
init()
|
|
}
|
|
|
|
class DerivedClassWithIVars : RootClassWithIVars {
|
|
var a: Int
|
|
override init()
|
|
}
|
|
|
|
sil @superinit : $@convention(method) (@owned RootClassWithIVars) -> @owned RootClassWithIVars
|
|
|
|
protocol P {}
|
|
class C : P {}
|
|
|
|
class SomeClass {}
|
|
|
|
sil @getSomeClass : $@convention(thin) () -> @owned SomeClass
|
|
sil @getSomeOptionalClass : $@convention(thin) () -> Optional<SomeClass>
|
|
|
|
///////////
|
|
// Tests //
|
|
///////////
|
|
|
|
// This can be generated by using:
|
|
//
|
|
// func makesInt() -> Int { return 0 }
|
|
// func takesIntInout(i: inout Int) -> () {}
|
|
//
|
|
// class RootClassWithIVars {
|
|
// var x: Int
|
|
// var y: Int
|
|
// var z: (Int, Int)
|
|
// init() {
|
|
// }
|
|
// }
|
|
//
|
|
// class DerivedClassWithIVars : RootClassWithIVars {
|
|
// var a: Int
|
|
// override init() {
|
|
// a = makesInt()
|
|
// }
|
|
// }
|
|
//
|
|
sil [ossa] @derived_test1 : $@convention(method) (@owned DerivedClassWithIVars) -> @owned DerivedClassWithIVars {
|
|
bb0(%0 : @owned $DerivedClassWithIVars):
|
|
%1 = alloc_box $<τ_0_0> { var τ_0_0 } <DerivedClassWithIVars>
|
|
%1a = mark_uninitialized [derivedself] %1 : $<τ_0_0> { var τ_0_0 } <DerivedClassWithIVars>
|
|
%3 = project_box %1a : $<τ_0_0> { var τ_0_0 } <DerivedClassWithIVars>, 0
|
|
store %0 to [init] %3 : $*DerivedClassWithIVars
|
|
|
|
// Get an int
|
|
%5 = function_ref @makesInt : $@convention(thin) () -> Int
|
|
%7 = apply %5() : $@convention(thin) () -> Int
|
|
|
|
// Initialize the 'a' ivar with the int.
|
|
%8 = load_borrow %3 : $*DerivedClassWithIVars
|
|
%9 = ref_element_addr %8 : $DerivedClassWithIVars, #DerivedClassWithIVars.a
|
|
assign %7 to %9 : $*Int
|
|
end_borrow %8 : $DerivedClassWithIVars
|
|
|
|
// Then perform the self.init call.
|
|
%11 = load [take] %3 : $*DerivedClassWithIVars
|
|
%13 = upcast %11 : $DerivedClassWithIVars to $RootClassWithIVars
|
|
%14 = function_ref @superinit : $@convention(method) (@owned RootClassWithIVars) -> @owned RootClassWithIVars
|
|
%15 = apply %14(%13) : $@convention(method) (@owned RootClassWithIVars) -> @owned RootClassWithIVars
|
|
%16 = unchecked_ref_cast %15 : $RootClassWithIVars to $DerivedClassWithIVars
|
|
store %16 to [init] %3 : $*DerivedClassWithIVars
|
|
|
|
// Finally perform the epilog.
|
|
%18 = load [copy] %3 : $*DerivedClassWithIVars
|
|
destroy_value %1a : $<τ_0_0> { var τ_0_0 } <DerivedClassWithIVars>
|
|
return %18 : $DerivedClassWithIVars
|
|
}
|
|
|
|
// This is testing the following swift:
|
|
//
|
|
// func makesInt() -> Int { return 0 }
|
|
// func takesIntInout(i: inout Int) -> () {}
|
|
//
|
|
// class RootClassWithIVars {
|
|
// var x: Int
|
|
// var y: Int
|
|
// var z: (Int, Int)
|
|
// init() {
|
|
// }
|
|
// }
|
|
//
|
|
// class DerivedClassWithIVars : RootClassWithIVars {
|
|
// var a: Int
|
|
// override init() {
|
|
// }
|
|
// }
|
|
sil [ossa] @derived_test2 : $@convention(method) (@owned DerivedClassWithIVars) -> @owned DerivedClassWithIVars {
|
|
bb0(%0 : @owned $DerivedClassWithIVars):
|
|
%1 = alloc_box $<τ_0_0> { var τ_0_0 } <DerivedClassWithIVars>
|
|
%1a = mark_uninitialized [derivedself] %1 : $<τ_0_0> { var τ_0_0 } <DerivedClassWithIVars>
|
|
%3 = project_box %1a : $<τ_0_0> { var τ_0_0 } <DerivedClassWithIVars>, 0
|
|
store %0 to [init] %3 : $*DerivedClassWithIVars
|
|
|
|
%11 = load [take] %3 : $*DerivedClassWithIVars
|
|
%13 = upcast %11 : $DerivedClassWithIVars to $RootClassWithIVars
|
|
%14 = function_ref @superinit : $@convention(method) (@owned RootClassWithIVars) -> @owned RootClassWithIVars
|
|
%15 = apply %14(%13) : $@convention(method) (@owned RootClassWithIVars) -> @owned RootClassWithIVars // expected-error {{property 'self.a' not initialized at super.init call}}
|
|
%16 = unchecked_ref_cast %15 : $RootClassWithIVars to $DerivedClassWithIVars
|
|
store %16 to [init] %3 : $*DerivedClassWithIVars
|
|
|
|
%18 = load [copy] %3 : $*DerivedClassWithIVars
|
|
destroy_value %1a : $<τ_0_0> { var τ_0_0 } <DerivedClassWithIVars>
|
|
return %18 : $DerivedClassWithIVars
|
|
}
|
|
|
|
struct MyStruct : P {}
|
|
|
|
struct MyStruct2 {
|
|
var x: P
|
|
init(delegate: ())
|
|
init()
|
|
}
|
|
|
|
class RootClassWithNontrivialStoredProperties {
|
|
var x, y: SomeClass
|
|
|
|
init()
|
|
}
|
|
|
|
class DerivedClassWithNontrivialStoredProperties : RootClassWithNontrivialStoredProperties {
|
|
var a, b: SomeClass
|
|
override init()
|
|
}
|
|
|
|
// I was unable to find a test case that could reproduce this since there isn't
|
|
// a way before DI today to eliminate the super.init call. I believe it may have
|
|
// come from when mandatory inlining ran very early. That being said, we should
|
|
// still dot he right thing.
|
|
//
|
|
// CHECK-LABEL: sil [ossa] @test_derived_release
|
|
// CHECK: bb0(%0 : @owned $DerivedClassWithNontrivialStoredProperties):
|
|
// CHECK-NEXT: [[SELFBOX:%[0-9]+]] = alloc_stack
|
|
// CHECK-NEXT: store
|
|
// CHECK-NEXT: [[SELF:%[0-9]+]] = load [take] [[SELFBOX]]
|
|
// CHECK-NEXT: [[METATYPE:%[0-9]+]] = metatype $@thick DerivedClassWithNontrivialStoredProperties.Type
|
|
// CHECK-NEXT: dealloc_partial_ref [[SELF]] : $DerivedClassWithNontrivialStoredProperties, [[METATYPE]] : $@thick DerivedClassWithNontrivialStoredProperties.Type
|
|
// CHECK-NEXT: dealloc_stack [[SELFBOX]]
|
|
sil [ossa] @test_derived_release : $@convention(method) (@owned DerivedClassWithNontrivialStoredProperties) -> () {
|
|
bb0(%0 : @owned $DerivedClassWithNontrivialStoredProperties):
|
|
%1 = alloc_stack $DerivedClassWithNontrivialStoredProperties
|
|
%4 = mark_uninitialized [derivedself] %1 : $*DerivedClassWithNontrivialStoredProperties
|
|
store %0 to [init] %4 : $*DerivedClassWithNontrivialStoredProperties
|
|
|
|
destroy_addr %4 : $*DerivedClassWithNontrivialStoredProperties
|
|
dealloc_stack %1 : $*DerivedClassWithNontrivialStoredProperties
|
|
|
|
%13 = tuple ()
|
|
return %13 : $()
|
|
}
|
|
|
|
// I was unable to find a test case that could reproduce this since there isn't
|
|
// a way before DI today to eliminate the super.init call. I believe it may have
|
|
// come from when mandatory inlining ran very early. That being said, we should
|
|
// still dot he right thing.
|
|
//
|
|
// CHECK-LABEL: sil [ossa] @test_derived_partial_release
|
|
// CHECK: bb0([[ARG:%.*]] : @owned $DerivedClassWithNontrivialStoredProperties):
|
|
//
|
|
// Initialize the self box.
|
|
// CHECK: [[SELFBOX:%[0-9]+]] = alloc_stack
|
|
// CHECK: store [[ARG]] to [init] [[SELFBOX]]
|
|
//
|
|
// Update field of self.
|
|
// CHECK: [[FIELD_VAL:%.*]] = alloc_ref $SomeClass
|
|
// CHECK: [[SELF:%[0-9]+]] = load_borrow [[SELFBOX]]
|
|
// CHECK: [[SELF_FIELD:%.*]] = ref_element_addr [[SELF]]
|
|
// CHECK: store [[FIELD_VAL]] to [init] [[SELF_FIELD]]
|
|
// CHECK: end_borrow [[SELF]]
|
|
//
|
|
// Now we destroy the stored value.
|
|
// CHECK: [[SELF:%[0-9]+]] = load_borrow [[SELFBOX]]
|
|
// CHECK: [[SELF_FIELD:%.*]] = ref_element_addr [[SELF]]
|
|
// CHECK: [[SELF_FIELD_ACCESS:%.*]] = begin_access [deinit] [static] [[SELF_FIELD]]
|
|
// CHECK: destroy_addr [[SELF_FIELD_ACCESS]]
|
|
// CHECK: end_access [[SELF_FIELD_ACCESS]]
|
|
// CHECK: end_borrow [[SELF]]
|
|
//
|
|
// And then perform dealloc_partial_ref.
|
|
// CHECK: [[SELF:%[0-9]+]] = load [take] [[SELFBOX]]
|
|
// CHECK: [[METATYPE:%[0-9]+]] = metatype $@thick DerivedClassWithNontrivialStoredProperties.Type
|
|
// CHECK: dealloc_partial_ref [[SELF]] : $DerivedClassWithNontrivialStoredProperties, [[METATYPE]] : $@thick DerivedClassWithNontrivialStoredProperties.Type
|
|
// CHECK: dealloc_stack [[SELFBOX]]
|
|
// CHECK: } // end sil function 'test_derived_partial_release'
|
|
sil [ossa] @test_derived_partial_release : $@convention(method) (@owned DerivedClassWithNontrivialStoredProperties) -> () {
|
|
bb0(%0 : @owned $DerivedClassWithNontrivialStoredProperties):
|
|
%1 = alloc_stack $DerivedClassWithNontrivialStoredProperties
|
|
%4 = mark_uninitialized [derivedself] %1 : $*DerivedClassWithNontrivialStoredProperties
|
|
store %0 to [init] %4 : $*DerivedClassWithNontrivialStoredProperties
|
|
|
|
%8 = alloc_ref $SomeClass
|
|
%9 = load_borrow %4 : $*DerivedClassWithNontrivialStoredProperties
|
|
%10 = ref_element_addr %9 : $DerivedClassWithNontrivialStoredProperties, #DerivedClassWithNontrivialStoredProperties.a
|
|
assign %8 to %10 : $*SomeClass
|
|
end_borrow %9 : $DerivedClassWithNontrivialStoredProperties
|
|
|
|
destroy_addr %4 : $*DerivedClassWithNontrivialStoredProperties
|
|
dealloc_stack %1 : $*DerivedClassWithNontrivialStoredProperties
|
|
|
|
%13 = tuple ()
|
|
return %13 : $()
|
|
}
|
|
|
|
// <rdar://problem/18199087> DI doesn't catch use of super properties lexically inside super.init call
|
|
//
|
|
// *NOTE* There is currently a SILGen ownership bug where SILGen will emit the
|
|
// end_borrow too early. This does not need to be fixed in the short term since
|
|
// we are only going to verify swift stdlibCore. But it will need to be fixed.
|
|
//
|
|
// To recreate this:
|
|
//
|
|
// class Foo {
|
|
// var x: Int
|
|
// init() {}
|
|
// init(i: Int) {}
|
|
// }
|
|
//
|
|
// class Foo2 : Foo {
|
|
// override init() {
|
|
// super.init(i: self.x) // <--- The important part.
|
|
// }
|
|
// }
|
|
//
|
|
sil [ossa] @super_init_out_of_order : $@convention(method) (@owned DerivedClassWithIVars, Int) -> @owned DerivedClassWithIVars {
|
|
bb0(%0 : @owned $DerivedClassWithIVars, %i : $Int):
|
|
%1 = alloc_box $<τ_0_0> { var τ_0_0 } <DerivedClassWithIVars>
|
|
%1a = mark_uninitialized [derivedself] %1 : $<τ_0_0> { var τ_0_0 } <DerivedClassWithIVars>
|
|
%3 = project_box %1a : $<τ_0_0> { var τ_0_0 } <DerivedClassWithIVars>, 0
|
|
store %0 to [init] %3 : $*DerivedClassWithIVars
|
|
|
|
// Initialize properties in derived class.
|
|
%8 = load_borrow %3 : $*DerivedClassWithIVars
|
|
%9 = ref_element_addr %8 : $DerivedClassWithIVars, #DerivedClassWithIVars.a
|
|
assign %i to %9 : $*Int
|
|
end_borrow %8 : $DerivedClassWithIVars
|
|
|
|
// Get the super.init function information, but don't apply it.
|
|
%11 = load [take] %3 : $*DerivedClassWithIVars
|
|
%13 = upcast %11 : $DerivedClassWithIVars to $RootClassWithIVars
|
|
%14 = function_ref @superinit : $@convention(method) (@owned RootClassWithIVars) -> @owned RootClassWithIVars
|
|
|
|
// Access a super property before super.init is called.
|
|
%13a = begin_borrow %13 : $RootClassWithIVars
|
|
%13b = unchecked_ref_cast %13a : $RootClassWithIVars to $DerivedClassWithIVars
|
|
%13c = upcast %13b : $DerivedClassWithIVars to $RootClassWithIVars
|
|
%13d = ref_element_addr %13c : $RootClassWithIVars, #RootClassWithIVars.x // expected-error {{'self' used in property access 'x' before 'super.init' call}}
|
|
load [trivial] %13d : $*Int
|
|
end_borrow %13a : $RootClassWithIVars
|
|
|
|
// Call super.init.
|
|
%15 = apply %14(%13) : $@convention(method) (@owned RootClassWithIVars) -> @owned RootClassWithIVars
|
|
%16 = unchecked_ref_cast %15 : $RootClassWithIVars to $DerivedClassWithIVars
|
|
store %16 to [init] %3 : $*DerivedClassWithIVars
|
|
%18 = load [copy] %3 : $*DerivedClassWithIVars
|
|
destroy_value %1a : $<τ_0_0> { var τ_0_0 } <DerivedClassWithIVars>
|
|
return %18 : $DerivedClassWithIVars
|
|
}
|