File: guaranteed_normal_args.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (217 lines) | stat: -rw-r--r-- 8,064 bytes parent folder | download
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

// RUN: %target-swift-emit-silgen -parse-as-library -module-name Swift -parse-stdlib %s | %FileCheck %s

// This test checks specific codegen related to normal arguments being passed at
// +0. Eventually, it should be merged into normal SILGen tests.

/////////////////
// Fake Stdlib //
/////////////////

precedencegroup AssignmentPrecedence {
  assignment: true
}

public protocol ExpressibleByNilLiteral {
  init(nilLiteral: ())
}

protocol IteratorProtocol {
  associatedtype Element
  mutating func next() ->  Element?
}

protocol Sequence {
  associatedtype Element
  associatedtype Iterator : IteratorProtocol where Iterator.Element == Element

  func makeIterator() -> Iterator
}

enum Optional<T> {
case none
case some(T)
}

extension Optional : ExpressibleByNilLiteral {
  public init(nilLiteral: ()) {
    self = .none
  }
}

func _diagnoseUnexpectedNilOptional(_filenameStart: Builtin.RawPointer,
                                    _filenameLength: Builtin.Word,
                                    _filenameIsASCII: Builtin.Int1,
                                    _line: Builtin.Word) {
  // This would usually contain an assert, but we don't need one since we are
  // just emitting SILGen.
}

class Klass {
  init() {}
}

struct Buffer {
  var k: Klass
  init(inK: Klass) {
    k = inK
  }
}

public typealias AnyObject = Builtin.AnyObject

protocol Protocol {
  associatedtype AssocType
  static func useInput(_ input: Builtin.Int32, into processInput: (AssocType) -> ())
}

struct FakeArray<Element> {
  // Just to make this type non-trivial
  var k: Klass

  // We are only interested in this being called. We are not interested in its
  // implementation.
  mutating func append(_ t: Element) {}
}

struct FakeDictionary<Key, Value> {
}

struct FakeDictionaryIterator<Key, Value> {
  var dictionary: FakeDictionary<Key, Value>?

  init(_ newDictionary: FakeDictionary<Key, Value>) {
    dictionary = newDictionary
  }
}

extension FakeDictionaryIterator : IteratorProtocol {
  public typealias Element = (Key, Value)
  public mutating func next() -> Element? {
    return .none
  }
}

extension FakeDictionary : Sequence {
  public typealias Element = (Key, Value)
  public typealias Iterator = FakeDictionaryIterator<Key, Value>
  public func makeIterator() -> FakeDictionaryIterator<Key, Value> {
    return FakeDictionaryIterator(self)
  }
}

public struct Unmanaged<Instance : AnyObject> {
  internal unowned(unsafe) var _value: Instance
}

///////////
// Tests //
///////////

class KlassWithBuffer {
  var buffer: Buffer

  // Make sure that the allocating init forwards into the initializing init at +1.
  // CHECK-LABEL: sil hidden [exact_self_class] [ossa] @$ss15KlassWithBufferC3inKABs0A0C_tcfC : $@convention(method) (@owned Klass, @thick KlassWithBuffer.Type) -> @owned KlassWithBuffer {
  // CHECK: bb0([[ARG:%.*]] : @owned $Klass,
  // CHECK:   [[INITIALIZING_INIT:%.*]] = function_ref @$ss15KlassWithBufferC3inKABs0A0C_tcfc : $@convention(method) (@owned Klass, @owned KlassWithBuffer) -> @owned KlassWithBuffer
  // CHECK:   apply [[INITIALIZING_INIT]]([[ARG]],
  // CHECK: } // end sil function '$ss15KlassWithBufferC3inKABs0A0C_tcfC'
  init(inK: Klass = Klass()) {
    buffer = Buffer(inK: inK)
  }

  // This test makes sure that we:
  //
  // 1. Are able to propagate a +0 value buffer.k into a +0 value and that
  // we then copy that +0 value into a +1 value, before we begin the epilog and
  // then return that value.
  // CHECK-LABEL: sil hidden [ossa] @$ss15KlassWithBufferC03getC14AsNativeObjectBoyF : $@convention(method) (@guaranteed KlassWithBuffer) -> @owned Builtin.NativeObject {
  // CHECK: bb0([[SELF:%.*]] : @guaranteed $KlassWithBuffer):
  // CHECK:   [[METHOD:%.*]] = class_method [[SELF]] : $KlassWithBuffer, #KlassWithBuffer.buffer!getter
  // CHECK:   [[BUF:%.*]] = apply [[METHOD]]([[SELF]])
  // CHECK:   [[BUF_BORROW:%.*]] = begin_borrow [[BUF]]
  // CHECK:   [[K:%.*]] = struct_extract [[BUF_BORROW]] : $Buffer, #Buffer.k
  // CHECK:   [[COPIED_K:%.*]] = copy_value [[K]]
  // CHECK:   end_borrow [[BUF_BORROW]]
  // CHECK:   [[CASTED_COPIED_K:%.*]] = unchecked_ref_cast [[COPIED_K]]
  // CHECK:   destroy_value [[BUF]]
  // CHECK:   return [[CASTED_COPIED_K]]
  // CHECK: } // end sil function '$ss15KlassWithBufferC03getC14AsNativeObjectBoyF'
  func getBufferAsNativeObject() -> Builtin.NativeObject {
    return Builtin.unsafeCastToNativeObject(buffer.k)
  }
}

struct StructContainingBridgeObject {
  var rawValue: Builtin.BridgeObject

  // CHECK-LABEL: sil hidden [ossa] @$ss28StructContainingBridgeObjectV8swiftObjAByXl_tcfC : $@convention(method) (@owned AnyObject, @thin StructContainingBridgeObject.Type) -> @owned StructContainingBridgeObject {
  // CHECK: bb0([[ARG:%.*]] : @owned $AnyObject,
  // CHECK:   [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
  // CHECK:   [[COPIED_ARG:%.*]] = copy_value [[BORROWED_ARG]]
  // CHECK:   [[CASTED_ARG:%.*]] = unchecked_ref_cast [[COPIED_ARG]] : $AnyObject to $Builtin.BridgeObject
  // CHECK:   assign [[CASTED_ARG]] to
  // CHECK: } // end sil function '$ss28StructContainingBridgeObjectV8swiftObjAByXl_tcfC'
  init(swiftObj: AnyObject) {
    rawValue = Builtin.reinterpretCast(swiftObj)
  }
}

struct ReabstractionThunkTest : Protocol {
  typealias AssocType = Builtin.Int32

  static func useInput(_ input: Builtin.Int32, into processInput: (AssocType) -> ()) {
    processInput(input)
  }
}

// Make sure that we provide a cleanup to x properly before we pass it to
// result.
extension FakeDictionary {
  // CHECK-LABEL: sil hidden [ossa] @$ss14FakeDictionaryV20makeSureToCopyTuplesyyF : $@convention(method) <Key, Value> (FakeDictionary<Key, Value>) -> () {
  // CHECK:   [[X:%.*]] = alloc_stack [lexical] [var_decl] $(Key, Value), let, name "x"
  // CHECK:   [[INDUCTION_VAR:%.*]] = unchecked_take_enum_data_addr {{%.*}} : $*Optional<(Key, Value)>, #Optional.some!enumelt
  // CHECK:   [[INDUCTION_VAR_0:%.*]] = tuple_element_addr [[INDUCTION_VAR]] : $*(Key, Value), 0
  // CHECK:   [[INDUCTION_VAR_1:%.*]] = tuple_element_addr [[INDUCTION_VAR]] : $*(Key, Value), 1
  // CHECK:   [[X_0:%.*]] = tuple_element_addr [[X]] : $*(Key, Value), 0
  // CHECK:   [[X_1:%.*]] = tuple_element_addr [[X]] : $*(Key, Value), 1
  // CHECK:   copy_addr [take] [[INDUCTION_VAR_0]] to [init] [[X_0]]
  // CHECK:   copy_addr [take] [[INDUCTION_VAR_1]] to [init] [[X_1]]
  // CHECK:   [[X_0:%.*]] = tuple_element_addr [[X]] : $*(Key, Value), 0
  // CHECK:   [[X_1:%.*]] = tuple_element_addr [[X]] : $*(Key, Value), 1
  // CHECK:   [[TMP_X:%.*]] = alloc_stack $(Key, Value)
  // CHECK:   [[TMP_X_0:%.*]] = tuple_element_addr [[TMP_X]] : $*(Key, Value), 0
  // CHECK:   [[TMP_X_1:%.*]] = tuple_element_addr [[TMP_X]] : $*(Key, Value), 1
  // CHECK:   [[TMP_0:%.*]] = alloc_stack $Key
  // CHECK:   copy_addr [[X_0]] to [init] [[TMP_0]]
  // CHECK:   copy_addr [take] [[TMP_0]] to [init] [[TMP_X_0]]
  // CHECK:   [[TMP_1:%.*]] = alloc_stack $Value
  // CHECK:   copy_addr [[X_1]] to [init] [[TMP_1]]
  // CHECK:   copy_addr [take] [[TMP_1]] to [init] [[TMP_X_1]]
  // CHECK:   [[FUNC:%.*]] = function_ref @$ss9FakeArrayV6appendyyxF : $@convention(method) <τ_0_0> (@in_guaranteed τ_0_0, @inout FakeArray<τ_0_0>) -> ()
  // CHECK:   apply [[FUNC]]<(Key, Value)>([[TMP_X]],
  // CHECK: } // end sil function '$ss14FakeDictionaryV20makeSureToCopyTuplesyyF'
  func makeSureToCopyTuples() {
    var result = FakeArray<Element>(k: Klass())
    for x in self {
      result.append(x)
    }
  }
}

// Make sure that we properly forward x into memory and don't crash.
public func forwardIntoMemory(fromNative x: AnyObject, y: Builtin.Word) -> Builtin.BridgeObject {
  // y would normally be 0._builtinWordValue. We don't want to define that
  // conformance.
  let object = Builtin.castToBridgeObject(x, y)
  return object
}

public struct StructWithOptionalAddressOnlyField<T> {
  public let newValue: T?
}

func useStructWithOptionalAddressOnlyField<T>(t: T) -> StructWithOptionalAddressOnlyField<T> {
  return StructWithOptionalAddressOnlyField<T>(newValue: t)
}