Skip to content

Commit 0472ad1

Browse files
committed
Avoid illegal function pointer operation for async funcs [Authored by @kateinoigakukun]
If function pointer is a direct pointer to a function, it could not be an async function pointer. And additive operation to function address is illegal on some archs like wasm32, so emit undefs instead.
1 parent 7c0cb4b commit 0472ad1

File tree

1 file changed

+34
-19
lines changed

1 file changed

+34
-19
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1956,27 +1956,42 @@ std::pair<llvm::Value *, llvm::Value *> irgen::getAsyncFunctionAndSize(
19561956
{ // thin
19571957
IGF.Builder.emitBlock(thinBlock);
19581958
auto *ptr = functionPointer.getRawPointer();
1959-
if (auto authInfo = functionPointer.getAuthInfo()) {
1960-
ptr = emitPointerAuthAuth(IGF, ptr, authInfo);
1961-
}
1962-
auto *afpPtr =
1963-
IGF.Builder.CreateBitCast(ptr, IGF.IGM.AsyncFunctionPointerPtrTy);
1964-
if (emitFunction) {
1965-
llvm::Value *addrPtr = IGF.Builder.CreateStructGEP(afpPtr, 0);
1966-
auto *uncastFnPtr = IGF.emitLoadOfRelativePointer(
1967-
Address(addrPtr, IGF.IGM.getPointerAlignment()), /*isFar*/ false,
1968-
/*expectedType*/ functionPointer.getFunctionType()->getPointerTo());
1969-
auto *fnPtr = IGF.Builder.CreateBitCast(uncastFnPtr, IGF.IGM.Int8PtrTy);
1959+
1960+
// If function pointer is a direct pointer to a function, it could not be
1961+
// an async function pointer. And additive operation to function address is
1962+
// illegal on some archs like wasm32, so emit undefs instead.
1963+
if (isa<llvm::Function>(ptr)) {
1964+
if (emitFunction) {
1965+
auto *undef = llvm::UndefValue::get(IGF.IGM.Int8PtrTy);
1966+
fnPhiValues.push_back({thinBlock, undef});
1967+
}
1968+
if (emitSize) {
1969+
auto *undef = llvm::UndefValue::get(IGF.IGM.Int32Ty);
1970+
sizePhiValues.push_back({thinBlock, undef});
1971+
}
1972+
} else {
19701973
if (auto authInfo = functionPointer.getAuthInfo()) {
1971-
fnPtr = emitPointerAuthSign(IGF, fnPtr, authInfo);
1974+
ptr = emitPointerAuthAuth(IGF, ptr, authInfo);
1975+
}
1976+
auto *afpPtr =
1977+
IGF.Builder.CreateBitCast(ptr, IGF.IGM.AsyncFunctionPointerPtrTy);
1978+
if (emitFunction) {
1979+
llvm::Value *addrPtr = IGF.Builder.CreateStructGEP(afpPtr, 0);
1980+
auto *uncastFnPtr = IGF.emitLoadOfRelativePointer(
1981+
Address(addrPtr, IGF.IGM.getPointerAlignment()), /*isFar*/ false,
1982+
/*expectedType*/ functionPointer.getFunctionType()->getPointerTo());
1983+
auto *fnPtr = IGF.Builder.CreateBitCast(uncastFnPtr, IGF.IGM.Int8PtrTy);
1984+
if (auto authInfo = functionPointer.getAuthInfo()) {
1985+
fnPtr = emitPointerAuthSign(IGF, fnPtr, authInfo);
1986+
}
1987+
fnPhiValues.push_back({thinBlock, fnPtr});
1988+
}
1989+
if (emitSize) {
1990+
auto *sizePtr = IGF.Builder.CreateStructGEP(afpPtr, 1);
1991+
auto *size =
1992+
IGF.Builder.CreateLoad(sizePtr, IGF.IGM.getPointerAlignment());
1993+
sizePhiValues.push_back({thinBlock, size});
19721994
}
1973-
fnPhiValues.push_back({thinBlock, fnPtr});
1974-
}
1975-
if (emitSize) {
1976-
auto *sizePtr = IGF.Builder.CreateStructGEP(afpPtr, 1);
1977-
auto *size =
1978-
IGF.Builder.CreateLoad(sizePtr, IGF.IGM.getPointerAlignment());
1979-
sizePhiValues.push_back({thinBlock, size});
19801995
}
19811996
IGF.Builder.CreateBr(joinBlock);
19821997
}

0 commit comments

Comments
 (0)