Skip to content

Commit ae94890

Browse files
author
Wolfgang Pieb
committed
[NFC][Metadata] Define move constructor and move assignment operator for MDOperand.
This is a preparatory patch for the MDNode resize functionality. Reviewed By: dexonsmith Differential Revision: https://reviews.llvm.org/D125994
1 parent d7ebb74 commit ae94890

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

llvm/include/llvm/IR/Metadata.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -775,10 +775,21 @@ class MDOperand {
775775

776776
public:
777777
MDOperand() = default;
778-
MDOperand(MDOperand &&) = delete;
779778
MDOperand(const MDOperand &) = delete;
780-
MDOperand &operator=(MDOperand &&) = delete;
779+
MDOperand(MDOperand &&Op) {
780+
MD = Op.MD;
781+
if (MD)
782+
(void)MetadataTracking::retrack(Op.MD, MD);
783+
Op.MD = nullptr;
784+
}
781785
MDOperand &operator=(const MDOperand &) = delete;
786+
MDOperand &operator=(MDOperand &&Op) {
787+
MD = Op.MD;
788+
if (MD)
789+
(void)MetadataTracking::retrack(Op.MD, MD);
790+
Op.MD = nullptr;
791+
return *this;
792+
}
782793
~MDOperand() { untrack(); }
783794

784795
Metadata *get() const { return MD; }

llvm/unittests/IR/MetadataTest.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3602,4 +3602,33 @@ TEST_F(DebugVariableTest, DenseMap) {
36023602
EXPECT_EQ(DebugVariableMap.find(DebugVariableFragB)->second, 12u);
36033603
}
36043604

3605+
typedef MetadataTest MDTupleAllocationTest;
3606+
TEST_F(MDTupleAllocationTest, Tracking) {
3607+
// Make sure that the move constructor and move assignment op
3608+
// for MDOperand correctly adjust tracking information.
3609+
auto *Value1 = getConstantAsMetadata();
3610+
MDTuple *A = MDTuple::getDistinct(Context, {Value1, Value1});
3611+
EXPECT_EQ(A->getOperand(0), Value1);
3612+
EXPECT_EQ(A->getOperand(1), Value1);
3613+
3614+
MDNode::op_range Ops = A->operands();
3615+
3616+
MDOperand NewOps1;
3617+
// Move assignment operator.
3618+
NewOps1 = std::move(*const_cast<MDOperand *>(Ops.begin()));
3619+
// Move constructor.
3620+
MDOperand NewOps2(std::move(*const_cast<MDOperand *>(Ops.begin() + 1)));
3621+
3622+
EXPECT_EQ(NewOps1.get(), static_cast<Metadata *>(Value1));
3623+
EXPECT_EQ(NewOps2.get(), static_cast<Metadata *>(Value1));
3624+
3625+
auto *Value2 = getConstantAsMetadata();
3626+
Value *V1 = Value1->getValue();
3627+
Value *V2 = Value2->getValue();
3628+
ValueAsMetadata::handleRAUW(V1, V2);
3629+
3630+
EXPECT_EQ(NewOps1.get(), static_cast<Metadata *>(Value2));
3631+
EXPECT_EQ(NewOps2.get(), static_cast<Metadata *>(Value2));
3632+
}
3633+
36053634
} // end namespace

0 commit comments

Comments
 (0)