Skip to content

Commit 064d37f

Browse files
committed
Add test: SIL lifetime dependence diagnostic passes
1 parent 9f74282 commit 064d37f

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// RUN: %target-sil-opt -test-runner %s \
2+
// RUN: -diagnostics -sil-verify-all \
3+
// RUN: -enable-experimental-feature LifetimeDependence \
4+
// RUN: -enable-experimental-feature LifetimeDependenceDiagnoseTrivial \
5+
// RUN: 2>&1 | %FileCheck %s
6+
7+
// Test SIL expected from SILGen output. Run all diagnostic passes which includes lifetime dependence handling:
8+
// -lifetime-dependence-insertion
9+
// -lifetime-dependence-scopefixup
10+
// -lifetime-dependence-diagnostics
11+
//
12+
// This is a good place to put reduced .sil tests.
13+
14+
// REQUIRES: swift_in_compiler
15+
// REQUIRES: swift_feature_LifetimeDependence
16+
// REQUIRES: swift_feature_LifetimeDependenceDiagnoseTrivial
17+
18+
sil_stage raw
19+
20+
import Builtin
21+
import Swift
22+
import SwiftShims
23+
24+
struct Owner {}
25+
struct NE: ~Escapable {}
26+
struct OtherNE: ~Escapable {}
27+
28+
sil @getNE : $@convention(c) (@in_guaranteed Owner) -> @lifetime(borrow 0) @autoreleased NE
29+
sil @copyNE : $@convention(c) (NE, @lifetime(copy 0) @inout NE) -> ()
30+
sil @makeOwner : $@convention(c) () -> Owner
31+
32+
// Modify a local via 'inout' assignment.
33+
// Do not insert a mark_dep.
34+
// Do not extend any scopes.
35+
// Consider all uses of the local to be potential uses of the argument.
36+
//
37+
// CHECK-LABEL: sil [ossa] @copyToLocal : $@convention(thin) (@owned NE) -> () {
38+
// CHECK: bb0(%0 : @owned $NE):
39+
// CHECK: [[ALLOC:%.*]] = alloc_stack [var_decl] $NE, var, name "v1"
40+
// CHECK: [[MV:%.*]] = move_value [var_decl] %0
41+
// CHECK: [[ACCESS:%.*]] = begin_access [modify] [static] [[ALLOC]]
42+
// CHECK: apply %{{.*}}([[MV]], [[ACCESS]]) : $@convention(c) (NE, @lifetime(copy 0) @inout NE) -> ()
43+
// CHECK: end_access [[ACCESS]]
44+
// CHECK: destroy_value [[MV]]
45+
// CHECK: destroy_addr [[ALLOC]]
46+
// CHECK-LABEL: } // end sil function 'copyToLocal'
47+
sil [ossa] @copyToLocal : $@convention(thin) (@owned NE) -> () {
48+
bb0(%0 : @owned $NE):
49+
%1 = alloc_box ${ var NE }, var, name "v1"
50+
%2 = begin_borrow [var_decl] %1
51+
%3 = project_box %2, 0
52+
%4 = move_value [var_decl] %0
53+
%5 = begin_borrow %4
54+
// assign the local to the argument
55+
%6 = begin_access [modify] [unknown] %3
56+
%7 = function_ref @copyNE : $@convention(c) (NE, @lifetime(copy 0) @inout NE) -> ()
57+
%8 = apply %7(%5, %6) : $@convention(c) (NE, @lifetime(copy 0) @inout NE) -> ()
58+
end_access %6
59+
end_borrow %5
60+
// destroy the argument
61+
destroy_value %4
62+
end_borrow %2
63+
// destroy the local
64+
destroy_value %1
65+
%14 = tuple ()
66+
return %14
67+
}
68+
69+
// rdar://140424699
70+
//
71+
// Reassign into a local that outlives the original.
72+
//
73+
// CHECK-LABEL: sil [ossa] @testInoutReassign : $@convention(thin) () -> () {
74+
// CHECK: [[V1:%.*]] = alloc_stack [var_decl] $NE, var, name "v1", type $NE
75+
// CHECK: [[MD1:%.*]] = mark_dependence [nonescaping]
76+
// CHECK: store [[MD1]] to [init] [[V1]]
77+
// CHECK: [[MD2:%.*]] = mark_dependence [nonescaping]
78+
// CHECK: [[MV:%.*]] = move_value [var_decl] [[MD2]]
79+
// CHECK: debug_value [[MV]], let, name "v2"
80+
// CHECK: [[ACCESS:%.*]] = begin_access [modify] [static] [[V1]]
81+
// CHECK: apply %{{.*}}([[MV]], [[ACCESS]]) : $@convention(c) (NE, @lifetime(copy 0) @inout NE) -> ()
82+
// CHECK: end_access [[ACCESS]]
83+
// CHECK: destroy_value [[MV]]
84+
// CHECK: destroy_addr [[V1]]
85+
// CHECK-LABEL: } // end sil function 'testInoutReassign'
86+
sil [ossa] @testInoutReassign : $@convention(thin) () -> () {
87+
bb0:
88+
%0 = function_ref @makeOwner : $@convention(c) () -> Owner // user: %1
89+
%1 = apply %0() : $@convention(c) () -> Owner
90+
%2 = move_value [var_decl] %1 : $Owner
91+
debug_value %2 : $Owner, let, name "o"
92+
93+
// Declare v1: NE
94+
%8 = alloc_box ${ var NE }, var, name "v1"
95+
%9 = begin_borrow [var_decl] %8 : ${ var NE }
96+
%10 = project_box %9 : ${ var NE }, 0
97+
98+
// v1 = owner.ne
99+
%11 = alloc_stack $Owner
100+
store %2 to [trivial] %11 : $*Owner
101+
%13 = function_ref @getNE : $@convention(c) (@in_guaranteed Owner) -> @lifetime(borrow 0) @autoreleased NE
102+
%14 = apply %13(%11) : $@convention(c) (@in_guaranteed Owner) -> @lifetime(borrow 0) @autoreleased NE
103+
dealloc_stack %11 : $*Owner
104+
store %14 to [init] %10 : $*NE
105+
106+
// v2 = owner.ne
107+
%17 = alloc_stack $Owner
108+
store %2 to [trivial] %17 : $*Owner
109+
%22 = apply %13(%17) : $@convention(c) (@in_guaranteed Owner) -> @lifetime(borrow 0) @autoreleased NE
110+
dealloc_stack %17 : $*Owner
111+
%25 = move_value [var_decl] %22 : $NE
112+
debug_value %25 : $NE, let, name "v2"
113+
114+
// copyView(v2, &v1)
115+
%81 = begin_borrow %25 : $NE
116+
%82 = begin_access [modify] [unknown] %10 : $*NE
117+
%83 = function_ref @copyNE : $@convention(c) (NE, @lifetime(copy 0) @inout NE) -> ()
118+
%84 = apply %83(%81, %82) : $@convention(c) (NE, @lifetime(copy 0) @inout NE) -> ()
119+
end_access %82 : $*NE
120+
end_borrow %81 : $NE
121+
122+
// destroy v2
123+
destroy_value %25 : $NE
124+
125+
// destroy v1
126+
end_borrow %9 : ${ var NE }
127+
destroy_value %8 : ${ var NE }
128+
129+
// Owner covers all uses.
130+
extend_lifetime %2 : $Owner
131+
%93 = tuple ()
132+
return %93 : $()
133+
}

0 commit comments

Comments
 (0)