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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
// RUN: %target-swift-emit-silgen %s -o /dev/null -verify
// RUN: %target-swift-emit-silgen -enforce-exclusivity=checked %s -o /dev/null -verify
func takeInOut<T>(_: inout T) {}
struct MutatorStruct {
mutating func f(_ x : inout MutatorStruct) {}
}
var global_property : MutatorStruct { get {} set {} }
var global_int_property : Int {
get { return 42 }
set {}
}
struct StructWithProperty {
var computed_int : Int {
get { return 42 }
set {}
}
var stored_int = 0
var computed_struct : MutatorStruct { get {} set {} }
}
var global_struct_property : StructWithProperty
var c_global_struct_property : StructWithProperty { get {} set {} }
func testInOutAlias() {
var x = 42
swap(&x, // expected-note {{previous aliasing argument}}
&x) // expected-error {{inout arguments are not allowed to alias each other}}
swap(&global_struct_property, // expected-note {{previous aliasing argument}}
&global_struct_property) // expected-error {{inout arguments are not allowed to alias each other}}
}
func testWriteback() {
var a = StructWithProperty()
a.computed_struct . // expected-note {{concurrent writeback occurred here}}
f(&a.computed_struct) // expected-error {{inout writeback to computed property 'computed_struct' occurs in multiple arguments to call, introducing invalid aliasing}}
swap(&global_struct_property.stored_int,
&global_struct_property.stored_int) // ok
swap(&global_struct_property.computed_int, // expected-note {{concurrent writeback occurred here}}
&global_struct_property.computed_int) // expected-error {{inout writeback to computed property 'computed_int' occurs in multiple arguments to call, introducing invalid aliasing}}
swap(&a.computed_int, // expected-note {{concurrent writeback occurred here}}
&a.computed_int) // expected-error {{inout writeback to computed property 'computed_int' occurs in multiple arguments to call, introducing invalid aliasing}}
global_property.f(&global_property) // expected-error {{inout writeback to computed property 'global_property' occurs in multiple arguments to call, introducing invalid aliasing}} expected-note {{concurrent writeback occurred here}}
a.computed_struct.f(&a.computed_struct) // expected-error {{inout writeback to computed property 'computed_struct' occurs in multiple arguments to call, introducing invalid aliasing}} expected-note {{concurrent writeback occurred here}}
}
func testComputedStructWithProperty() {
swap(&c_global_struct_property.stored_int, &c_global_struct_property.stored_int) // expected-error {{inout writeback to computed property 'c_global_struct_property' occurs in multiple arguments to call, introducing invalid aliasing}} expected-note {{concurrent writeback occurred here}}
var c_local_struct_property : StructWithProperty { get {} set {} }
swap(&c_local_struct_property.stored_int, &c_local_struct_property.stored_int) // expected-error {{inout writeback to computed property 'c_local_struct_property' occurs in multiple arguments to call, introducing invalid aliasing}} expected-note {{concurrent writeback occurred here}}
swap(&c_local_struct_property.stored_int, &c_global_struct_property.stored_int) // ok
}
var global_array : [[Int]]
func testMultiArray(_ i : Int, j : Int, array : [[Int]]) {
var array = array
swap(&array[i][j], // expected-note {{concurrent writeback occurred here}}
&array[i][i]) // expected-error {{inout writeback through subscript occurs in multiple arguments to call, introducing invalid aliasing}}
swap(&array[0][j], // expected-note {{concurrent writeback occurred here}}
&array[0][i]) // expected-error {{inout writeback through subscript occurs in multiple arguments to call, introducing invalid aliasing}}
swap(&global_array[0][j], // expected-note {{concurrent writeback occurred here}}
&global_array[0][i]) // expected-error {{inout writeback through subscript occurs in multiple arguments to call, introducing invalid aliasing}}
// TODO: This is obviously the same writeback problem, but isn't detectable
// with the current level of sophistication in SILGen.
swap(&array[1+0][j], &array[1+0][i])
swap(&global_array[0][j], &array[j][i]) // ok
}
struct ArrayWithoutAddressors<T> {
subscript(i: Int) -> T {
get { return value }
set {}
}
var value: T
}
var global_array_without_addressors: ArrayWithoutAddressors<ArrayWithoutAddressors<Int>>
func testMultiArrayWithoutAddressors(
_ i: Int, j: Int, array: ArrayWithoutAddressors<ArrayWithoutAddressors<Int>>
) {
var array = array
swap(&array[i][j], // expected-note {{concurrent writeback occurred here}}
&array[i][i]) // expected-error {{inout writeback through subscript occurs in multiple arguments to call, introducing invalid aliasing}}
swap(&array[0][j], // expected-note {{concurrent writeback occurred here}}
&array[0][i]) // expected-error {{inout writeback through subscript occurs in multiple arguments to call, introducing invalid aliasing}}
swap(&global_array_without_addressors[0][j], // expected-note {{concurrent writeback occurred here}}
&global_array_without_addressors[0][i]) // expected-error {{inout writeback through subscript occurs in multiple arguments to call, introducing invalid aliasing}}
// TODO: This is obviously the same writeback problem, but isn't detectable
// with the current level of sophistication in SILGen.
swap(&array[1+0][j], &array[1+0][i])
swap(&global_array_without_addressors[0][j], &array[j][i]) // ok
}
// rdar://43802132
struct ArrayWithReadModify<T> {
init(value: T) { self.property = value }
var property: T
subscript(i: Int) -> T {
_read { yield property }
_modify { yield &property }
}
}
func testArrayWithReadModify<T>(array: ArrayWithReadModify<T>) {
var copy = array
swap(©[0], ©[1])
swap(©[0], // expected-note {{concurrent writeback occurred here}}
©[0]) // expected-error {{inout writeback through subscript occurs in multiple arguments to call}}
}
// rdar://44147745
func testNestedArrayWithReadModify<T>(array: ArrayWithReadModify<ArrayWithReadModify<T>>) {
var copy = array
takeInOut(©[0][0])
}
|