IRGen: fix async vtable stubs

For deleted async vtable methods we need to create a async function pointer.

Fixes a missing-symbol linker error
rdar://108924001
This commit is contained in:
Erik Eckstein
2023-05-15 22:47:09 +02:00
parent cb51359adb
commit 82b24ba165
4 changed files with 118 additions and 28 deletions

View File

@@ -2103,8 +2103,20 @@ void IRGenModule::emitVTableStubs() {
}
// For each eliminated method symbol create an alias to the stub.
auto *alias = llvm::GlobalAlias::create(llvm::GlobalValue::ExternalLinkage,
F.getName(), stub);
llvm::GlobalValue *alias = nullptr;
if (F.isAsync()) {
// TODO: We cannot directly create a pointer to `swift_deletedAsyncMethodError`
// to workaround a linker crash.
// Instead use the stub, which calls swift_deletedMethodError. This works because
// swift_deletedMethodError takes no parameters and simply aborts the program.
auto asyncLayout = getAsyncContextLayout(*this, const_cast<SILFunction *>(&F));
auto entity = LinkEntity::forSILFunction(const_cast<SILFunction *>(&F));
auto *fnPtr = emitAsyncFunctionPointer(*this, stub, entity, asyncLayout.getSize());
alias = fnPtr;
} else {
alias = llvm::GlobalAlias::create(llvm::GlobalValue::ExternalLinkage,
F.getName(), stub);
}
if (F.getEffectiveSymbolLinkage() == SILLinkage::Hidden)
alias->setVisibility(llvm::GlobalValue::HiddenVisibility);