Skip to content

Commit 04f6d99

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 0414cb2 commit 04f6d99

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

lib/IRGen/GenCall.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -6346,10 +6346,12 @@ void irgen::emitAsyncReturn(IRGenFunction &IGF, AsyncContextLayout &asyncLayout,
63466346
if (combinedTy->isVoidTy()) {
63476347
assert(result.empty() && "Unexpected result values");
63486348
} else {
6349+
Explosion native = nativeSchema.mapIntoNative(
6350+
IGM, IGF, result, funcResultTypeInContext, /*isOutlined*/ false);
63496351
if (auto *structTy = dyn_cast<llvm::StructType>(combinedTy)) {
63506352
llvm::Value *nativeAgg = llvm::UndefValue::get(structTy);
6351-
for (unsigned i = 0, e = result.size(); i < e; ++i) {
6352-
llvm::Value *elt = result.claimNext();
6353+
for (unsigned i = 0, e = native.size(); i < e; ++i) {
6354+
llvm::Value *elt = native.claimNext();
63536355
auto *nativeTy = structTy->getElementType(i);
63546356
elt = convertForDirectError(IGF, elt, nativeTy,
63556357
/*forExtraction*/ false);
@@ -6360,9 +6362,9 @@ void irgen::emitAsyncReturn(IRGenFunction &IGF, AsyncContextLayout &asyncLayout,
63606362
while (!out.empty()) {
63616363
nativeResultsStorage.push_back(out.claimNext());
63626364
}
6363-
} else if (!result.empty()) {
6365+
} else if (!native.empty()) {
63646366
auto *converted = convertForDirectError(
6365-
IGF, result.claimNext(), combinedTy, /*forExtraction*/ false);
6367+
IGF, native.claimNext(), combinedTy, /*forExtraction*/ false);
63666368
nativeResultsStorage.push_back(converted);
63676369
} else {
63686370
nativeResultsStorage.push_back(llvm::UndefValue::get(combinedTy));

test/IRGen/typed_throws.swift

+10
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)