Skip to content

Commit 37eafa9

Browse files
committed
OpaqueValues: add tests for typed throws
1 parent 3b0e773 commit 37eafa9

File tree

2 files changed

+192
-1
lines changed

2 files changed

+192
-1
lines changed

test/SILGen/opaque_values_silgen.swift

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,7 @@ struct Twople<T> {
875875
}
876876
}
877877

878-
// CHECK-LABEL: sil{{.*}} [ossa] @throwTypedValue : {{.*}} {
878+
// CHECK-LABEL: sil{{.*}} [ossa] @throwTypedValue : {{.*}} -> @error Err {
879879
// CHECK: bb0([[E:%[^,]+]] :
880880
// CHECK: [[SWIFT_WILL_THROW_TYPED:%[^,]+]] = function_ref @swift_willThrowTyped
881881
// CHECK: apply [[SWIFT_WILL_THROW_TYPED]]<Err>([[E]])
@@ -884,6 +884,57 @@ struct Twople<T> {
884884
@_silgen_name("throwTypedValue")
885885
func throwTypedValue(_ e: Err) throws(Err) { throw e }
886886

887+
// CHECK-LABEL: sil{{.*}} [ossa] @callTypedThrowsFunc : {{.*}} -> @error any Error {
888+
// CHECK: bb0:
889+
// CHECK: [[TYPED_THROW_FN:%[^,]+]] = function_ref @throwTypedValue
890+
// CHECK: try_apply [[TYPED_THROW_FN]]({{%[0-9]+}}) : $@convention(thin) (Err) -> @error Err, normal bb1, error bb2
891+
//
892+
// CHECK: bb1({{%[0-9]+}} : $()):
893+
// CHECK: return
894+
//
895+
// CHECK: bb2([[E:%[^,]+]] : $Err):
896+
// CHECK: [[STACK_ALLOC:%[^,]+]] = alloc_stack $any Error
897+
// CHECK: [[BOX:%[^,]+]] = project_existential_box $Err
898+
// CHECK: store [[E]] to [trivial] [[BOX]]
899+
// CHECK: [[ANY_ERROR:%[^,]+]] = load [take] [[STACK_ALLOC]]
900+
// CHECK: throw [[ANY_ERROR]]
901+
// CHECK-LABEL: } // end sil function 'callTypedThrowsFunc'
902+
@_silgen_name("callTypedThrowsFunc")
903+
func callTypedThrowsFunc() throws {
904+
try throwTypedValue(Err())
905+
}
906+
907+
// CHECK-LABEL: sil{{.*}} [ossa] @throwTypedValueGeneric : {{.*}} <GenErr where GenErr : Error> (@in_guaranteed GenErr) -> @error_indirect GenErr {
908+
// CHECK: bb0([[BORROWED_ERR:%[^,]+]] : @guaranteed $GenErr):
909+
// CHECK: [[E:%[^,]+]] = copy_value [[BORROWED_ERR]]
910+
// CHECK: [[SWIFT_WILL_THROW_TYPED:%[^,]+]] = function_ref @swift_willThrowTyped
911+
// CHECK: apply [[SWIFT_WILL_THROW_TYPED]]<GenErr>([[E]])
912+
// CHECK: throw [[E]]
913+
// CHECK-LABEL: } // end sil function 'throwTypedValueGeneric'
914+
@_silgen_name("throwTypedValueGeneric")
915+
func throwTypedValueGeneric<GenErr: Error>(_ e: GenErr) throws(GenErr) { throw e }
916+
917+
// CHECK-LABEL: sil{{.*}} [ossa] @callTypedThrowsFuncGeneric : {{.*}} -> @error any Error {
918+
// CHECK: bb0:
919+
// CHECK: [[ERR_VAL:%[^,]+]] = apply {{.*}} -> Err
920+
// CHECK: [[GEN_TYPED_THROW_FN:%[^,]+]] = function_ref @throwTypedValueGeneric
921+
// CHECK: try_apply [[GEN_TYPED_THROW_FN]]<Err>([[ERR_VAL]]) : $@convention(thin) <τ_0_0 where τ_0_0 : Error> (@in_guaranteed τ_0_0) -> @error_indirect τ_0_0, normal bb1, error bb2
922+
//
923+
// CHECK: bb1({{%[0-9]+}} : $()):
924+
// CHECK: return
925+
//
926+
// CHECK: bb2([[E:%[^,]+]] : $Err):
927+
// CHECK: [[STACK_ALLOC:%[^,]+]] = alloc_stack $any Error
928+
// CHECK: [[BOX:%[^,]+]] = project_existential_box $Err
929+
// CHECK: store [[E]] to [trivial] [[BOX]]
930+
// CHECK: [[ANY_ERROR:%[^,]+]] = load [take] [[STACK_ALLOC]]
931+
// CHECK: throw [[ANY_ERROR]]
932+
// CHECK-LABEL: } // end sil function 'callTypedThrowsFuncGeneric'
933+
@_silgen_name("callTypedThrowsFuncGeneric")
934+
func callTypedThrowsFuncGeneric() throws {
935+
try throwTypedValueGeneric(Err())
936+
}
937+
887938
struct Err : Error {}
888939

889940
// CHECK-LABEL: sil{{.*}} [ossa] @copy_expr_generic : {{.*}} {

test/SILOptimizer/address_lowering.sil

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ enum Optional<T> {
2929

3030
protocol Error {}
3131

32+
struct Bad: Error {}
33+
3234
struct I {}
3335

3436
class Klass {}
@@ -109,6 +111,8 @@ sil [ossa] @takeTuple : $@convention(thin) <τ_0_0> (@in_guaranteed (τ_0_0, C))
109111

110112
sil [ossa] @eraseToAny : $@convention(thin) <T> (@in_guaranteed T) -> @out Any
111113
sil [ossa] @produceInt : $@convention(thin) () -> Int
114+
sil [ossa] @produceBool : $@convention(thin) () -> Bool
115+
sil [ossa] @produceBad : $@convention(thin) () -> Bad
112116

113117
sil [ossa] @takeIn : $@convention(thin) <T> (@in T) -> ()
114118
sil [ossa] @takeInGuaranteed : $@convention(thin) <T> (@in_guaranteed T) -> ()
@@ -1454,6 +1458,142 @@ bad(%41 : @owned $any Error):
14541458
throw %41 : $any Error
14551459
}
14561460

1461+
// While an '@error Error' turns into an '@error any Error', an '@error' of a concrete type remains as-is.
1462+
// --------
1463+
// CHECK-LABEL: sil [ossa] @f270_typedThrows_throwConcrete : $@convention(thin) (Bad) -> (Bad, @error Bad) {
1464+
// CHECK: bb0(%0 : $Bad):
1465+
// CHECK: return %0 : $Bad
1466+
// CHECK: throw %0 : $Bad
1467+
// CHECK-LABEL: } // end sil function 'f270_typedThrows_throwConcrete'
1468+
sil [ossa] @f270_typedThrows_throwConcrete : $@convention(thin) (Bad) -> (Bad, @error Bad) {
1469+
bb0(%0 : $Bad):
1470+
%fn = function_ref @produceBool : $@convention(thin) () -> Bool
1471+
%cond = apply %fn() : $@convention(thin) () -> Bool
1472+
cond_br %cond, doThrow, doReturn
1473+
1474+
doThrow:
1475+
throw %0
1476+
1477+
doReturn:
1478+
return %0
1479+
}
1480+
1481+
// CHECK-LABEL: sil [ossa] @f271_typedThrows_callConcrete : $@convention(thin) () -> () {
1482+
// CHECK: try_apply {{.*}} : $@convention(thin) (Bad) -> (Bad, @error Bad), normal bb2, error bb1
1483+
// CHECK: bb1({{.*}} : $Bad)
1484+
// CHECK: bb2({{.*}} : $Bad)
1485+
// CHECK-LABEL: } // end sil function 'f271_typedThrows_callConcrete'
1486+
sil [ossa] @f271_typedThrows_callConcrete : $@convention(thin) () -> () {
1487+
bb0:
1488+
%fn = function_ref @produceBad : $@convention(thin) () -> Bad
1489+
%arg = apply %fn() : $@convention(thin) () -> Bad
1490+
%callee = function_ref @f270_typedThrows_throwConcrete : $@convention(thin) (Bad) -> (Bad, @error Bad)
1491+
try_apply %callee(%arg) : $@convention(thin) (Bad) -> (Bad, @error Bad), normal normalBB, error errorBB
1492+
1493+
normalBB(%r : $Bad):
1494+
ignored_use %r
1495+
br exitBB
1496+
1497+
errorBB(%e : $Bad):
1498+
ignored_use %e
1499+
br exitBB
1500+
1501+
exitBB:
1502+
%t = tuple ()
1503+
return %t
1504+
}
1505+
1506+
// Handle throwing a generic type conforming to Error via @error_indirect
1507+
// --------
1508+
// CHECK-LABEL: sil [ossa] @f272_typedThrows_throwGeneric : $@convention(thin) <GenBad, Result where GenBad : Error> (@in_guaranteed GenBad, @in_guaranteed Result) -> (@out Result, @error_indirect GenBad) {
1509+
// CHECK: bb0(%0 : $*Result, %1 : $*GenBad, %2 : $*GenBad, %3 : $*Result):
1510+
// CHECK: cond_br {{.*}}, bb2, bb1
1511+
//
1512+
// CHECK: bb1:
1513+
// CHECK: copy_addr %3 to [init] %0 : $*Result
1514+
// CHECK: return {{.*}} : $()
1515+
//
1516+
// CHECK: bb2:
1517+
// CHECK: [[STACK:%[^,]+]] = alloc_stack $GenBad
1518+
// CHECK: copy_addr %2 to [init] [[STACK]] : $*GenBad
1519+
// CHECK: copy_addr [take] [[STACK]] to [init] %1 : $*GenBad
1520+
// CHECK: dealloc_stack [[STACK]] : $*GenBad
1521+
// CHECK: throw_addr
1522+
// CHECK-LABEL: } // end sil function 'f272_typedThrows_throwGeneric'
1523+
sil [ossa] @f272_typedThrows_throwGeneric : $@convention(thin) <GenBad, Result where GenBad : Error> (@in_guaranteed GenBad, @in_guaranteed Result) -> (@out Result, @error_indirect GenBad) {
1524+
bb0(%e : @guaranteed $GenBad, %r : @guaranteed $Result):
1525+
%fn = function_ref @produceBool : $@convention(thin) () -> Bool
1526+
%cond = apply %fn() : $@convention(thin) () -> Bool
1527+
cond_br %cond, doThrow, doReturn
1528+
1529+
doReturn:
1530+
%rCopy = copy_value %r
1531+
return %rCopy
1532+
1533+
doThrow:
1534+
%eCopy = copy_value %e
1535+
throw %eCopy
1536+
}
1537+
1538+
// CHECK-LABEL: sil [ossa] @f273_typedThrows_callGeneric : $@convention(thin) () -> () {
1539+
// CHECK: bb0:
1540+
// CHECK: // function_ref produceBad
1541+
// CHECK: [[PROD:%[^,]+]] = function_ref @produceBad : $@convention(thin) () -> Bad
1542+
// CHECK: [[ARG1:%[^,]+]] = apply [[PROD]]() : $@convention(thin) () -> Bad
1543+
// CHECK: [[ARG2:%[^,]+]] = apply [[PROD]]() : $@convention(thin) () -> Bad
1544+
// CHECK: [[ARG1_IN:%[^,]+]] = alloc_stack $Bad
1545+
// CHECK: store [[ARG1]] to [trivial] [[ARG1_IN]] : $*Bad
1546+
// CHECK: [[ARG2_IN:%[^,]+]] = alloc_stack $Bad
1547+
// CHECK: store [[ARG2]] to [trivial] [[ARG2_IN]] : $*Bad
1548+
// CHECK: [[RESULT_OUT:%[^,]+]] = alloc_stack $Bad
1549+
// CHECK: [[ERR_OUT:%[^,]+]] = alloc_stack $Bad
1550+
// CHECK: try_apply {{.*}}<Bad, Bad>([[RESULT_OUT]], [[ERR_OUT]], [[ARG1_IN]], [[ARG2_IN]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Error> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> (@out τ_0_1, @error_indirect τ_0_0), normal bb2, error bb1
1551+
1552+
// CHECK: bb1:
1553+
// CHECK: [[ERR:%[^,]+]] = load [trivial] [[ERR_OUT]] : $*Bad
1554+
// CHECK: dealloc_stack [[ERR_OUT]] : $*Bad
1555+
// CHECK: dealloc_stack [[RESULT_OUT]] : $*Bad
1556+
// CHECK: dealloc_stack [[ARG2_IN]] : $*Bad
1557+
// CHECK: dealloc_stack [[ARG1_IN]] : $*Bad
1558+
// CHECK: ignored_use [[ERR]] : $Bad
1559+
// CHECK: ignored_use [[ERR]] : $Bad
1560+
// CHECK: br bb3
1561+
1562+
// CHECK: bb2(%11 : $()):
1563+
// CHECK: dealloc_stack [[ERR_OUT]] : $*Bad
1564+
// CHECK: [[RESULT:%[^,]+]] = load [trivial] [[RESULT_OUT]] : $*Bad
1565+
// CHECK: dealloc_stack [[RESULT_OUT]] : $*Bad
1566+
// CHECK: dealloc_stack [[ARG2_IN]] : $*Bad
1567+
// CHECK: dealloc_stack [[ARG1_IN]] : $*Bad
1568+
// CHECK: ignored_use [[RESULT]] : $Bad
1569+
// CHECK: br bb3
1570+
1571+
// CHECK: bb3:
1572+
// CHECK: return {{.*}} : $()
1573+
// CHECK-LABEL: } // end sil function 'f273_typedThrows_callGeneric'
1574+
sil [ossa] @f273_typedThrows_callGeneric : $@convention(thin) () -> () {
1575+
bb0:
1576+
%fn = function_ref @produceBad : $@convention(thin) () -> Bad
1577+
%arg1 = apply %fn() : $@convention(thin) () -> Bad
1578+
%arg2 = apply %fn() : $@convention(thin) () -> Bad
1579+
%callee = function_ref @f272_typedThrows_throwGeneric : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Error> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> (@out τ_0_1, @error_indirect τ_0_0)
1580+
try_apply %callee<Bad, Bad>(%arg1, %arg2) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Error> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> (@out τ_0_1, @error_indirect τ_0_0), normal normalBB, error errorBB
1581+
1582+
normalBB(%r : $Bad):
1583+
ignored_use %r
1584+
br exitBB
1585+
1586+
errorBB(%e : $Bad):
1587+
ignored_use %e
1588+
ignored_use %e
1589+
br exitBB
1590+
1591+
exitBB:
1592+
%t = tuple ()
1593+
return %t
1594+
}
1595+
1596+
14571597
// CHECK-LABEL: sil [ossa] @fixeeLifetime : {{.*}} {
14581598
// CHECK: {{bb[0-9]+}}([[ADDR:%[^,]+]] : $*T):
14591599
// CHECK: fix_lifetime [[ADDR]]

0 commit comments

Comments
 (0)