Skip to content

Commit a4f13dc

Browse files
authored
Merge pull request swiftlang#79370 from drexin/wip-144719032-6.1
[6.1][IRGen] Apply correct type to conversion for direct values and erorrs…
2 parents 7180350 + f343db5 commit a4f13dc

File tree

3 files changed

+85
-7
lines changed

3 files changed

+85
-7
lines changed

lib/IRGen/GenCall.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -4541,8 +4541,8 @@ void CallEmission::emitToUnmappedExplosionWithDirectTypedError(
45414541

45424542
Explosion errorExplosion;
45434543
if (!errorSchema.empty()) {
4544-
if (auto *structTy =
4545-
dyn_cast<llvm::StructType>(errorSchema.getExpandedType(IGF.IGM))) {
4544+
auto *expandedType = errorSchema.getExpandedType(IGF.IGM);
4545+
if (auto *structTy = dyn_cast<llvm::StructType>(expandedType)) {
45464546
for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) {
45474547
llvm::Value *elt = values[combined.errorValueMapping[i]];
45484548
auto *nativeTy = structTy->getElementType(i);
@@ -4552,7 +4552,7 @@ void CallEmission::emitToUnmappedExplosionWithDirectTypedError(
45524552
} else {
45534553
auto *converted =
45544554
convertForDirectError(IGF, values[combined.errorValueMapping[0]],
4555-
combined.combinedTy, /*forExtraction*/ true);
4555+
expandedType, /*forExtraction*/ true);
45564556
errorExplosion.add(converted);
45574557
}
45584558

@@ -4565,17 +4565,17 @@ void CallEmission::emitToUnmappedExplosionWithDirectTypedError(
45654565
// If the regular result type is void, there is nothing to explode
45664566
if (!nativeSchema.empty()) {
45674567
Explosion resultExplosion;
4568-
if (auto *structTy =
4569-
dyn_cast<llvm::StructType>(nativeSchema.getExpandedType(IGF.IGM))) {
4568+
auto *expandedType = nativeSchema.getExpandedType(IGF.IGM);
4569+
if (auto *structTy = dyn_cast<llvm::StructType>(expandedType)) {
45704570
for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) {
45714571
auto *nativeTy = structTy->getElementType(i);
45724572
auto *converted = convertForDirectError(IGF, values[i], nativeTy,
45734573
/*forExtraction*/ true);
45744574
resultExplosion.add(converted);
45754575
}
45764576
} else {
4577-
auto *converted = convertForDirectError(
4578-
IGF, values[0], combined.combinedTy, /*forExtraction*/ true);
4577+
auto *converted = convertForDirectError(IGF, values[0], expandedType,
4578+
/*forExtraction*/ true);
45794579
resultExplosion.add(converted);
45804580
}
45814581
out = nativeSchema.mapFromNative(IGF.IGM, IGF, resultExplosion, resultType);

test/IRGen/typed_throws.swift

+39
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,42 @@ func callAsyncIndirectResult<A>(p: any AsyncGenProto<A>, x: Int) async throws(Sm
310310
return try await p.fn(arg: x)
311311
}
312312

313+
@inline(never)
314+
func smallResultLargerError() throws(SmallError) -> Int8? {
315+
return 10
316+
}
317+
318+
// CHECK: [[COERCED:%.*]] = alloca { i16 }, align 2
319+
// CHECK: [[RES:%.*]] = call swiftcc i64 @"$s12typed_throws22smallResultLargerErrors4Int8VSgyAA05SmallF0VYKF"(ptr swiftself undef, ptr noalias nocapture swifterror dereferenceable(8) %swifterror)
320+
// CHECK: [[TRUNC:%.*]] = trunc i64 [[RES]] to i16
321+
// CHECK: [[COERCED_PTR:%.*]] = getelementptr inbounds { i16 }, ptr [[COERCED]], i32 0, i32 0
322+
// CHECK: store i16 [[TRUNC]], ptr [[COERCED_PTR]], align 2
323+
func callSmallResultLargerError() {
324+
let res = try! smallResultLargerError()
325+
precondition(res! == 10)
326+
}
327+
328+
enum UInt8OptSingletonError: Error {
329+
case a(Int8?)
330+
}
331+
332+
@inline(never)
333+
func smallErrorLargerResult() throws(UInt8OptSingletonError) -> Int {
334+
throw .a(10)
335+
}
336+
337+
// CHECK: [[COERCED:%.*]] = alloca { i16 }, align 2
338+
// CHECK: [[RES:%.*]] = call swiftcc i64 @"$s12typed_throws22smallErrorLargerResultSiyAA017UInt8OptSingletonD0OYKF"(ptr swiftself undef, ptr noalias nocapture swifterror dereferenceable(8) %swifterror)
339+
// CHECK: [[TRUNC:%.*]] = trunc i64 [[RES]] to i16
340+
// CHECK: [[COERCED_PTR:%.*]] = getelementptr inbounds { i16 }, ptr [[COERCED]], i32 0, i32 0
341+
// CHECK: store i16 [[TRUNC]], ptr [[COERCED_PTR]], align 2
342+
func callSmallErrorLargerResult() {
343+
do {
344+
_ = try smallErrorLargerResult()
345+
} catch {
346+
switch error {
347+
case .a(let x):
348+
precondition(x! == 10)
349+
}
350+
}
351+
}

test/Interpreter/typed_throws_abi.swift

+39
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,40 @@ func checkAsync() async {
284284
await invoke { try await impl.nonMatching_f1(false) }
285285
}
286286

287+
enum SmallError: Error {
288+
case a(Int)
289+
}
290+
291+
@inline(never)
292+
func smallResultLargerError() throws(SmallError) -> Int8? {
293+
return 10
294+
}
295+
296+
func callSmallResultLargerError() {
297+
let res = try! smallResultLargerError()
298+
print("Result is: \(String(describing: res))")
299+
}
300+
301+
enum UInt8OptSingletonError: Error {
302+
case a(Int8?)
303+
}
304+
305+
@inline(never)
306+
func smallErrorLargerResult() throws(UInt8OptSingletonError) -> Int {
307+
throw .a(10)
308+
}
309+
310+
func callSmallErrorLargerResult() {
311+
do {
312+
_ = try smallErrorLargerResult()
313+
} catch {
314+
switch error {
315+
case .a(let x):
316+
print("Error value is: \(String(describing: x))")
317+
}
318+
}
319+
}
320+
287321
enum MyError: Error {
288322
case x
289323
case y
@@ -314,5 +348,10 @@ public struct Main {
314348
await checkAsync()
315349
// CHECK: Arg is 10
316350
print(try! await callAsyncIndirectResult(p: AsyncGenProtoImpl(), x: 10))
351+
352+
// CHECK: Result is: Optional(10)
353+
callSmallResultLargerError()
354+
// CHECK: Error value is: Optional(10)
355+
callSmallErrorLargerResult()
317356
}
318357
}

0 commit comments

Comments
 (0)