[Function] Properly remove use when clearing personality
authorKeno Fischer <kfischer@college.harvard.edu>
Wed, 23 Dec 2015 18:27:23 +0000 (18:27 +0000)
committerKeno Fischer <kfischer@college.harvard.edu>
Wed, 23 Dec 2015 18:27:23 +0000 (18:27 +0000)
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
unittests/IR/UserTest.cpp

index f5974a6..cfb40b1 100644 (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) {
index 56b054b..8d48838 100644 (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