Skip to content

Commit 98e732d

Browse files
committed
[Async CC] Pass witness metadata to callees.
Previously, the WitnessMetadata values that were collected were just ignored when making a function call, although space was reserved for them in the async context. Here, that error is corrected by actually storing them into the async context if they are present.
1 parent d2726c3 commit 98e732d

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2449,6 +2449,18 @@ class AsyncCallEmission final : public CallEmission {
24492449
auto fieldLayout = layout.getLocalContextLayout();
24502450
saveValue(fieldLayout, localExplosion, isOutlined);
24512451
}
2452+
if (auto selfMetadata = witnessMetadata->SelfMetadata) {
2453+
Explosion selfMetadataExplosion;
2454+
selfMetadataExplosion.add(selfMetadata);
2455+
auto fieldLayout = layout.getSelfMetadataLayout();
2456+
saveValue(fieldLayout, selfMetadataExplosion, isOutlined);
2457+
}
2458+
if (auto selfWitnessTable = witnessMetadata->SelfWitnessTable) {
2459+
Explosion selfWitnessTableExplosion;
2460+
selfWitnessTableExplosion.add(selfWitnessTable);
2461+
auto fieldLayout = layout.getSelfWitnessTableLayout();
2462+
saveValue(fieldLayout, selfWitnessTableExplosion, isOutlined);
2463+
}
24522464
}
24532465
void emitCallToUnmappedExplosion(llvm::CallInst *call, Explosion &out) override {
24542466
auto layout = getAsyncContextLayout();
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift -Xfrontend -enable-experimental-concurrency %s -emit-ir | %FileCheck %s --check-prefix=CHECK-LL
3+
// RUN: %target-build-swift -Xfrontend -enable-experimental-concurrency %s -module-name main -o %t/main
4+
// RUN: %target-codesign %t/main
5+
// RUN: %target-run %t/main | %FileCheck %s
6+
7+
// REQUIRES: executable_test
8+
// REQUIRES: swift_test_mode_optimize_none
9+
// REQUIRES: concurrency
10+
// UNSUPPORTED: use_os_stdlib
11+
12+
import _Concurrency
13+
14+
func printGeneric<T>(_ t: T) {
15+
print(t)
16+
}
17+
18+
protocol P {
19+
func f() async
20+
}
21+
22+
// CHECK: entering call_f
23+
// CHECK: entering f
24+
// CHECK: X
25+
// CHECK: main.X
26+
// CHECK: exiting f
27+
// CHECK: exiting call_f
28+
29+
// CHECK-LL: @"$s4main1PPAAE1fyyYFTu" = hidden global %swift.async_func_pointer
30+
// CHECK-LL: @"$s4main6call_fyyxYAA1PRzlFTu" = hidden global %swift.async_func_pointer
31+
// CHECK-LL: @"$s4main1XCAA1PA2aDP1fyyYFTWTu" = internal global %swift.async_func_pointer
32+
33+
extension P {
34+
// CHECK-LL: define hidden swiftcc void @"$s4main1PPAAE1fyyYF"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} {
35+
func f() async {
36+
print("entering f")
37+
printGeneric(Self.self)
38+
printGeneric(self)
39+
print("exiting f")
40+
}
41+
}
42+
43+
// CHECK-LL: define internal swiftcc void @"$s4main1XCAA1PA2aDP1fyyYFTW"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} {
44+
extension X : P {}
45+
46+
// CHECK-LL: define hidden swiftcc void @"$s4main6call_fyyxYAA1PRzlF"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} {
47+
func call_f<T : P>(_ t: T) async {
48+
print("entering call_f")
49+
await t.f()
50+
print("exiting call_f")
51+
}
52+
53+
class X {}
54+
55+
runAsyncAndBlock {
56+
let x = X()
57+
await call_f(x)
58+
}

0 commit comments

Comments
 (0)