1
1
2
- // RUN: %target-swift-emit-silgen -module-name indirect_enum -Xllvm -sil-print-debuginfo %s | %FileCheck %s
2
+ // RUN: %target-swift-emit-silgen -enable-sil-ownership - module-name indirect_enum -Xllvm -sil-print-debuginfo %s | %FileCheck %s
3
3
4
4
indirect enum TreeA < T> {
5
5
case Nil
@@ -151,7 +151,9 @@ func switchTreeA<T>(_ x: TreeA<T>) {
151
151
// CHECK: bb0([[ARG:%.*]] : @guaranteed $TreeA<T>):
152
152
// -- x +2
153
153
// CHECK: [[ARG_COPY:%.*]] = copy_value [[ARG]]
154
- // CHECK: switch_enum [[ARG_COPY]] : $TreeA<T>,
154
+ // CHECK: [[BORROWED_ARG_COPY:%.*]] = begin_borrow [[ARG_COPY]]
155
+ // CHECK: [[ARG_COPY_2:%.*]] = copy_value [[BORROWED_ARG_COPY]]
156
+ // CHECK: switch_enum [[ARG_COPY_2]] : $TreeA<T>,
155
157
// CHECK: case #TreeA.Nil!enumelt: [[NIL_CASE:bb1]],
156
158
// CHECK: case #TreeA.Leaf!enumelt.1: [[LEAF_CASE:bb2]],
157
159
// CHECK: case #TreeA.Branch!enumelt.1: [[BRANCH_CASE:bb3]],
@@ -177,13 +179,15 @@ func switchTreeA<T>(_ x: TreeA<T>) {
177
179
// CHECK: [[TUPLE_ADDR:%.*]] = project_box [[NODE_BOX]]
178
180
// CHECK: [[TUPLE:%.*]] = load_borrow [[TUPLE_ADDR]]
179
181
// CHECK: ([[LEFT:%.*]], [[RIGHT:%.*]]) = destructure_tuple [[TUPLE]]
180
- // CHECK: switch_enum [[LEFT]] : $TreeA<T>,
182
+ // CHECK: [[LEFT_COPY:%.*]] = copy_value [[LEFT]]
183
+ // CHECK: switch_enum [[LEFT_COPY]] : $TreeA<T>,
181
184
// CHECK: case #TreeA.Leaf!enumelt.1: [[LEAF_CASE_LEFT:bb[0-9]+]],
182
185
// CHECK: default [[FAIL_LEFT:bb[0-9]+]]
183
186
184
187
// CHECK: [[LEAF_CASE_LEFT]]([[LEFT_LEAF_BOX:%.*]] : @owned $<τ_0_0> { var τ_0_0 } <T>):
185
188
// CHECK: [[LEFT_LEAF_VALUE:%.*]] = project_box [[LEFT_LEAF_BOX]]
186
- // CHECK: switch_enum [[RIGHT]] : $TreeA<T>,
189
+ // CHECK: [[RIGHT_COPY:%.*]] = copy_value [[RIGHT]]
190
+ // CHECK: switch_enum [[RIGHT_COPY]] : $TreeA<T>,
187
191
// CHECK: case #TreeA.Leaf!enumelt.1: [[LEAF_CASE_RIGHT:bb[0-9]+]],
188
192
// CHECK: default [[FAIL_RIGHT:bb[0-9]+]]
189
193
@@ -195,10 +199,12 @@ func switchTreeA<T>(_ x: TreeA<T>) {
195
199
// CHECK: destroy_value [[NODE_BOX]]
196
200
// CHECK: br [[OUTER_CONT]]
197
201
198
- // CHECK: [[FAIL_RIGHT]]:
202
+ // CHECK: [[FAIL_RIGHT]]([[DEFAULT_VAL:%.*]] :
203
+ // CHECK: destroy_value [[DEFAULT_VAL]]
199
204
// CHECK: br [[DEFAULT:bb[0-9]+]]
200
205
201
- // CHECK: [[FAIL_LEFT]]:
206
+ // CHECK: [[FAIL_LEFT]]([[DEFAULT_VAL:%.*]] :
207
+ // CHECK: destroy_value [[DEFAULT_VAL]]
202
208
// CHECK: br [[DEFAULT]]
203
209
204
210
case . Branch( . Leaf( let x) , . Leaf( let y) ) :
@@ -310,6 +316,27 @@ func switchTreeB<T>(_ x: TreeB<T>) {
310
316
// CHECK: return
311
317
}
312
318
319
+ // Make sure that switchTreeInt obeys ownership invariants.
320
+ //
321
+ // CHECK-LABEL: sil hidden @$s13indirect_enum13switchTreeInt{{[_0-9a-zA-Z]*}}F
322
+ func switchTreeInt( _ x: TreeInt ) {
323
+ switch x {
324
+
325
+ case . Nil:
326
+ a ( )
327
+
328
+ case . Leaf( let x) :
329
+ b ( x)
330
+
331
+ case . Branch( . Leaf( let x) , . Leaf( let y) ) :
332
+ c ( x, y)
333
+
334
+ default :
335
+ d ( )
336
+ }
337
+ }
338
+ // CHECK: } // end sil function '$s13indirect_enum13switchTreeInt{{[_0-9a-zA-Z]*}}F'
339
+
313
340
// CHECK-LABEL: sil hidden @$s13indirect_enum10guardTreeA{{[_0-9a-zA-Z]*}}F
314
341
func guardTreeA< T> ( _ tree: TreeA < T > ) {
315
342
// CHECK: bb0([[ARG:%.*]] : @guaranteed $TreeA<T>):
@@ -340,8 +367,9 @@ func guardTreeA<T>(_ tree: TreeA<T>) {
340
367
// CHECK: destroy_value [[ORIGINAL_VALUE]]
341
368
// CHECK: [[YES]]([[BOX:%.*]] : @owned $<τ_0_0> { var (left: TreeA<τ_0_0>, right: TreeA<τ_0_0>) } <T>):
342
369
// CHECK: [[VALUE_ADDR:%.*]] = project_box [[BOX]]
343
- // CHECK: [[TUPLE:%.*]] = load [take] [[VALUE_ADDR]]
370
+ // CHECK: [[TUPLE:%.*]] = load_borrow [[VALUE_ADDR]]
344
371
// CHECK: [[TUPLE_COPY:%.*]] = copy_value [[TUPLE]]
372
+ // CHECK: end_borrow [[TUPLE]]
345
373
// CHECK: ([[L:%.*]], [[R:%.*]]) = destructure_tuple [[TUPLE_COPY]]
346
374
// CHECK: destroy_value [[BOX]]
347
375
guard case . Branch( left: let l, right: let r) = tree else { return }
@@ -381,16 +409,16 @@ func guardTreeA<T>(_ tree: TreeA<T>) {
381
409
// CHECK: destroy_value [[ORIGINAL_VALUE]]
382
410
// CHECK: [[YES]]([[BOX:%.*]] : @owned $<τ_0_0> { var (left: TreeA<τ_0_0>, right: TreeA<τ_0_0>) } <T>):
383
411
// CHECK: [[VALUE_ADDR:%.*]] = project_box [[BOX]]
384
- // CHECK: [[TUPLE:%.*]] = load [take] [[VALUE_ADDR]]
412
+ // CHECK: [[TUPLE:%.*]] = load_borrow [[VALUE_ADDR]]
385
413
// CHECK: [[TUPLE_COPY:%.*]] = copy_value [[TUPLE]]
414
+ // CHECK: end_borrow [[TUPLE]]
386
415
// CHECK: ([[L:%.*]], [[R:%.*]]) = destructure_tuple [[TUPLE_COPY]]
387
416
// CHECK: destroy_value [[BOX]]
388
417
// CHECK: destroy_value [[R]]
389
418
// CHECK: destroy_value [[L]]
390
419
if case . Branch( left: let l, right: let r) = tree { }
391
420
}
392
421
}
393
-
394
422
// CHECK-LABEL: sil hidden @$s13indirect_enum10guardTreeB{{[_0-9a-zA-Z]*}}F
395
423
func guardTreeB< T> ( _ tree: TreeB < T > ) {
396
424
do {
@@ -479,6 +507,25 @@ func guardTreeB<T>(_ tree: TreeB<T>) {
479
507
}
480
508
}
481
509
510
+ // Just run guardTreeInt through the ownership verifier
511
+ //
512
+ // CHECK-LABEL: sil hidden @$s13indirect_enum12guardTreeInt{{[_0-9a-zA-Z]*}}F
513
+ func guardTreeInt( _ tree: TreeInt ) {
514
+ do {
515
+ guard case . Nil = tree else { return }
516
+
517
+ guard case . Leaf( let x) = tree else { return }
518
+
519
+ guard case . Branch( left: let l, right: let r) = tree else { return }
520
+ }
521
+
522
+ do {
523
+ if case . Nil = tree { }
524
+ if case . Leaf( let x) = tree { }
525
+ if case . Branch( left: let l, right: let r) = tree { }
526
+ }
527
+ }
528
+
482
529
// SEMANTIC ARC TODO: This test needs to be made far more comprehensive.
483
530
// CHECK-LABEL: sil hidden @$s13indirect_enum35dontDisableCleanupOfIndirectPayloadyyAA010TrivialButG0OF : $@convention(thin) (@guaranteed TrivialButIndirect) -> () {
484
531
func dontDisableCleanupOfIndirectPayload( _ x: TrivialButIndirect ) {
0 commit comments