[llvm] [ADT] Improve unit test coverage for FoldingSet (PR #217214)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 18 22:20:28 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-adt
Author: Kazu Hirata (kazutakahirata)
<details>
<summary>Changes</summary>
This patch adds unit tests covering the following previously uncovered
areas of FoldingSet, FoldingSetVector, and ContextualFoldingSet:
- Move semantics (move constructor and move assignment operator of
FoldingSet).
- Iterators (begin()/end(), exact element traversal, and pre/post
increment operators).
- FoldingSetVector (basic operations including deduplication, lookup with
an insertion token, deterministic iteration order, and clear()).
- ContextualFoldingSet (similar basic operations with contextual node
profiling).
Assisted-by: Antigravity
---
Full diff: https://github.com/llvm/llvm-project/pull/217214.diff
1 Files Affected:
- (modified) llvm/unittests/ADT/FoldingSet.cpp (+176)
``````````diff
diff --git a/llvm/unittests/ADT/FoldingSet.cpp b/llvm/unittests/ADT/FoldingSet.cpp
index 0101c85667202..c88df15453c76 100644
--- a/llvm/unittests/ADT/FoldingSet.cpp
+++ b/llvm/unittests/ADT/FoldingSet.cpp
@@ -11,10 +11,16 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/FoldingSet.h"
+#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <string>
+#include <vector>
using namespace llvm;
+using testing::ElementsAre;
+using testing::IsEmpty;
+using testing::SizeIs;
+using testing::UnorderedElementsAre;
namespace {
@@ -188,4 +194,174 @@ TEST(FoldingSetTest, SmallReserveChangesNothing) {
EXPECT_EQ(Trivial.capacity(), OldCapacity);
}
+TEST(FoldingSetTest, MoveConstructor) {
+ FoldingSet<TrivialPair> A;
+ TrivialPair T1(10, 100);
+ TrivialPair T2(20, 200);
+ A.InsertNode(&T1);
+ A.InsertNode(&T2);
+ EXPECT_THAT(A, SizeIs(2));
+
+ FoldingSet<TrivialPair> B(std::move(A));
+ EXPECT_THAT(B, SizeIs(2));
+ EXPECT_THAT(B, testing::Not(IsEmpty()));
+
+ void *InsertPos = nullptr;
+ FoldingSetNodeID ID1, ID2;
+ T1.Profile(ID1);
+ T2.Profile(ID2);
+ EXPECT_EQ(&T1, B.FindNodeOrInsertPos(ID1, InsertPos));
+ EXPECT_EQ(&T2, B.FindNodeOrInsertPos(ID2, InsertPos));
+}
+
+TEST(FoldingSetTest, MoveAssignment) {
+ FoldingSet<TrivialPair> A;
+ FoldingSet<TrivialPair> B;
+ TrivialPair T1(10, 100);
+ TrivialPair T2(20, 200);
+ TrivialPair T3(30, 300);
+ B.InsertNode(&T1);
+ A.InsertNode(&T2);
+ A.InsertNode(&T3);
+
+ B = std::move(A);
+ EXPECT_THAT(B, SizeIs(2));
+ EXPECT_THAT(B, testing::Not(IsEmpty()));
+
+ void *InsertPos = nullptr;
+ FoldingSetNodeID ID2, ID3;
+ T2.Profile(ID2);
+ T3.Profile(ID3);
+ EXPECT_EQ(&T2, B.FindNodeOrInsertPos(ID2, InsertPos));
+ EXPECT_EQ(&T3, B.FindNodeOrInsertPos(ID3, InsertPos));
+}
+
+TEST(FoldingSetTest, Iterator) {
+ FoldingSet<TrivialPair> Set;
+ EXPECT_EQ(Set.begin(), Set.end());
+
+ TrivialPair T1(1, 10);
+ TrivialPair T2(2, 20);
+ TrivialPair T3(3, 30);
+ Set.InsertNode(&T1);
+ Set.InsertNode(&T2);
+ Set.InsertNode(&T3);
+
+ {
+ std::vector<const TrivialPair *> Elements;
+ for (const TrivialPair &Item : Set)
+ Elements.push_back(&Item);
+ EXPECT_THAT(Elements, UnorderedElementsAre(&T1, &T2, &T3));
+ }
+
+ ASSERT_NE(Set.begin(), Set.end());
+ auto It = Set.begin();
+ auto ItCopy = It++;
+ EXPECT_NE(It, ItCopy);
+}
+
+TEST(FoldingSetTest, FoldingSetVectorBasic) {
+ FoldingSetVector<TrivialPair> Vec;
+ EXPECT_THAT(Vec, IsEmpty());
+ EXPECT_THAT(Vec, SizeIs(0));
+
+ TrivialPair T1(10, 100);
+ TrivialPair T1Copy(10, 100);
+ TrivialPair T2(20, 200);
+ TrivialPair T3(30, 300);
+
+ EXPECT_EQ(&T1, Vec.GetOrInsertNode(&T1));
+ EXPECT_EQ(&T1, Vec.GetOrInsertNode(&T1Copy));
+ EXPECT_THAT(Vec, SizeIs(1));
+
+ // Insert a new node using an insertion token.
+ FoldingSetNodeID ID2;
+ T2.Profile(ID2);
+ void *InsertPos = nullptr;
+ EXPECT_EQ(nullptr, Vec.FindNodeOrInsertPos(ID2, InsertPos));
+ ASSERT_NE(nullptr, InsertPos);
+ Vec.InsertNode(&T2, InsertPos);
+ EXPECT_THAT(Vec, SizeIs(2));
+
+ Vec.InsertNode(&T3);
+ EXPECT_THAT(Vec, SizeIs(3));
+ EXPECT_THAT(Vec, testing::Not(IsEmpty()));
+
+ // Verify deterministic iteration order matching insertion order.
+ {
+ std::vector<const TrivialPair *> Elements;
+ for (const TrivialPair &Item : Vec)
+ Elements.push_back(&Item);
+ EXPECT_THAT(Elements, ElementsAre(&T1, &T2, &T3));
+ }
+
+ Vec.clear();
+ EXPECT_THAT(Vec, IsEmpty());
+ EXPECT_THAT(Vec, SizeIs(0));
+}
+
+struct TestContext {
+ unsigned Value = 0;
+};
+
+struct ContextualPair : public FoldingSetNode {
+ unsigned Key = 0;
+ unsigned Value = 0;
+ ContextualPair(unsigned K, unsigned V) : FoldingSetNode(), Key(K), Value(V) {}
+
+ void Profile(FoldingSetNodeID &ID, TestContext Context) const {
+ ID.AddInteger(Key ^ Context.Value);
+ ID.AddInteger(Value ^ Context.Value);
+ }
+};
+
+TEST(FoldingSetTest, ContextualFoldingSetBasic) {
+ TestContext ContextVal{0xABCD};
+ ContextualFoldingSet<ContextualPair, TestContext> Set(ContextVal);
+ EXPECT_EQ(ContextVal.Value, Set.getContext().Value);
+ EXPECT_THAT(Set, IsEmpty());
+ EXPECT_THAT(Set, SizeIs(0));
+
+ ContextualPair T1(10, 100);
+ ContextualPair T1Copy(10, 100);
+ ContextualPair T2(20, 200);
+
+ EXPECT_EQ(&T1, Set.GetOrInsertNode(&T1));
+ EXPECT_EQ(&T1, Set.GetOrInsertNode(&T1Copy));
+ EXPECT_THAT(Set, SizeIs(1));
+
+ // Insert a new node using an insertion token.
+ void *InsertPos = nullptr;
+ FoldingSetNodeID ID2;
+ T2.Profile(ID2, ContextVal);
+ EXPECT_EQ(nullptr, Set.FindNodeOrInsertPos(ID2, InsertPos));
+ ASSERT_NE(nullptr, InsertPos);
+ Set.InsertNode(&T2, InsertPos);
+ EXPECT_THAT(Set, SizeIs(2));
+
+ EXPECT_EQ(&T2, Set.FindNodeOrInsertPos(ID2, InsertPos));
+
+ {
+ std::vector<const ContextualPair *> Elements;
+ for (const ContextualPair &Item : Set)
+ Elements.push_back(&Item);
+ EXPECT_THAT(Elements, UnorderedElementsAre(&T1, &T2));
+ }
+
+ EXPECT_TRUE(Set.RemoveNode(&T1));
+ EXPECT_THAT(Set, SizeIs(1));
+ EXPECT_FALSE(Set.RemoveNode(&T1));
+
+ {
+ std::vector<const ContextualPair *> Elements;
+ for (const ContextualPair &Item : Set)
+ Elements.push_back(&Item);
+ EXPECT_THAT(Elements, UnorderedElementsAre(&T2));
+ }
+
+ Set.clear();
+ EXPECT_THAT(Set, IsEmpty());
+ EXPECT_THAT(Set, SizeIs(0));
+}
+
} // namespace
``````````
</details>
https://github.com/llvm/llvm-project/pull/217214
More information about the llvm-commits
mailing list