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 | |
parent | f3eae68bd1d17df708f2b59a43ad7e837a616e6a (diff) |
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')
-rw-r--r-- | absl/container/BUILD.bazel | 2 | ||||
-rw-r--r-- | absl/container/CMakeLists.txt | 2 | ||||
-rw-r--r-- | absl/container/flat_hash_set_test.cc | 65 |
3 files changed, 69 insertions, 0 deletions
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index a1f6fd4f..208e78e8 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -283,12 +283,14 @@ cc_test( linkopts = ABSL_DEFAULT_LINKOPTS, tags = ["no_test_loonix"], deps = [ + ":container_memory", ":flat_hash_set", ":hash_generator_testing", ":unordered_set_constructor_test", ":unordered_set_lookup_test", ":unordered_set_members_test", ":unordered_set_modifiers_test", + "//absl/base:config", "//absl/log:check", "//absl/memory", "//absl/strings", diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index f3443a66..64f6965a 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -338,6 +338,8 @@ absl_cc_test( "-DUNORDERED_SET_CXX17" DEPS absl::check + absl::config + absl::container_memory absl::flat_hash_set absl::hash_generator_testing absl::memory 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 |