From: Keno Fischer Date: Wed, 23 Dec 2015 18:27:23 +0000 (+0000) Subject: [Function] Properly remove use when clearing personality X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=fdf52d35570d49dc00730511e32218aecd828926 [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256345 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp index f5974a63f45..cfb40b19c73 100644 --- a/lib/IR/Function.cpp +++ b/lib/IR/Function.cpp @@ -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 void Function::setHungoffOperand(Constant *C) { - assert(C && "Cannot set hungoff operand to nullptr"); - allocHungoffUselist(); - Op().set(C); + if (C) { + allocHungoffUselist(); + Op().set(C); + } else if (getNumOperands()) { + Op().set( + ConstantPointerNull::get(Type::getInt1PtrTy(getContext(), 0))); + } } void Function::setValueSubclassDataBit(unsigned Bit, bool On) { diff --git a/unittests/IR/UserTest.cpp b/unittests/IR/UserTest.cpp index 56b054b6835..8d488389448 100644 --- a/unittests/IR/UserTest.cpp +++ b/unittests/IR/UserTest.cpp @@ -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