From 4fef722974dd847a26cb2bdad6fd4a298e1edd1f Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Tue, 13 Jan 2015 00:10:38 +0000 Subject: [PATCH] IR: Fix an inverted assertion when replacing resolved operands Add a unit test, since this bug was only exposed by clang tests. Thanks to Rafael for tracking this down! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225738 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/IR/Metadata.cpp | 2 +- unittests/IR/MetadataTest.cpp | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/IR/Metadata.cpp b/lib/IR/Metadata.cpp index 13844313925..0132bab82c6 100644 --- a/lib/IR/Metadata.cpp +++ b/lib/IR/Metadata.cpp @@ -444,7 +444,7 @@ void UniquableMDNode::resolveAfterOperandChange(Metadata *Old, Metadata *New) { // Check if an operand was resolved. if (!isOperandUnresolved(Old)) - assert(isOperandUnresolved(New) && "Operand just became unresolved"); + assert(!isOperandUnresolved(New) && "Operand just became unresolved"); else if (!isOperandUnresolved(New)) decrementUnresolvedOperandCount(); } diff --git a/unittests/IR/MetadataTest.cpp b/unittests/IR/MetadataTest.cpp index af110742dd7..c364aeacba1 100644 --- a/unittests/IR/MetadataTest.cpp +++ b/unittests/IR/MetadataTest.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/STLExtras.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Instructions.h" @@ -361,6 +362,28 @@ TEST_F(MDNodeTest, handleChangedOperandRecursion) { EXPECT_EQ(N4, N6->getOperand(0)); } +TEST_F(MDNodeTest, replaceResolvedOperand) { + // Check code for replacing one resolved operand with another. If doing this + // directly (via replaceOperandWith()) becomes illegal, change the operand to + // a global value that gets RAUW'ed. + // + // Use a temporary node to keep N from being resolved. + std::unique_ptr Temp(MDNodeFwdDecl::get(Context, None)); + Metadata *Ops[] = {nullptr, Temp.get()}; + + MDNode *Empty = MDTuple::get(Context, {}); + MDNode *N = MDTuple::get(Context, Ops); + EXPECT_EQ(nullptr, N->getOperand(0)); + ASSERT_FALSE(N->isResolved()); + + // Check code for replacing resolved nodes. + N->replaceOperandWith(0, Empty); + EXPECT_EQ(Empty, N->getOperand(0)); + + // Remove the reference to Temp; required for teardown. + N->replaceOperandWith(1, nullptr); +} + typedef MetadataTest MetadataAsValueTest; TEST_F(MetadataAsValueTest, MDNode) { -- 2.34.1