Skip to content

Commit e68aa49

Browse files
authored
Merge pull request #34583 from gottesmm/pr-bf7a29f9994c4b246636b8d18611051d25e6b928
[ownership] Add a few test cases that show that the reborrow verifier handles recursive reborrows correctly.
2 parents 526fe57 + d537908 commit e68aa49

File tree

1 file changed

+116
-22
lines changed

1 file changed

+116
-22
lines changed

test/SIL/ownership-verifier/borrow_validate.sil

Lines changed: 116 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// REQUIRES: asserts
33

44
import Builtin
5-
import Swift
65

76
//////////////////
87
// Declarations //
@@ -15,6 +14,11 @@ struct WrapperStruct {
1514
var cls : Klass
1615
}
1716

17+
enum FakeOptional<T> {
18+
case none
19+
case some(T)
20+
}
21+
1822
sil shared [noinline] @blackhole_spl : $@convention(thin) (@guaranteed WrapperStruct) -> () {
1923

2024
bb0(%0 : $WrapperStruct):
@@ -259,6 +263,96 @@ bb3(%newborrowi : @guaranteed $WrapperStruct, %newborrowo : @guaranteed $Wrapper
259263
return %ret : $()
260264
}
261265

266+
// CHECK-NOT: Function: 'borrow_lifetime_discrepency_2'
267+
sil [ossa] @borrow_lifetime_discrepency_2 : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
268+
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
269+
cond_br undef, bb1, bb2
270+
271+
bb1:
272+
%copy0 = copy_value %0 : $WrapperStruct
273+
%borrow0 = begin_borrow %copy0 : $WrapperStruct
274+
%borrow0a = begin_borrow %borrow0 : $WrapperStruct
275+
br bb3(%borrow0a : $WrapperStruct, %borrow0 : $WrapperStruct, %copy0 : $WrapperStruct)
276+
277+
bb2:
278+
%copy1 = copy_value %0 : $WrapperStruct
279+
%borrow1 = begin_borrow %copy1 : $WrapperStruct
280+
%borrow1a = begin_borrow %borrow1 : $WrapperStruct
281+
br bb3(%borrow1a : $WrapperStruct, %borrow1 : $WrapperStruct, %copy1 : $WrapperStruct)
282+
283+
bb3(%newborrowi : @guaranteed $WrapperStruct, %newborrowo : @guaranteed $WrapperStruct, %base : @owned $WrapperStruct):
284+
end_borrow %newborrowi : $WrapperStruct
285+
end_borrow %newborrowo : $WrapperStruct
286+
destroy_value %base : $WrapperStruct
287+
%ret = tuple ()
288+
return %ret : $()
289+
}
290+
291+
// CHECK-LABEL: Error#: 0. Begin Error in Function: 'borrow_lifetime_discrepency_incorrect_1'
292+
// CHECK: Found outside of lifetime use?!
293+
// CHECK: Value: %13 = argument of bb3 : $WrapperStruct // user: %15
294+
// CHECK: Consuming User: destroy_value %13 : $WrapperStruct // id: %15
295+
// CHECK: Non Consuming User: end_borrow %12 : $WrapperStruct // id: %16
296+
// CHECK: Block: bb3
297+
// CHECK-LABEL: Error#: 0. End Error in Function: 'borrow_lifetime_discrepency_incorrect_1'
298+
// CHECK-NOT: Error#: 1.
299+
sil [ossa] @borrow_lifetime_discrepency_incorrect_1 : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
300+
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
301+
cond_br undef, bb1, bb2
302+
303+
bb1:
304+
%copy0 = copy_value %0 : $WrapperStruct
305+
%borrow0 = begin_borrow %copy0 : $WrapperStruct
306+
%borrow0a = begin_borrow %borrow0 : $WrapperStruct
307+
br bb3(%borrow0a : $WrapperStruct, %borrow0 : $WrapperStruct, %copy0 : $WrapperStruct)
308+
309+
bb2:
310+
%copy1 = copy_value %0 : $WrapperStruct
311+
%borrow1 = begin_borrow %copy1 : $WrapperStruct
312+
%borrow1a = begin_borrow %borrow1 : $WrapperStruct
313+
br bb3(%borrow1a : $WrapperStruct, %borrow1 : $WrapperStruct, %copy1 : $WrapperStruct)
314+
315+
bb3(%newborrowi : @guaranteed $WrapperStruct, %newborrowo : @guaranteed $WrapperStruct, %base : @owned $WrapperStruct):
316+
end_borrow %newborrowi : $WrapperStruct
317+
destroy_value %base : $WrapperStruct
318+
end_borrow %newborrowo : $WrapperStruct
319+
%ret = tuple ()
320+
return %ret : $()
321+
}
322+
323+
// CHECK-LABEL: Error#: 0. Begin Error in Function: 'borrow_lifetime_discrepency_incorrect_2'
324+
// CHECK: Found outside of lifetime use?!
325+
// CHECK: Value: %12 = argument of bb3 : $WrapperStruct // user: %14
326+
// CHECK: Consuming User: end_borrow %12 : $WrapperStruct // id: %14
327+
// CHECK: Non Consuming User: end_borrow %11 : $WrapperStruct // id: %15
328+
// CHECK: Block: bb3
329+
// CHECK-LABEL: Error#: 0. End Error in Function: 'borrow_lifetime_discrepency_incorrect_2'
330+
// CHECK-NOT: Error#: 1.
331+
sil [ossa] @borrow_lifetime_discrepency_incorrect_2 : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
332+
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
333+
cond_br undef, bb1, bb2
334+
335+
bb1:
336+
%copy0 = copy_value %0 : $WrapperStruct
337+
%borrow0 = begin_borrow %copy0 : $WrapperStruct
338+
%borrow0a = begin_borrow %borrow0 : $WrapperStruct
339+
br bb3(%borrow0a : $WrapperStruct, %borrow0 : $WrapperStruct, %copy0 : $WrapperStruct)
340+
341+
bb2:
342+
%copy1 = copy_value %0 : $WrapperStruct
343+
%borrow1 = begin_borrow %copy1 : $WrapperStruct
344+
%borrow1a = begin_borrow %borrow1 : $WrapperStruct
345+
br bb3(%borrow1a : $WrapperStruct, %borrow1 : $WrapperStruct, %copy1 : $WrapperStruct)
346+
347+
bb3(%newborrowi : @guaranteed $WrapperStruct, %newborrowo : @guaranteed $WrapperStruct, %base : @owned $WrapperStruct):
348+
end_borrow %newborrowo : $WrapperStruct
349+
end_borrow %newborrowi : $WrapperStruct
350+
destroy_value %base : $WrapperStruct
351+
%ret = tuple ()
352+
return %ret : $()
353+
}
354+
355+
262356
// CHECK-NOT: Function: 'borrow_lifetime_nodiscrepency'
263357
sil [ossa] @borrow_lifetime_nodiscrepency : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
264358
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
@@ -601,27 +695,27 @@ bb0(%0 : @owned $Klass):
601695

602696
bb1(%1 : @owned $SuperKlass):
603697
destroy_value %1 : $SuperKlass
604-
%none = enum $Optional<Klass>, #Optional.none!enumelt
605-
%borrownone = begin_borrow %none : $Optional<Klass>
606-
br bb3(%borrownone : $Optional<Klass>, %none : $Optional<Klass>)
698+
%none = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
699+
%borrownone = begin_borrow %none : $FakeOptional<Klass>
700+
br bb3(%borrownone : $FakeOptional<Klass>, %none : $FakeOptional<Klass>)
607701

608702
bb2(%2 : @owned $Klass):
609-
%some = enum $Optional<Klass>, #Optional.some!enumelt, %2 : $Klass
610-
%borrowsome = begin_borrow %some : $Optional<Klass>
611-
br bb3(%borrowsome : $Optional<Klass>, %some : $Optional<Klass>)
703+
%some = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %2 : $Klass
704+
%borrowsome = begin_borrow %some : $FakeOptional<Klass>
705+
br bb3(%borrowsome : $FakeOptional<Klass>, %some : $FakeOptional<Klass>)
612706

613-
bb3(%borrow : @guaranteed $Optional<Klass>, %mKlass : @owned $Optional<Klass>):
614-
end_borrow %borrow : $Optional<Klass>
615-
destroy_value %mKlass : $Optional<Klass>
707+
bb3(%borrow : @guaranteed $FakeOptional<Klass>, %mKlass : @owned $FakeOptional<Klass>):
708+
end_borrow %borrow : $FakeOptional<Klass>
709+
destroy_value %mKlass : $FakeOptional<Klass>
616710
%9999 = tuple()
617711
return %9999 : $()
618712
}
619713

620714
// CHECK-LABEL: Error#: 0. Begin Error in Function: 'test_borrow_checked_cast_switch_enum_control_flow_incorrect'
621715
// CHECK: Found outside of lifetime use?!
622-
// CHECK: Value: %12 = argument of bb3 : $Optional<Klass>
623-
// CHECK: Consuming User: destroy_value %12 : $Optional<Klass>
624-
// CHECK: Non Consuming User: end_borrow %11 : $Optional<Klass>
716+
// CHECK: Value: %12 = argument of bb3 : $FakeOptional<Klass>
717+
// CHECK: Consuming User: destroy_value %12 : $FakeOptional<Klass>
718+
// CHECK: Non Consuming User: end_borrow %11 : $FakeOptional<Klass>
625719
// CHECK: Block: bb3
626720
// CHECK-LABEL: Error#: 0. End Error in Function: 'test_borrow_checked_cast_switch_enum_control_flow_incorrect'
627721
// CHECK-NOT: Error#: {{[0-9][0-9]*}}. End Error in Function: 'test_borrow_checked_cast_switch_enum_control_flow_incorrect'
@@ -631,18 +725,18 @@ bb0(%0 : @owned $Klass):
631725

632726
bb1(%1 : @owned $SuperKlass):
633727
destroy_value %1 : $SuperKlass
634-
%none = enum $Optional<Klass>, #Optional.none!enumelt
635-
%borrownone = begin_borrow %none : $Optional<Klass>
636-
br bb3(%borrownone : $Optional<Klass>, %none : $Optional<Klass>)
728+
%none = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
729+
%borrownone = begin_borrow %none : $FakeOptional<Klass>
730+
br bb3(%borrownone : $FakeOptional<Klass>, %none : $FakeOptional<Klass>)
637731

638732
bb2(%2 : @owned $Klass):
639-
%some = enum $Optional<Klass>, #Optional.some!enumelt, %2 : $Klass
640-
%borrowsome = begin_borrow %some : $Optional<Klass>
641-
br bb3(%borrowsome : $Optional<Klass>, %some : $Optional<Klass>)
733+
%some = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %2 : $Klass
734+
%borrowsome = begin_borrow %some : $FakeOptional<Klass>
735+
br bb3(%borrowsome : $FakeOptional<Klass>, %some : $FakeOptional<Klass>)
642736

643-
bb3(%borrow : @guaranteed $Optional<Klass>, %mKlass : @owned $Optional<Klass>):
644-
destroy_value %mKlass : $Optional<Klass>
645-
end_borrow %borrow : $Optional<Klass>
737+
bb3(%borrow : @guaranteed $FakeOptional<Klass>, %mKlass : @owned $FakeOptional<Klass>):
738+
destroy_value %mKlass : $FakeOptional<Klass>
739+
end_borrow %borrow : $FakeOptional<Klass>
646740
%9999 = tuple()
647741
return %9999 : $()
648742
}

0 commit comments

Comments
 (0)