Skip to content

Commit 8d7eba1

Browse files
committed
[Test] Add test for async direct error return with non-maching error/result types
When the error type does not directly fit into the result type, we appy a mapping. These tests verify that this mapping is applied properly on the callee and caller site.
1 parent 399eb88 commit 8d7eba1

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed

test/IRGen/typed_throws_abi.swift

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,6 +1549,128 @@ func callNonMatching_f1(_ b: Bool) -> (Int, Float, Bool, Float) {
15491549
}
15501550
}
15511551

1552+
// CHECK: define hidden swifttailcc void @"$s16typed_throws_abi20nonMatching_f0_asyncySf_SftSbYaAA7OneWordVYKF"(ptr swiftasync %0, i1 %1)
1553+
// CHECK: br i1 %1, label %[[SUCCESS:.*]], label %[[ERROR:.*]]
1554+
// CHECK: [[SUCCESS]]:
1555+
// CHECK: call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr {{%.*}}, i1 false, ptr @"$s16typed_throws_abi20nonMatching_f0_asyncySf_SftSbYaAA7OneWordVYKF.0.49", ptr {{%.*}}, ptr {{%.*}}, float 1.000000e+00, float 2.000000e+00, i64 undef, ptr null)
1556+
// CHECK: unreachable
1557+
// CHECK: 18:
1558+
// CHECK: [[ERROR_X:%.*]] = load i64, ptr %.x1._value, align 8
1559+
// CHECK: [[ERROR_RET:%.*]] = insertvalue { float, float, i64 } undef, i64 [[ERROR_X]], 2
1560+
// CHECK: [[ERROR_RET0:%.*]] = extractvalue { float, float, i64 } [[ERROR_RET]], 0
1561+
// CHECK: [[ERROR_RET1:%.*]] = extractvalue { float, float, i64 } [[ERROR_RET]], 1
1562+
// CHECK: [[ERROR_RET2:%.*]] = extractvalue { float, float, i64 } [[ERROR_RET]], 2
1563+
// CHECK: call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr {{%.*}}, i1 false, ptr @"$s16typed_throws_abi20nonMatching_f0_asyncySf_SftSbYaAA7OneWordVYKF.0", ptr {{%.*}}, ptr {{%.*}}, float [[ERROR_RET0]], float [[ERROR_RET1]], i64 [[ERROR_RET2]], ptr inttoptr (i64 1 to ptr))
1564+
// CHECK: unreachable
1565+
// CHECK: }
1566+
@available(SwiftStdlib 6.0, *)
1567+
func nonMatching_f0_async(_ b: Bool) async throws(OneWord) -> (Float, Float) {
1568+
guard b else {
1569+
throw OneWord()
1570+
}
1571+
return (1.0, 2.0)
1572+
}
1573+
1574+
1575+
// CHECK: define hidden swifttailcc void @"$s16typed_throws_abi24callNonMatching_f0_asyncySi_S2ftSbYaF"(ptr swiftasync %0, i1 %1)
1576+
// CHECK: call { ptr, float, float, i64, ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0f32f32i64p0s(i32 1024, ptr {{%.*}}, ptr @__swift_async_resume_project_context, ptr @"$s16typed_throws_abi24callNonMatching_f0_asyncySi_S2ftSbYaF.0", ptr @"$s16typed_throws_abi20nonMatching_f0_asyncySf_SftSbYaAA7OneWordVYKF", ptr {{%.*}}, i1 %1)
1577+
// CHECK: [[CALL_RES0:%.*]] = extractvalue { float, float, i64 } {{%.*}}, 0
1578+
// CHECK: [[CALL_RES1:%.*]] = extractvalue { float, float, i64 } {{%.*}}, 1
1579+
// CHECK: [[CALL_RES2:%.*]] = extractvalue { float, float, i64 } {{%.*}}, 2
1580+
// CHECK: [[ERROR:%.*]] = extractvalue { ptr, float, float, i64, ptr } {{%.*}}, 4
1581+
// CHECK: store ptr [[ERROR]], ptr %swifterror, align 8
1582+
// CHECK: [[ERROR0:%.*]] = load ptr, ptr %swifterror, align 8
1583+
// CHECK: [[ISERROR:%.*]] = icmp ne ptr [[ERROR0]], null
1584+
// CHECK: br i1 [[ISERROR]], label %typed.error.load, label %[[SUCCESS:.*]]
1585+
// CHECK: typed.error.load:
1586+
// CHECK: br label %[[SET_ERROR:.*]]
1587+
// CHECK: [[SUCCESS]]:
1588+
// CHECK: [[SUCCESS_RES0:%.*]] = phi float [ [[CALL_RES0]], %entry ]
1589+
// CHECK: [[SUCCESS_RES1:%.*]] = phi float [ [[CALL_RES1]], %entry ]
1590+
// CHECK: br label %[[COMMON_RET:.*]]
1591+
// CHECK: [[COMMON_RET]]:
1592+
// CHECK: [[RETVAL0:%.*]] = phi i64 [ [[ERROR_RES0:%.*]], %[[SET_ERROR]] ], [ 1, %[[SUCCESS]] ]
1593+
// CHECK: [[RETVAL1:%.*]] = phi float [ 0.000000e+00, %[[SET_ERROR]] ], [ [[SUCCESS_RES0]], %[[SUCCESS]] ]
1594+
// CHECK: [[RETVAL2:%.*]] = phi float [ 0.000000e+00, %[[SET_ERROR]] ], [ [[SUCCESS_RES1]], %[[SUCCESS]] ]
1595+
// CHECK: %39 = call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr {{%.*}}, i1 false, ptr @"$s16typed_throws_abi24callNonMatching_f0_asyncySi_S2ftSbYaF.0.50", ptr {{%.*}}, ptr {{%.*}}, i64 [[RETVAL0]], float [[RETVAL1]], float [[RETVAL2]])
1596+
// CHECK: unreachable
1597+
// CHECK: [[SET_ERROR]]:
1598+
// CHECK: [[ERROR_RES0]] = phi i64 [ [[CALL_RES2]], %typed.error.load ]
1599+
// CHECK: store ptr null, ptr %swifterror, align 8
1600+
// CHECK: br label %[[COMMON_RET]]
1601+
// CHECK: }
1602+
@available(SwiftStdlib 6.0, *)
1603+
func callNonMatching_f0_async(_ b: Bool) async -> (Int, Float, Float) {
1604+
do {
1605+
let res = try await nonMatching_f0_async(b)
1606+
return (1, res.0, res.1)
1607+
} catch {
1608+
return (error.x, 0.0, 0.0)
1609+
}
1610+
}
1611+
1612+
// CHECK: define hidden swifttailcc void @"$s16typed_throws_abi20nonMatching_f1_asyncySf_SbSftSbYaAA7OneWordVYKF"(ptr swiftasync %0, i1 %1)
1613+
// CHECK: br i1 %1, label %[[SUCCESS:.*]], label %[[ERROR:.*]]
1614+
// CHECK: [[SUCCESS]]:
1615+
// CHECK: %17 = call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr {{%.*}}, i1 false, ptr @"$s16typed_throws_abi20nonMatching_f1_asyncySf_SbSftSbYaAA7OneWordVYKF.0.51", ptr {{%.*}}, ptr {{%.*}}, float 1.000000e+00, i64 1, float 2.000000e+00, ptr null)
1616+
// CHECK: unreachable
1617+
// CHECK: [[ERROR]]:
1618+
// CHECK: [[ERROR_X:%.*]] = load i64, ptr %.x1._value, align 8
1619+
// CHECK: [[ERROR_RET:%.*]] = insertvalue { float, i64, float } undef, i64 [[ERROR_X]], 1
1620+
// CHECK: [[ERROR_RET0:%.*]] = extractvalue { float, i64, float } [[ERROR_RET]], 0
1621+
// CHECK: [[ERROR_RET1:%.*]] = extractvalue { float, i64, float } [[ERROR_RET]], 1
1622+
// CHECK: [[ERROR_RET2:%.*]] = extractvalue { float, i64, float } [[ERROR_RET]], 2
1623+
// CHECK: call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr {{%.*}}, i1 false, ptr @"$s16typed_throws_abi20nonMatching_f1_asyncySf_SbSftSbYaAA7OneWordVYKF.0", ptr {{%.*}}, ptr {{%.*}}, float [[ERROR_RET0]], i64 [[ERROR_RET1]], float [[ERROR_RET2]], ptr inttoptr (i64 1 to ptr))
1624+
// CHECK: unreachable
1625+
// CHECK: }
1626+
@available(SwiftStdlib 6.0, *)
1627+
func nonMatching_f1_async(_ b: Bool) async throws(OneWord) -> (Float, Bool, Float) {
1628+
guard b else {
1629+
throw OneWord()
1630+
}
1631+
return (1.0, true, 2.0)
1632+
}
1633+
1634+
// CHECK: define hidden swifttailcc void @"$s16typed_throws_abi24callNonMatching_f1_asyncySi_SfSbSftSbYaF"(ptr swiftasync %0, i1 %1)
1635+
// CHECK: call { ptr, float, i64, float, ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0f32i64f32p0s(i32 1024, ptr {{%.*}}, ptr @__swift_async_resume_project_context, ptr @"$s16typed_throws_abi24callNonMatching_f1_asyncySi_SfSbSftSbYaF.0", ptr @"$s16typed_throws_abi20nonMatching_f1_asyncySf_SbSftSbYaAA7OneWordVYKF", ptr {{%.*}}, i1 %1)
1636+
// CHECK: [[CALL_RES0:%.*]] = extractvalue { float, i64, float } {{%.*}}, 0
1637+
// CHECK: [[CALL_RES1:%.*]] = extractvalue { float, i64, float } {{%.*}}, 1
1638+
// CHECK: [[CALL_RES2:%.*]] = extractvalue { float, i64, float } {{%.*}}, 2
1639+
// CHECK: [[CALL_RES1_TRUNC:%.*]] = trunc i64 [[CALL_RES1]] to i1
1640+
// CHECK: [[ERROR:%.*]] = extractvalue { ptr, float, i64, float, ptr } {{%.*}}, 4
1641+
// CHECK: store ptr [[ERROR]], ptr %swifterror, align 8
1642+
// CHECK: [[ERROR0:%.*]] = load ptr, ptr %swifterror, align 8
1643+
// CHECK: [[ISERROR:%.*]] = icmp ne ptr [[ERROR0]], null
1644+
// CHECK: br i1 [[ISERROR]], label %typed.error.load, label %[[SUCCESS:.*]]
1645+
// CHECK: typed.error.load:
1646+
// CHECK: br label %[[SET_ERROR:.*]]
1647+
// CHECK: [[SUCCESS]]:
1648+
// CHECK: [[SUCCESS_RES0:%.*]] = phi float [ [[CALL_RES0]], %entry ]
1649+
// CHECK: [[SUCCESS_RES1:%.*]] = phi i1 [ [[CALL_RES1_TRUNC]], %entry ]
1650+
// CHECK: [[SUCCESS_RES2:%.*]] = phi float [ [[CALL_RES2]], %entry ]
1651+
// CHECK: br label %[[COMMON_RET:.*]]
1652+
// CHECK: [[COMMON_RET]]:
1653+
// CHECK: [[RETVAL0:%.*]] = phi i64 [ [[ERROR_RES0:%.*]], %[[SET_ERROR]] ], [ 1, %[[SUCCESS]] ]
1654+
// CHECK: [[RETVAL1:%.*]] = phi float [ 0.000000e+00, %[[SET_ERROR]] ], [ [[SUCCESS_RES0]], %[[SUCCESS]] ]
1655+
// CHECK: [[RETVAL2:%.*]] = phi i1 [ false, %[[SET_ERROR]] ], [ [[SUCCESS_RES1]], %[[SUCCESS]] ]
1656+
// CHECK: [[RETVAL3:%.*]] = phi float [ 0.000000e+00, %[[SET_ERROR]] ], [ [[SUCCESS_RES2]], %[[SUCCESS]] ]
1657+
// CHECK: %43 = call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr {{%.*}}, i1 false, ptr @"$s16typed_throws_abi24callNonMatching_f1_asyncySi_SfSbSftSbYaF.0.52", ptr {{%.*}}, ptr {{%.*}}, i64 [[RETVAL0]], float [[RETVAL1]], i1 [[RETVAL2]], float [[RETVAL3]])
1658+
// CHECK: unreachable
1659+
// CHECK: [[SET_ERROR]]:
1660+
// CHECK: [[ERROR_RES0]] = phi i64 [ [[CALL_RES1]], %typed.error.load ]
1661+
// CHECK: store ptr null, ptr %swifterror, align 8
1662+
// CHECK: br label %[[COMMON_RET]]
1663+
// CHECK: }
1664+
@available(SwiftStdlib 6.0, *)
1665+
func callNonMatching_f1_async(_ b: Bool) async -> (Int, Float, Bool, Float) {
1666+
do {
1667+
let res = try await nonMatching_f1_async(b)
1668+
return (1, res.0, res.1, res.2)
1669+
} catch {
1670+
return (error.x, 0.0, false, 0.0)
1671+
}
1672+
}
1673+
15521674
protocol P {
15531675
// CHECK: define hidden swiftcc void @"$s16typed_throws_abi1PP2f0yySbAA5EmptyVYKFTj"(i1 %0, ptr noalias swiftself %1, ptr noalias nocapture swifterror dereferenceable(8) %2, ptr %3, ptr %4)
15541676
// CHECK: [[ERROR:%.*]] = load ptr, ptr %2

0 commit comments

Comments
 (0)