diff options
author | Evan Brown <ezb@google.com> | 2023-09-12 08:16:03 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-09-12 08:16:59 -0700 |
commit | f01b1b56de359de540c97a7898ff3011c47e2c26 (patch) | |
tree | 962949615909631158fb952f827da004b7080cdb /absl/container/flat_hash_set_test.cc | |
parent | f3eae68bd1d17df708f2b59a43ad7e837a616e6a (diff) | |
download | abseil-f01b1b56de359de540c97a7898ff3011c47e2c26.tar.gz abseil-f01b1b56de359de540c97a7898ff3011c47e2c26.tar.bz2 abseil-f01b1b56de359de540c97a7898ff3011c47e2c26.zip |
Add a flat_hash_set_test that we use value_type member functions to read/write from value_types when we aren't allowed to memcpy them.
The motivation is to prevent a bug in small buffer optimization for swisstables.
PiperOrigin-RevId: 564726325
Change-Id: Id0df5d28d65c7586428001fcb266886988cd481e
Diffstat (limited to 'absl/container/flat_hash_set_test.cc')
-rw-r--r-- | absl/container/flat_hash_set_test.cc | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/absl/container/flat_hash_set_test.cc b/absl/container/flat_hash_set_test.cc index 20130f91..a60b4bf5 100644 --- a/absl/container/flat_hash_set_test.cc +++ b/absl/container/flat_hash_set_test.cc @@ -14,8 +14,15 @@ #include "absl/container/flat_hash_set.h" +#include <cstdint> +#include <memory> +#include <utility> #include <vector> +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/base/config.h" +#include "absl/container/internal/container_memory.h" #include "absl/container/internal/hash_generator_testing.h" #include "absl/container/internal/unordered_set_constructor_test.h" #include "absl/container/internal/unordered_set_lookup_test.h" @@ -172,6 +179,64 @@ TEST(FlatHashSet, EraseIf) { } } +class PoisonInline { + int64_t data_; + + public: + explicit PoisonInline(int64_t d) : data_(d) { + SanitizerPoisonObject(&data_); + } + PoisonInline(const PoisonInline& that) : PoisonInline(*that) {} + ~PoisonInline() { SanitizerUnpoisonObject(&data_); } + + int64_t operator*() const { + SanitizerUnpoisonObject(&data_); + const int64_t ret = data_; + SanitizerPoisonObject(&data_); + return ret; + } + template <typename H> + friend H AbslHashValue(H h, const PoisonInline& pi) { + return H::combine(std::move(h), *pi); + } + bool operator==(const PoisonInline& rhs) const { return **this == *rhs; } +}; + +// Tests that we don't touch the poison_ member of PoisonInline. +TEST(FlatHashSet, PoisonInline) { + PoisonInline a(0), b(1); + { // basic usage + flat_hash_set<PoisonInline> set; + set.insert(a); + EXPECT_THAT(set, UnorderedElementsAre(a)); + set.insert(b); + EXPECT_THAT(set, UnorderedElementsAre(a, b)); + set.erase(a); + EXPECT_THAT(set, UnorderedElementsAre(b)); + set.rehash(0); // shrink to inline + EXPECT_THAT(set, UnorderedElementsAre(b)); + } + { // test move constructor from inline to inline + flat_hash_set<PoisonInline> set; + set.insert(a); + flat_hash_set<PoisonInline> set2(std::move(set)); + EXPECT_THAT(set2, UnorderedElementsAre(a)); + } + { // test move assignment from inline to inline + flat_hash_set<PoisonInline> set, set2; + set.insert(a); + set2 = std::move(set); + EXPECT_THAT(set2, UnorderedElementsAre(a)); + } + { // test alloc move constructor from inline to inline + flat_hash_set<PoisonInline> set; + set.insert(a); + flat_hash_set<PoisonInline> set2(std::move(set), + std::allocator<PoisonInline>()); + EXPECT_THAT(set2, UnorderedElementsAre(a)); + } +} + } // namespace } // namespace container_internal ABSL_NAMESPACE_END |