@@ -31,6 +31,17 @@ struct Wrapper<T>: ~Copyable {
31
31
var t: T
32
32
}
33
33
34
+ struct NonCopyableForwardingStruct : ~Copyable {
35
+ var some: Int
36
+ deinit
37
+ }
38
+
39
+ enum NonCopyableForwardingEnum : ~Copyable {
40
+ case some(Int)
41
+ case nothing
42
+ deinit
43
+ }
44
+
34
45
sil @getWrappedValue : $@convention(thin) <T> (@in_guaranteed Wrapper<T>) -> @out T
35
46
36
47
// Test that a release_value is not removed for a struct-with-deinit.
@@ -110,3 +121,51 @@ bb0(%0 : @owned $S):
110
121
%64 = tuple ()
111
122
return %64 : $()
112
123
}
124
+
125
+ // Test a "dead" non-Copyable struct-with-deinit that forwards a
126
+ // single trivial value. The destroy_value cannot be eliminated
127
+ // without first devirtualizing the deinit.
128
+ //
129
+ // CHECK-LABEL: sil [ossa] @testNonCopyableForwardingStructDeinit : $@convention(thin) (Int) -> () {
130
+ // CHECK: [[STRUCT:%[0-9]+]] = struct $NonCopyableForwardingStruct (%0 : $Int)
131
+ // CHECK: destroy_value [[STRUCT]]
132
+ // CHECK-LABEL: } // end sil function 'testNonCopyableForwardingStructDeinit'
133
+ sil [ossa] @testNonCopyableForwardingStructDeinit : $@convention(thin) (Int) -> () {
134
+ bb0(%0: $Int):
135
+ %1 = struct $NonCopyableForwardingStruct(%0 : $Int)
136
+ destroy_value %1
137
+ %13 = tuple ()
138
+ return %13
139
+ }
140
+
141
+ // Test a "dead" non-Copyable enum-with-deinit that forwards a single
142
+ // trivial value. The destroy_value cannot be eliminated without first
143
+ // devirtualizing the deinit.
144
+ //
145
+ // CHECK-LABEL: sil [ossa] @testNonCopyableForwardingEnumDeinit : $@convention(thin) (Int) -> () {
146
+ // CHECK: [[ENUM:%[0-9]+]] = enum $NonCopyableForwardingEnum, #NonCopyableForwardingEnum.some!enumelt, %0
147
+ // CHECK: destroy_value [[ENUM]]
148
+ // CHECK-LABEL: } // end sil function 'testNonCopyableForwardingEnumDeinit'
149
+ sil [ossa] @testNonCopyableForwardingEnumDeinit : $@convention(thin) (Int) -> () {
150
+ bb0(%0 : $Int):
151
+ %1 = enum $NonCopyableForwardingEnum, #NonCopyableForwardingEnum.some!enumelt, %0
152
+ destroy_value %1
153
+ %13 = tuple ()
154
+ return %13
155
+ }
156
+
157
+ // Test a "dead" non-Copyable enum-with-deinit and an empty case. The
158
+ // destroy_value cannot be eliminated without first devirtualizing the
159
+ // deinit.
160
+ //
161
+ // CHECK-LABEL: sil [ossa] @testNonCopyableEmptyEnumDeinit : $@convention(thin) () -> () {
162
+ // CHECK: [[ENUM:%[0-9]+]] = enum $NonCopyableForwardingEnum, #NonCopyableForwardingEnum.nothing
163
+ // CHECK: destroy_value [[ENUM]]
164
+ // CHECK-LABEL: } // end sil function 'testNonCopyableEmptyEnumDeinit'
165
+ sil [ossa] @testNonCopyableEmptyEnumDeinit : $@convention(thin) () -> () {
166
+ bb0:
167
+ %0 = enum $NonCopyableForwardingEnum, #NonCopyableForwardingEnum.nothing
168
+ destroy_value %0
169
+ %13 = tuple ()
170
+ return %13
171
+ }
0 commit comments