From: Easwaran Raman Date: Fri, 4 Mar 2016 00:44:01 +0000 (+0000) Subject: Fix a use-after-free bug introduced in r262636 X-Git-Tag: llvmorg-3.9.0-rc1~12508 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3b7a8246c984bf5de8daa346f55a55f7d42d0391;p=platform%2Fupstream%2Fllvm.git Fix a use-after-free bug introduced in r262636 llvm-svn: 262679 --- diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h index 8f6502e..b934a56 100644 --- a/llvm/include/llvm/Transforms/Utils/Cloning.h +++ b/llvm/include/llvm/Transforms/Utils/Cloning.h @@ -189,7 +189,7 @@ public: explicit InlineFunctionInfo(CallGraph *cg = nullptr, AssumptionCacheTracker *ACT = nullptr, BlockCloningFunctor Ftor = nullptr) - : CG(cg), ACT(ACT), Ftor(Ftor) {} + : CG(cg), ACT(ACT), Ftor(Ftor), CallSuccessorBlockDeleted(false) {} /// CG - If non-null, InlineFunction will update the callgraph to reflect the /// changes it makes. @@ -198,6 +198,10 @@ public: // Functor that is invoked when a block is cloned into the new function. BlockCloningFunctor Ftor; + /// CallSuccessorBlockDeleted - whether the block immediately following the + /// call has been deleted during inlining + bool CallSuccessorBlockDeleted; + /// StaticAllocas - InlineFunction fills this in with all static allocas that /// get copied into the caller. SmallVector StaticAllocas; diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp index 8ed4bda..c82c7df 100644 --- a/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/llvm/lib/Transforms/IPO/Inliner.cpp @@ -580,11 +580,13 @@ bool Inliner::runOnSCC(CallGraphSCC &SCC) { continue; } updateEntryCount(CallSiteBlock, Callee); - // The instruction following the call is part of a new basic block - // created during the inlining process. This does not have an entry in - // the BFI. We create an entry by copying the frequency of the original - // block containing the call. - copyBlockFrequency(CallSiteBlock, CallSuccessor->getParent()); + if (!InlineInfo.CallSuccessorBlockDeleted) { + // The instruction following the call is part of a new basic block + // created during the inlining process. This does not have an entry in + // the BFI. We create an entry by copying the frequency of the + // original block containing the call. + copyBlockFrequency(CallSiteBlock, CallSuccessor->getParent()); + } ++NumInlined; diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 923e5b2..251afb5 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -1994,8 +1994,11 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, // If we inlined any musttail calls and the original return is now // unreachable, delete it. It can only contain a bitcast and ret. - if (InlinedMustTailCalls && pred_begin(AfterCallBB) == pred_end(AfterCallBB)) + if (InlinedMustTailCalls && + pred_begin(AfterCallBB) == pred_end(AfterCallBB)) { + IFI.CallSuccessorBlockDeleted = true; AfterCallBB->eraseFromParent(); + } // We should always be able to fold the entry block of the function into the // single predecessor of the block...