From bcd960a1bcecee6d769b98020c06ff1f1e16fdaf Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Mon, 5 Jan 2015 23:31:54 +0000 Subject: [PATCH] IR: Don't drop MDNode uniquing on null operands Now that `LLVMContextImpl` can call `MDNode::dropAllReferences()` to prevent teardown madness, stop dropping uniquing just because an operand drops to null. Part of PR21532. llvm-svn: 225223 --- llvm/lib/IR/Metadata.cpp | 9 ++------- llvm/unittests/IR/MetadataTest.cpp | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp index bed2b6b..1a65157 100644 --- a/llvm/lib/IR/Metadata.cpp +++ b/llvm/lib/IR/Metadata.cpp @@ -515,13 +515,8 @@ void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) { Metadata *Old = getOperand(Op); setOperand(Op, New); - // Drop uniquing for self-reference cycles or if an operand drops to null. - // - // FIXME: Stop dropping uniquing when an operand drops to null. The original - // motivation was to prevent madness during teardown of LLVMContextImpl, but - // dropAllReferences() fixes that problem in a better way. (It's just here - // now for better staging of semantic changes.) - if (New == this || !New) { + // Drop uniquing for self-reference cycles. + if (New == this) { storeDistinctInContext(); setHash(0); if (!isResolved()) diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp index ccdda1c..ef071b3 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -202,6 +202,26 @@ TEST_F(MDNodeTest, Print) { EXPECT_EQ(Expected, Actual); } +TEST_F(MDNodeTest, NullOperand) { + // metadata !{} + MDNode *Empty = MDNode::get(Context, None); + + // metadata !{metadata !{}} + Metadata *Ops[] = {Empty}; + MDNode *N = MDNode::get(Context, Ops); + ASSERT_EQ(Empty, N->getOperand(0)); + + // metadata !{metadata !{}} => metadata !{null} + N->replaceOperandWith(0, nullptr); + ASSERT_EQ(nullptr, N->getOperand(0)); + + // metadata !{null} + Ops[0] = nullptr; + MDNode *NullOp = MDNode::get(Context, Ops); + ASSERT_EQ(nullptr, NullOp->getOperand(0)); + EXPECT_EQ(N, NullOp); +} + typedef MetadataTest MetadataAsValueTest; TEST_F(MetadataAsValueTest, MDNode) { -- 2.7.4