1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[ObjC][ARC] Check whether the return and parameter types of the old and

new functions are compatible before upgrading a function call to an
intrinsic call.

Sometimes users insert calls to ARC runtime functions that are not
compatible with the corresponding intrinsic functions (for example,
'i8* @objc_storeStrong' instead of 'void @objc_storeStrong'). Don't
upgrade those calls.

rdar://problem/56447127
This commit is contained in:
Akira Hatanaka 2019-10-23 07:38:52 -07:00
parent ad3a6f4017
commit 74a0f2314a
3 changed files with 43 additions and 1 deletions

View File

@ -3877,15 +3877,36 @@ void llvm::UpgradeARCRuntime(Module &M) {
FunctionType *NewFuncTy = NewFn->getFunctionType();
SmallVector<Value *, 2> Args;
// Don't upgrade the intrinsic if it's not valid to bitcast the return
// value to the return type of the old function.
if (NewFuncTy->getReturnType() != CI->getType() &&
!CastInst::castIsValid(Instruction::BitCast, CI,
NewFuncTy->getReturnType()))
continue;
bool InvalidCast = false;
for (unsigned I = 0, E = CI->getNumArgOperands(); I != E; ++I) {
Value *Arg = CI->getArgOperand(I);
// Bitcast argument to the parameter type of the new function if it's
// not a variadic argument.
if (I < NewFuncTy->getNumParams())
if (I < NewFuncTy->getNumParams()) {
// Don't upgrade the intrinsic if it's not valid to bitcast the argument
// to the parameter type of the new function.
if (!CastInst::castIsValid(Instruction::BitCast, Arg,
NewFuncTy->getParamType(I))) {
InvalidCast = true;
break;
}
Arg = Builder.CreateBitCast(Arg, NewFuncTy->getParamType(I));
}
Args.push_back(Arg);
}
if (InvalidCast)
continue;
// Create a call instruction that calls the new function.
CallInst *NewCall = Builder.CreateCall(NewFuncTy, NewFn, Args);
NewCall->setTailCallKind(cast<CallInst>(CI)->getTailCallKind());

Binary file not shown.

View File

@ -0,0 +1,21 @@
target triple = "arm64-apple-ios7.0"
; RUN: llvm-dis < %S/upgrade-arc-runtime-calls-bitcast.bc | FileCheck %s
; CHECK: tail call i8* @objc_retain(i32 1)
; CHECK: tail call i8* @objc_storeStrong(
define void @testRuntimeCalls(i8* %a, i8** %b) {
%v6 = tail call i8* @objc_retain(i32 1)
%1 = tail call i8* @objc_storeStrong(i8** %b, i8* %a)
ret void
}
declare i8* @objc_retain(i32)
declare i8* @objc_storeStrong(i8**, i8*)
attributes #0 = { nounwind }
!llvm.module.flags = !{!0}
!0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov\09fp, fp\09\09; marker for objc_retainAutoreleaseReturnValue"}