Skip to content

Commit 287e779

Browse files
committed
[IRGen] Map result to native representation in emitAsyncReturn
rdar://147872231 When an async typed throwing function had a result type that combined multiple fields into a single register, we created invalid IR, that could lead to compiler crashes or in some cases even miscompiles. With this fix we are mapping the result to the native representation before mapping it to the combined result type.
1 parent fc16f3f commit 287e779

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6653,10 +6653,12 @@ void irgen::emitAsyncReturn(IRGenFunction &IGF, AsyncContextLayout &asyncLayout,
66536653
if (combinedTy->isVoidTy()) {
66546654
assert(result.empty() && "Unexpected result values");
66556655
} else {
6656+
Explosion native = nativeSchema.mapIntoNative(
6657+
IGM, IGF, result, funcResultTypeInContext, /*isOutlined*/ false);
66566658
if (auto *structTy = dyn_cast<llvm::StructType>(combinedTy)) {
66576659
llvm::Value *nativeAgg = llvm::UndefValue::get(structTy);
6658-
for (unsigned i = 0, e = result.size(); i < e; ++i) {
6659-
llvm::Value *elt = result.claimNext();
6660+
for (unsigned i = 0, e = native.size(); i < e; ++i) {
6661+
llvm::Value *elt = native.claimNext();
66606662
auto *nativeTy = structTy->getElementType(i);
66616663
elt = convertForDirectError(IGF, elt, nativeTy,
66626664
/*forExtraction*/ false);
@@ -6667,9 +6669,9 @@ void irgen::emitAsyncReturn(IRGenFunction &IGF, AsyncContextLayout &asyncLayout,
66676669
while (!out.empty()) {
66686670
nativeResultsStorage.push_back(out.claimNext());
66696671
}
6670-
} else if (!result.empty()) {
6672+
} else if (!native.empty()) {
66716673
auto *converted = convertForDirectError(
6672-
IGF, result.claimNext(), combinedTy, /*forExtraction*/ false);
6674+
IGF, native.claimNext(), combinedTy, /*forExtraction*/ false);
66736675
nativeResultsStorage.push_back(converted);
66746676
} else {
66756677
nativeResultsStorage.push_back(llvm::UndefValue::get(combinedTy));

test/IRGen/typed_throws.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,3 +349,13 @@ func callSmallErrorLargerResult() {
349349
}
350350
}
351351
}
352+
353+
struct SomeStruct {
354+
let x: Int
355+
let y: UInt32
356+
let z: UInt32
357+
}
358+
359+
func someFunc() async throws(SmallError) -> SomeStruct {
360+
SomeStruct(x: 42, y: 23, z: 25)
361+
}

0 commit comments

Comments
 (0)