From fdf52d35570d49dc00730511e32218aecd828926 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Wed, 23 Dec 2015 18:27:23 +0000 Subject: [PATCH] [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 --- lib/IR/Function.cpp | 19 ++++++++++--------- unittests/IR/UserTest.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 9 deletions(-) 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 -- 2.11.0