[llvm] [ADT] Clean up and fix FoldingSetBase move operations (PR #217453)
Kazu Hirata via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 24 15:54:34 PDT 2026
https://github.com/kazutakahirata updated https://github.com/llvm/llvm-project/pull/217453
>From 0a7aa80be30b14c0a9f5f38fed74b4a67fa70612 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Mon, 24 Aug 2026 13:59:20 -0700
Subject: [PATCH] Rebase.
---
llvm/include/llvm/ADT/FoldingSet.h | 6 +++---
llvm/lib/Support/FoldingSet.cpp | 19 +++++++++----------
llvm/unittests/ADT/FoldingSet.cpp | 17 +++++++++++++++++
3 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/llvm/include/llvm/ADT/FoldingSet.h b/llvm/include/llvm/ADT/FoldingSet.h
index 74d4b2f08bb19..9b324b337072c 100644
--- a/llvm/include/llvm/ADT/FoldingSet.h
+++ b/llvm/include/llvm/ADT/FoldingSet.h
@@ -299,14 +299,14 @@ class FoldingSetNodeID {
class FoldingSetBase : public DebugEpochBase {
protected:
/// Array of bucket chains.
- void **Buckets;
+ void **Buckets = nullptr;
/// Length of the Buckets array. Always a power of 2.
- unsigned NumBuckets;
+ unsigned NumBuckets = 0;
/// Number of nodes in the folding set. Growth occurs when NumNodes
/// is greater than twice the number of buckets.
- unsigned NumNodes;
+ unsigned NumNodes = 0;
LLVM_ABI explicit FoldingSetBase(unsigned Log2InitSize);
LLVM_ABI FoldingSetBase(FoldingSetBase &&Arg);
diff --git a/llvm/lib/Support/FoldingSet.cpp b/llvm/lib/Support/FoldingSet.cpp
index d4bd863fa9a3f..13aac74280978 100644
--- a/llvm/lib/Support/FoldingSet.cpp
+++ b/llvm/lib/Support/FoldingSet.cpp
@@ -184,23 +184,22 @@ FoldingSetBase::FoldingSetBase(unsigned Log2InitSize) {
}
FoldingSetBase::FoldingSetBase(FoldingSetBase &&Arg)
- : Buckets(Arg.Buckets), NumBuckets(Arg.NumBuckets), NumNodes(Arg.NumNodes) {
+ : Buckets(std::exchange(Arg.Buckets, nullptr)),
+ NumBuckets(std::exchange(Arg.NumBuckets, 0)),
+ NumNodes(std::exchange(Arg.NumNodes, 0)) {
Arg.incrementEpoch();
- Arg.Buckets = nullptr;
- Arg.NumBuckets = 0;
- Arg.NumNodes = 0;
}
FoldingSetBase &FoldingSetBase::operator=(FoldingSetBase &&RHS) {
+ if (this == &RHS)
+ return *this;
+
incrementEpoch();
RHS.incrementEpoch();
free(Buckets); // This may be null if the set is in a moved-from state.
- Buckets = RHS.Buckets;
- NumBuckets = RHS.NumBuckets;
- NumNodes = RHS.NumNodes;
- RHS.Buckets = nullptr;
- RHS.NumBuckets = 0;
- RHS.NumNodes = 0;
+ Buckets = std::exchange(RHS.Buckets, nullptr);
+ NumBuckets = std::exchange(RHS.NumBuckets, 0);
+ NumNodes = std::exchange(RHS.NumNodes, 0);
return *this;
}
diff --git a/llvm/unittests/ADT/FoldingSet.cpp b/llvm/unittests/ADT/FoldingSet.cpp
index ff0f253cf355a..168443b21a4ef 100644
--- a/llvm/unittests/ADT/FoldingSet.cpp
+++ b/llvm/unittests/ADT/FoldingSet.cpp
@@ -358,6 +358,23 @@ TEST(FoldingSetTest, ContextualFoldingSetBasic) {
EXPECT_THAT(Set, SizeIs(0));
}
+TEST(FoldingSetTest, SelfMoveAssignment) {
+ FoldingSet<TrivialPair> Set;
+ TrivialPair T1(10, 100);
+ Set.InsertNode(&T1);
+
+ // Route through a helper lambda to test self-move aliasing without triggering
+ // -Wself-move.
+ auto MoveAssign = [](FoldingSet<TrivialPair> &Dest,
+ FoldingSet<TrivialPair> &&Src) {
+ Dest = std::move(Src);
+ };
+ MoveAssign(Set, std::move(Set));
+
+ EXPECT_EQ(1u, Set.size());
+ EXPECT_FALSE(Set.empty());
+}
+
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
TEST(FoldingSetTest, InsertInvalidatesIterators) {
FoldingSet<TrivialPair> Set;
More information about the llvm-commits
mailing list