summaryrefslogtreecommitdiff
path: root/absl
diff options
context:
space:
mode:
authorGravatar Evan Brown <ezb@google.com>2023-09-12 08:16:03 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2023-09-12 08:16:59 -0700
commitf01b1b56de359de540c97a7898ff3011c47e2c26 (patch)
tree962949615909631158fb952f827da004b7080cdb /absl
parentf3eae68bd1d17df708f2b59a43ad7e837a616e6a (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.bazel2
-rw-r--r--absl/container/CMakeLists.txt2
-rw-r--r--absl/container/flat_hash_set_test.cc65
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