Files
swift-mirror/test/IRGen/async-inheritance.swift
Saleem Abdulrasool 68bc33fed3 IRGen: initial pass to support async inheritance on Windows
With PE/COFF, one cannot reference a data symbol directly across the
binary module boundary.  Instead, the reference must be indirected
through the Import Address Table (IAT) to allow for position
independence.

When generating a reference to a AsyncFunctionPointer ({i8*, i32}), we
tag the pointer as being indirected by tagging bit 1 (with the
assumption that native alignment will ensure 4/8 byte alignment, freeing
the bottom 2 bits at least for bit-packing).  We tweak the
v-table/witness table emission such that all references to the
AsyncFunctionPointer are replaced with the linker synthetic import
symbol with the bit packing:

~~~
.quad __imp_$s1L1CC1yyYaKFTu+1
~~~

rather than

~~~
.quad $s1L1CC1yyYaKFTu
~~~

Upon access of the async function pointer reference, we open-code the
check for the following:

~~~
pointer = (pointer & 1) ? *(void **)(pointer & ~1) : pointer;
~~~

Thanks to @DougGregor for the discussion and the suggestion for the
pointer tagging.  Thanks to @aschwaighofer for pointers to the code that
I had missed.  Also, thanks to @SeanROlszewski for the original code
sample that led to the reduced test case.

Fixes: SR-15399
2021-11-01 11:23:51 -07:00

28 lines
590 B
Swift

// RUN: %empty-directory(%t)
// RUN: %target-build-swift-dylib(%t/%target-library-name(L)) -module-name L -emit-module -emit-module-path %t/L.swiftmodule %s -DL
// RUN: %target-build-swift -I%t -L%t -lL -parse-as-library %s -module-name E -o %t/E %target-rpath(%t)
// RUN: %target-codesign %t/E
// RUN: %target-run %t/E %t/%target-library-name(L) | %FileCheck %s
#if L
open class C {
public init() {}
open func f() async {
print("\(#function)")
}
}
#else
import L
class D: C {
}
@main
struct S {
public static func main() async {
await D().f()
}
}
#endif
// CHECK: f()