Skip to content

Commit

Permalink
[ObjC][ARC] Check whether the return and parameter types of the old and
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ahatanaka committed Oct 24, 2019
1 parent a5376f6 commit 31b752c
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 1 deletion.
23 changes: 22 additions & 1 deletion llvm/lib/IR/AutoUpgrade.cpp
Expand Up @@ -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());
Expand Down
Binary file not shown.
21 changes: 21 additions & 0 deletions llvm/test/Bitcode/upgrade-arc-runtime-calls-bitcast.ll
@@ -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"}

0 comments on commit 31b752c

Please sign in to comment.