Skip to content

Commit 85ec68d

Browse files
committed
[IR] Fix a memory leak if Function::dropAllReferences() is followed by setHungoffOperand
This patch fixes a memory leak if Function::dropAllReferences() is followed by setHungoffOperand (e.g. setPersonality) If NumUserOperands changes from 3 to 0 before calling allocHungoffUselist() to allocate memory, the memory leaks which are allocated when NumUserOperands is changed from 0 to 3. e.g. ``` llvm::Function* func = ...; func->setPersonalityFn(foo); // (1). call allocHungoffUselist() to allocate memory for uses func->deleteBody(); // (2). call dropAllReferences(), and it changes NumUserOperands from 3 to 0 // (3). at this point, NumUserOperands is 0, the next line will allocate memory by allocHungoffUselist() func->setPersonalityFn(bar); // (4). call allocHungoffUselist(), so memory allocated in (1) leaks. ``` Reviewed By: dexonsmith, MaskRay Differential Revision: https://reviews.llvm.org/D156618
1 parent da26500 commit 85ec68d

File tree

2 files changed

+18
-14
lines changed

2 files changed

+18
-14
lines changed

llvm/include/llvm/IR/Function.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ class LLVM_EXTERNAL_VISIBILITY Function : public GlobalObject,
116116

117117
void clearArguments();
118118

119+
void deleteBodyImpl(bool ShouldDrop);
120+
119121
/// Function ctor - If the (optional) Module argument is specified, the
120122
/// function is automatically inserted into the end of the function list for
121123
/// the module.
@@ -667,7 +669,7 @@ class LLVM_EXTERNAL_VISIBILITY Function : public GlobalObject,
667669
/// the linkage to external.
668670
///
669671
void deleteBody() {
670-
dropAllReferences();
672+
deleteBodyImpl(/*ShouldDrop=*/false);
671673
setLinkage(ExternalLinkage);
672674
}
673675

@@ -882,7 +884,9 @@ class LLVM_EXTERNAL_VISIBILITY Function : public GlobalObject,
882884
/// function, dropping all references deletes the entire body of the function,
883885
/// including any contained basic blocks.
884886
///
885-
void dropAllReferences();
887+
void dropAllReferences() {
888+
deleteBodyImpl(/*ShouldDrop=*/true);
889+
}
886890

887891
/// hasAddressTaken - returns true if there are any uses of this function
888892
/// other than direct calls or invokes to it, or blockaddress expressions.

llvm/lib/IR/Function.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -518,15 +518,7 @@ void Function::stealArgumentListFrom(Function &Src) {
518518
Src.setValueSubclassData(Src.getSubclassDataFromValue() | (1 << 0));
519519
}
520520

521-
// dropAllReferences() - This function causes all the subinstructions to "let
522-
// go" of all references that they are maintaining. This allows one to
523-
// 'delete' a whole class at a time, even though there may be circular
524-
// references... first all references are dropped, and all use counts go to
525-
// zero. Then everything is deleted for real. Note that no operations are
526-
// valid on an object that has "dropped all references", except operator
527-
// delete.
528-
//
529-
void Function::dropAllReferences() {
521+
void Function::deleteBodyImpl(bool ShouldDrop) {
530522
setIsMaterializable(false);
531523

532524
for (BasicBlock &BB : *this)
@@ -537,10 +529,18 @@ void Function::dropAllReferences() {
537529
while (!BasicBlocks.empty())
538530
BasicBlocks.begin()->eraseFromParent();
539531

540-
// Drop uses of any optional data (real or placeholder).
541532
if (getNumOperands()) {
542-
User::dropAllReferences();
543-
setNumHungOffUseOperands(0);
533+
if (ShouldDrop) {
534+
// Drop uses of any optional data (real or placeholder).
535+
User::dropAllReferences();
536+
setNumHungOffUseOperands(0);
537+
} else {
538+
// The code needs to match Function::allocHungoffUselist().
539+
auto *CPN = ConstantPointerNull::get(PointerType::get(getContext(), 0));
540+
Op<0>().set(CPN);
541+
Op<1>().set(CPN);
542+
Op<2>().set(CPN);
543+
}
544544
setValueSubclassData(getSubclassDataFromValue() & ~0xe);
545545
}
546546

0 commit comments

Comments
 (0)