Skip to content

Commit 9acc21e

Browse files
committed
[5.8] IRGen: Don't directly call async functions that have weak/linkonce_odr linkage
The async function pointer context size and the async function implementiation are logically tied. Using a different async context pointer context size and async function implementation (from different translation units) is problematic. rdar://106029807 Original PR: #64638 Fixes an issue when linking static libraries/object files from different TU with the same async function pointer name put different context values.
1 parent 2d01578 commit 9acc21e

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

lib/IRGen/IRGenSIL.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2664,6 +2664,18 @@ FunctionPointer::Kind irgen::classifyFunctionPointerKind(SILFunction *fn) {
26642664

26652665
return fn->getLoweredFunctionType();
26662666
}
2667+
// Async functions that end up with weak_odr or linkonce_odr linkage may not be
2668+
// directly called because we need to preserve the connection between the
2669+
// function's implementation and the function's context size in the async
2670+
// function pointer data structure.
2671+
static bool mayDirectlyCallAsync(SILFunction *fn) {
2672+
if (fn->getLinkage() == SILLinkage::Shared ||
2673+
fn->getLinkage() == SILLinkage::PublicNonABI) {
2674+
return false;
2675+
}
2676+
2677+
return true;
2678+
}
26672679

26682680
void IRGenSILFunction::visitFunctionRefBaseInst(FunctionRefBaseInst *i) {
26692681
auto fn = i->getInitiallyReferencedFunction();
@@ -2690,7 +2702,8 @@ void IRGenSILFunction::visitFunctionRefBaseInst(FunctionRefBaseInst *i) {
26902702
if (fpKind.isAsyncFunctionPointer()) {
26912703
value = IGM.getAddrOfAsyncFunctionPointer(fn);
26922704
value = llvm::ConstantExpr::getBitCast(value, fnPtr->getType());
2693-
secondaryValue = IGM.getAddrOfSILFunction(fn, NotForDefinition);
2705+
secondaryValue = mayDirectlyCallAsync(fn) ?
2706+
IGM.getAddrOfSILFunction(fn, NotForDefinition) : nullptr;
26942707

26952708
// For ordinary sync functions and special async functions, produce
26962709
// only the direct address of the function. The runtime does not

0 commit comments

Comments
 (0)