[Function] Properly remove use when clearing personality

Summary:
We need to actually remove the use of the personality function,
otherwise we can run into trouble if we want to e.g. delete
the personality function because ther's no way to get rid of
its uses. Do this by resetting to ConstantPointerNull value
that the operands are set to when first allocated.

Reviewers: vsk, dexonsmith

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D15752

llvm-svn: 256345
This commit is contained in:
Keno Fischer 2015-12-23 18:27:23 +00:00
parent 61ad8b3907
commit 9bc46b117b
2 changed files with 34 additions and 9 deletions

View File

@ -942,8 +942,7 @@ Constant *Function::getPersonalityFn() const {
}
void Function::setPersonalityFn(Constant *Fn) {
if (Fn)
setHungoffOperand<0>(Fn);
setHungoffOperand<0>(Fn);
setValueSubclassDataBit(3, Fn != nullptr);
}
@ -953,8 +952,7 @@ Constant *Function::getPrefixData() const {
}
void Function::setPrefixData(Constant *PrefixData) {
if (PrefixData)
setHungoffOperand<1>(PrefixData);
setHungoffOperand<1>(PrefixData);
setValueSubclassDataBit(1, PrefixData != nullptr);
}
@ -964,8 +962,7 @@ Constant *Function::getPrologueData() const {
}
void Function::setPrologueData(Constant *PrologueData) {
if (PrologueData)
setHungoffOperand<2>(PrologueData);
setHungoffOperand<2>(PrologueData);
setValueSubclassDataBit(2, PrologueData != nullptr);
}
@ -986,9 +983,13 @@ void Function::allocHungoffUselist() {
template <int Idx>
void Function::setHungoffOperand(Constant *C) {
assert(C && "Cannot set hungoff operand to nullptr");
allocHungoffUselist();
Op<Idx>().set(C);
if (C) {
allocHungoffUselist();
Op<Idx>().set(C);
} else if (getNumOperands()) {
Op<Idx>().set(
ConstantPointerNull::get(Type::getInt1PtrTy(getContext(), 0)));
}
}
void Function::setValueSubclassDataBit(unsigned Bit, bool On) {

View File

@ -93,4 +93,28 @@ TEST(UserTest, ValueOpIteration) {
EXPECT_EQ(P.value_op_end(), (I - 2) + 8);
}
TEST(UserTest, PersonalityUser) {
Module M("", getGlobalContext());
FunctionType *RetVoidTy =
FunctionType::get(Type::getVoidTy(getGlobalContext()), false);
Function *PersonalityF = Function::Create(
RetVoidTy, GlobalValue::ExternalLinkage, "PersonalityFn", &M);
Function *TestF =
Function::Create(RetVoidTy, GlobalValue::ExternalLinkage, "TestFn", &M);
// Set up the personality function
TestF->setPersonalityFn(PersonalityF);
auto PersonalityUsers = PersonalityF->user_begin();
// One user and that user is the Test function
EXPECT_EQ(*PersonalityUsers, TestF);
EXPECT_EQ(++PersonalityUsers, PersonalityF->user_end());
// Reset the personality function
TestF->setPersonalityFn(nullptr);
// No users should remain
EXPECT_TRUE(TestF->user_empty());
}
} // end anonymous namespace