Skip to content

Commit cff0585

Browse files
committed
[Test] Add test for sync 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 06a9e9f commit cff0585

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

test/IRGen/typed_throws_abi.swift

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,6 +1436,119 @@ func callImplAsync_g5(_ impl: ImplAsync, _ b: Bool) async -> (Int, Int, Int, Int
14361436
}
14371437
}
14381438

1439+
// CHECK: define hidden swiftcc { float, float, i64 } @"$s16typed_throws_abi14nonMatching_f0ySf_SftSbAA7OneWordVYKF"(i1 %0, ptr swiftself %1, ptr noalias nocapture swifterror dereferenceable(8) %2)
1440+
// CHECK: br i1 %0, label %[[SUCCESS:.*]], label %[[FAIL:.*]]
1441+
// CHECK: [[SUCCESS]]:
1442+
// CHECK: ret { float, float, i64 } { float 1.000000e+00, float 2.000000e+00, i64 undef }
1443+
// CHECK: [[FAIL]]:
1444+
// CHECK: [[ERROR_RES0:%.*]] = load i64, ptr %.x1._value, align 8
1445+
// CHECK: store ptr inttoptr (i64 1 to ptr), ptr %2, align 8
1446+
// CHECK: [[ERROR_RES:%.*]] = insertvalue { float, float, i64 } undef, i64 [[ERROR_RES0]], 2
1447+
// CHECK: ret { float, float, i64 } [[ERROR_RES]]
1448+
// CHECK: }
1449+
func nonMatching_f0(_ b: Bool) throws(OneWord) -> (Float, Float) {
1450+
guard b else {
1451+
throw OneWord()
1452+
}
1453+
return (1.0, 2.0)
1454+
}
1455+
1456+
// CHECK: define hidden swiftcc { i64, float, float } @"$s16typed_throws_abi18callNonMatching_f0ySi_S2ftSbF"(i1 %0)
1457+
// CHECK: %swifterror = alloca swifterror ptr, align 8
1458+
// CHECK: store ptr null, ptr %swifterror, align 8
1459+
// CHECK: [[CALL_RES:%.*]] = call swiftcc { float, float, i64 } @"$s16typed_throws_abi14nonMatching_f0ySf_SftSbAA7OneWordVYKF"(i1 %0, ptr swiftself undef, ptr noalias nocapture swifterror dereferenceable(8) %swifterror)
1460+
// CHECK: [[CALL_RES0:%.*]] = extractvalue { float, float, i64 } [[CALL_RES]], 0
1461+
// CHECK: [[CALL_RES1:%.*]] = extractvalue { float, float, i64 } [[CALL_RES]], 1
1462+
// CHECK: [[CALL_RES2:%.*]] = extractvalue { float, float, i64 } [[CALL_RES]], 2
1463+
// CHECK: [[ERROR:%.*]] = load ptr, ptr %swifterror, align 8
1464+
// CHECK: [[ISERROR:%.*]] = icmp ne ptr [[ERROR]], null
1465+
// CHECK: br i1 [[ISERROR]], label %typed.error.load, label %[[SUCCESS:.*]]
1466+
// CHECK: typed.error.load:
1467+
// CHECK: br label %[[SET_ERROR:.*]]
1468+
// CHECK: [[SUCCESS]]:
1469+
// CHECK: [[SUCCESS_RES0:%.*]] = phi float [ [[CALL_RES0]], %entry ]
1470+
// CHECK: [[SUCCESS_RES1:%.*]] = phi float [ [[CALL_RES1]], %entry ]
1471+
// CHECK: br label %[[COMMON_RET:.*]]
1472+
// CHECK: [[COMMON_RET]]:
1473+
// CHECK: [[RETVAL0:%.*]] = phi i64 [ [[ERROR_RES0:%.*]], %[[SET_ERROR]] ], [ 1, %[[SUCCESS]] ]
1474+
// CHECK: [[RETVAL1:%.*]] = phi float [ 0.000000e+00, %[[SET_ERROR]] ], [ [[SUCCESS_RES0]], %[[SUCCESS]] ]
1475+
// CHECK: [[RETVAL2:%.*]] = phi float [ 0.000000e+00, %[[SET_ERROR]] ], [ [[SUCCESS_RES1]], %[[SUCCESS]] ]
1476+
// CHECK: [[RETVAL3:%.*]] = insertvalue { i64, float, float } undef, i64 [[RETVAL0]], 0
1477+
// CHECK: [[RETVAL4:%.*]] = insertvalue { i64, float, float } [[RETVAL3]], float [[RETVAL1]], 1
1478+
// CHECK: [[RETVAL:%.*]] = insertvalue { i64, float, float } [[RETVAL4]], float [[RETVAL2]], 2
1479+
// CHECK: ret { i64, float, float } [[RETVAL]]
1480+
// CHECK: [[SET_ERROR]]:
1481+
// CHECK: [[ERROR_RES0]] = phi i64 [ [[CALL_RES2]], %typed.error.load ]
1482+
// CHECK: store ptr null, ptr %swifterror, align 8
1483+
// CHECK: br label %[[COMMON_RET]]
1484+
// CHECK: }
1485+
func callNonMatching_f0(_ b: Bool) -> (Int, Float, Float) {
1486+
do {
1487+
let res = try nonMatching_f0(b)
1488+
return (1, res.0, res.1)
1489+
} catch {
1490+
return (error.x, 0.0, 0.0)
1491+
}
1492+
}
1493+
1494+
// define hidden swiftcc { float, i64, float } @"$s16typed_throws_abi14nonMatching_f1ySf_SbSftSbAA7OneWordVYKF"(i1 %0, ptr swiftself %1, ptr noalias nocapture swifterror dereferenceable(8) %2)
1495+
// CHECK: br i1 %0, label %[[SUCCESS:.*]], label %[[FAIL:.*]]
1496+
// CHECK: [[SUCCESS]]:
1497+
// CHECK: ret { float, i64, float } { float 1.000000e+00, i64 1, float 2.000000e+00 }
1498+
// CHECK: [[FAIL]]:
1499+
// CHECK: [[ERROR_RES0:%.*]] = load i64, ptr %.x1._value, align 8
1500+
// CHECK: store ptr inttoptr (i64 1 to ptr), ptr %2, align 8
1501+
// CHECK: [[ERROR_RES:%.*]] = insertvalue { float, i64, float } undef, i64 [[ERROR_RES0]], 1
1502+
// CHECK: ret { float, i64, float } [[ERROR_RES]]
1503+
// }
1504+
func nonMatching_f1(_ b: Bool) throws(OneWord) -> (Float, Bool, Float) {
1505+
guard b else {
1506+
throw OneWord()
1507+
}
1508+
return (1.0, true, 2.0)
1509+
}
1510+
1511+
// CHECK: define hidden swiftcc { i64, float, i1, float } @"$s16typed_throws_abi18callNonMatching_f1ySi_SfSbSftSbF"(i1 %0)
1512+
// CHECK: %swifterror = alloca swifterror ptr, align 8
1513+
// CHECK: [[CALL_RES:%.*]] = call swiftcc { float, i64, float } @"$s16typed_throws_abi14nonMatching_f1ySf_SbSftSbAA7OneWordVYKF"(i1 %0, ptr swiftself undef, ptr noalias nocapture swifterror dereferenceable(8) %swifterror)
1514+
// CHECK: [[CALL_RES0:%.*]] = extractvalue { float, i64, float } [[CALL_RES]], 0
1515+
// CHECK: [[CALL_RES1:%.*]] = extractvalue { float, i64, float } [[CALL_RES]], 1
1516+
// CHECK: [[CALL_RES2:%.*]] = extractvalue { float, i64, float } [[CALL_RES]], 2
1517+
// CHECK: [[CALL_RES1_TRUNC:%.*]] = trunc i64 [[CALL_RES1]] to i1
1518+
// CHECK: [[ERROR:%.*]] = load ptr, ptr %swifterror, align 8
1519+
// CHECK: [[ISERROR:%.*]] = icmp ne ptr [[ERROR]], null
1520+
// CHECK: br i1 [[ISERROR]], label %typed.error.load, label %[[SUCCESS:.*]]
1521+
// CHECK: typed.error.load:
1522+
// CHECK: br label %[[SET_ERROR:.*]]
1523+
// CHECK: [[SUCCESS]]:
1524+
// CHECK: [[SUCCESS_RES0:%.*]] = phi float [ [[CALL_RES0]], %entry ]
1525+
// CHECK: [[SUCCESS_RES1:%.*]] = phi i1 [ [[CALL_RES1_TRUNC]], %entry ]
1526+
// CHECK: [[SUCCESS_RES2:%.*]] = phi float [ [[CALL_RES2]], %entry ]
1527+
// CHECK: br label %[[COMMON_RET:.*]]
1528+
// CHECK: [[COMMON_RET]]:
1529+
// CHECK: [[RETVAL0:%.*]] = phi i64 [ [[ERROR_RES0:%.*]], %[[SET_ERROR]] ], [ 1, %[[SUCCESS]] ]
1530+
// CHECK: [[RETVAL1:%.*]] = phi float [ 0.000000e+00, %[[SET_ERROR]] ], [ [[SUCCESS_RES0]], %[[SUCCESS]] ]
1531+
// CHECK: [[RETVAL2:%.*]] = phi i1 [ false, %[[SET_ERROR]] ], [ [[SUCCESS_RES1]], %[[SUCCESS]] ]
1532+
// CHECK: [[RETVAL3:%.*]] = phi float [ 0.000000e+00, %[[SET_ERROR]] ], [ [[SUCCESS_RES2]], %[[SUCCESS]] ]
1533+
// CHECK: [[RETVAL4:%.*]] = insertvalue { i64, float, i1, float } undef, i64 [[RETVAL0]], 0
1534+
// CHECK: [[RETVAL5:%.*]] = insertvalue { i64, float, i1, float } [[RETVAL4]], float [[RETVAL1]], 1
1535+
// CHECK: [[RETVAL6:%.*]] = insertvalue { i64, float, i1, float } [[RETVAL5]], i1 [[RETVAL2]], 2
1536+
// CHECK: [[RETVAL:%.*]] = insertvalue { i64, float, i1, float } [[RETVAL6]], float [[RETVAL3]], 3
1537+
// CHECK: ret { i64, float, i1, float } [[RETVAL]]
1538+
// CHECK: [[SET_ERROR]]:
1539+
// CHECK: [[ERROR_RES0]] = phi i64 [ [[CALL_RES1]], %typed.error.load ]
1540+
// CHECK: store ptr null, ptr %swifterror, align 8
1541+
// CHECK: br label %[[COMMON_RET]]
1542+
// CHECK: }
1543+
func callNonMatching_f1(_ b: Bool) -> (Int, Float, Bool, Float) {
1544+
do {
1545+
let res = try nonMatching_f1(b)
1546+
return (1, res.0, res.1, res.2)
1547+
} catch {
1548+
return (error.x, 0.0, false, 0.0)
1549+
}
1550+
}
1551+
14391552
protocol P {
14401553
// 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)
14411554
// CHECK: [[ERROR:%.*]] = load ptr, ptr %2

0 commit comments

Comments
 (0)