From 74a0f2314a2cf74fb664b0ee1a2d40a1b6ea5c36 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 23 Oct 2019 07:38:52 -0700 Subject: [PATCH] [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 --- lib/IR/AutoUpgrade.cpp | 23 +++++++++++++++++- .../upgrade-arc-runtime-calls-bitcast.bc | Bin 0 -> 1536 bytes .../upgrade-arc-runtime-calls-bitcast.ll | 21 ++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 test/Bitcode/upgrade-arc-runtime-calls-bitcast.bc create mode 100644 test/Bitcode/upgrade-arc-runtime-calls-bitcast.ll diff --git a/lib/IR/AutoUpgrade.cpp b/lib/IR/AutoUpgrade.cpp index 79f580d0e14..d2dd2a69bea 100644 --- a/lib/IR/AutoUpgrade.cpp +++ b/lib/IR/AutoUpgrade.cpp @@ -3877,15 +3877,36 @@ void llvm::UpgradeARCRuntime(Module &M) { FunctionType *NewFuncTy = NewFn->getFunctionType(); SmallVector 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(CI)->getTailCallKind()); diff --git a/test/Bitcode/upgrade-arc-runtime-calls-bitcast.bc b/test/Bitcode/upgrade-arc-runtime-calls-bitcast.bc new file mode 100644 index 0000000000000000000000000000000000000000..f2af475b26cb6309874fedc22ccb1a8059856739 GIT binary patch literal 1536 zcmZWpe@q*76#tf%UV-jenq|OI2K{YlZz6L{VViSCmT_&bz%1psmJXQC zLOZY1x|F$S6Bh%zX!Ngck~!mIfHK6{%>8niLI{-~naT*dxh!#sehCjVg~aGQB?j^u1uwoyzL5O&*V5y6gZ=pp~xgt?#MSd zW3}vvwm};{IyhLKQT4|{T?F#K;dpEmgNzi zqmp&Sr=yU~Mh6o`g>|ubK{Q&2kvb5N$a1%4y_1t=J>Ad0k$3&xA0IRx`7ztvoow_Uou7U0 z!qO+7PR`#nWxPMU^2^rO@ei->_uWtAhXu!vNT%H7_+BJ=Bm*F#K40@(_%Q`h?TS=4 zd;~yv3kKB!t_Dp~u3B4{i05s3c3eW8Erhx=N&w!4dxb2Fk7aRhk;opSOwn}Q8AiIh zkU+9Sz5o<=F!Wv+t&lr4qa*6egSeN>T``Mn$cXI|lszuCXS(7+7C9_Kx@&osMS56q zsEcO_UX@vkE+)_{sqmAE*=2OO9<9K})YDr0mR3DVYrNz!>xGE*3S}M=+b%?GQL#0% zToh_T4!0o276=_;4D%3Awh0O8kyj!sZ6o1yEa|v{|T9GBtMVJMlS5J*-Mje`KT70TkGc|+H zW!1llG+t$cDMeXMMXZ_njsGRm#2@NHx{?ib_Yw*L0nI_pB^tl2RZowokBBrvz*_Y( zE!}f8V#=hgDasB3c{pmDqpUF~rsEg$VW#{c7>^9;(IZ^4w{aFj7l+aLdh{--8@cAt z%w^Z#%BrVf0JSP>Dq1{!amt)Y+s==eC(1JcNBtN&OQKM`J0tyd2A!)%ACOe`XRUf+5MLIpL{8V-_$h6I#Y&~i zZc&yDWrk~47G%=H{RcWb=v@@_t?q}&f^K~$9n8{ z&^CYow~zKWm(rZOlw*Q)tKZQXZ08ssLkAeoE+*K?`S;SkPG%>~y~=QH?V&s`yM^$w zd3jc%ZAC|T+c~1$b$XYf4;!>J&j)5AVPdiJqN$`0ElMVYUp`xfx=!8NxX!ZTRVs#og=uEGZXa+oPz?kh2oQp;5*0!g1b8X!PYj0qJ6%=V<@cr1_UT~ z2f22Cb2(WGzd*=ORJgoGugAl<$jYk9N{`t^GoGz(ca@nbuc)l3bXOUTjHle=p}DrI zttB+e`k0c|_JFaJ^!Y+