aboutsummaryrefslogtreecommitdiff
path: root/absl/container/internal
diff options
context:
space:
mode:
authorEvan Brown <ezb@google.com>2024-03-26 13:34:56 -0700
committerCopybara-Service <copybara-worker@google.com>2024-03-26 13:36:12 -0700
commit6f0c500453dd911018bd5cfb46999cee5e3e2cf8 (patch)
treec1788b85e5b6d27e81b1ce1038b09f24d9285fc2 /absl/container/internal
parent68ce303da1920522a27e5d8e2732b3e50d3aae57 (diff)
downloadabseil-6f0c500453dd911018bd5cfb46999cee5e3e2cf8.tar.gz
abseil-6f0c500453dd911018bd5cfb46999cee5e3e2cf8.tar.bz2
abseil-6f0c500453dd911018bd5cfb46999cee5e3e2cf8.zip
Refactor the GCC unintialized memory warning suppression in raw_hash_set.h.
Motivation: there are new uninitialized memory warnings when we enable small object optimization. PiperOrigin-RevId: 619295212 Change-Id: If10762bab0e43c9619fc03f6d1eef5b8836bbf9a
Diffstat (limited to 'absl/container/internal')
-rw-r--r--absl/container/internal/raw_hash_set.h88
1 files changed, 52 insertions, 36 deletions
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index da2ee1c5..af75e7fb 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -1131,24 +1131,27 @@ struct soo_tag_t {};
// Sentinel type to indicate SOO CommonFields construction with full size.
struct full_soo_tag_t {};
+// Suppress erroneous uninitialized memory errors on GCC. For example, GCC
+// thinks that the call to slot_array() in find_or_prepare_insert() is reading
+// uninitialized memory, but slot_array is only called there when the table is
+// non-empty and this memory is initialized when the table is non-empty.
+#if !defined(__clang__) && defined(__GNUC__)
+#define ABSL_SWISSTABLE_IGNORE_UNINITIALIZED(x) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") \
+ _Pragma("GCC diagnostic ignored \"-Wuninitialized\"") x; \
+ _Pragma("GCC diagnostic pop")
+#define ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(x) \
+ ABSL_SWISSTABLE_IGNORE_UNINITIALIZED(return x)
+#else
+#define ABSL_SWISSTABLE_IGNORE_UNINITIALIZED(x) x
+#define ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(x) return x
+#endif
+
// This allows us to work around an uninitialized memory warning when
// constructing begin() iterators in empty hashtables.
union MaybeInitializedPtr {
- void* get() const {
- // Suppress erroneous uninitialized memory errors on GCC. GCC thinks that
- // the call to slot_array() in find_or_prepare_insert() is reading
- // uninitialized memory, but slot_array is only called there when the table
- // is non-empty and this memory is initialized when the table is non-empty.
-#if !defined(__clang__) && defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
-#pragma GCC diagnostic ignored "-Wuninitialized"
-#endif
- return p;
-#if !defined(__clang__) && defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
- }
+ void* get() const { ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(p); }
void set(void* ptr) { p = ptr; }
void* p;
@@ -1180,6 +1183,25 @@ union HeapOrSoo {
HeapOrSoo() = default;
explicit HeapOrSoo(ctrl_t* c) : heap(c) {}
+ ctrl_t*& control() {
+ ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(heap.control);
+ }
+ ctrl_t* control() const {
+ ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(heap.control);
+ }
+ MaybeInitializedPtr& slot_array() {
+ ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(heap.slot_array);
+ }
+ MaybeInitializedPtr slot_array() const {
+ ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(heap.slot_array);
+ }
+ void* get_soo_data() {
+ ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(soo_data);
+ }
+ const void* get_soo_data() const {
+ ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(soo_data);
+ }
+
HeapPtrs heap;
unsigned char soo_data[sizeof(HeapPtrs)];
};
@@ -1208,14 +1230,14 @@ class CommonFields : public CommonFieldsGenerationInfo {
}
// The inline data for SOO is written on top of control_/slots_.
- const void* soo_data() const { return heap_or_soo_.soo_data; }
- void* soo_data() { return heap_or_soo_.soo_data; }
+ const void* soo_data() const { return heap_or_soo_.get_soo_data(); }
+ void* soo_data() { return heap_or_soo_.get_soo_data(); }
HeapOrSoo heap_or_soo() const { return heap_or_soo_; }
const HeapOrSoo& heap_or_soo_ref() const { return heap_or_soo_; }
- ctrl_t* control() const { return heap_or_soo_.heap.control; }
- void set_control(ctrl_t* c) { heap_or_soo_.heap.control = c; }
+ ctrl_t* control() const { return heap_or_soo_.control(); }
+ void set_control(ctrl_t* c) { heap_or_soo_.control() = c; }
void* backing_array_start() const {
// growth_left (and maybe infoz) is stored before control bytes.
assert(reinterpret_cast<uintptr_t>(control()) % alignof(size_t) == 0);
@@ -1223,19 +1245,9 @@ class CommonFields : public CommonFieldsGenerationInfo {
}
// Note: we can't use slots() because Qt defines "slots" as a macro.
- void* slot_array() const { return heap_or_soo_.heap.slot_array.get(); }
- MaybeInitializedPtr slots_union() const {
- // Suppress erroneous uninitialized memory errors on GCC.
-#if !defined(__clang__) && defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
-#endif
- return heap_or_soo_.heap.slot_array;
-#if !defined(__clang__) && defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
- }
- void set_slots(void* s) { heap_or_soo_.heap.slot_array.set(s); }
+ void* slot_array() const { return heap_or_soo_.slot_array().get(); }
+ MaybeInitializedPtr slots_union() const { return heap_or_soo_.slot_array(); }
+ void set_slots(void* s) { heap_or_soo_.slot_array().set(s); }
// The number of filled slots.
size_t size() const { return size_ >> HasInfozShift(); }
@@ -1850,14 +1862,14 @@ class HashSetResizeHelper {
}
HeapOrSoo& old_heap_or_soo() { return old_heap_or_soo_; }
- void* old_soo_data() { return old_heap_or_soo_.soo_data; }
+ void* old_soo_data() { return old_heap_or_soo_.get_soo_data(); }
ctrl_t* old_ctrl() const {
assert(!was_soo_);
- return old_heap_or_soo_.heap.control;
+ return old_heap_or_soo_.control();
}
void* old_slots() const {
assert(!was_soo_);
- return old_heap_or_soo_.heap.slot_array.get();
+ return old_heap_or_soo_.slot_array().get();
}
size_t old_capacity() const { return old_capacity_; }
@@ -3393,7 +3405,9 @@ class raw_hash_set {
inline void destructor_impl() {
if (capacity() == 0) return;
if (is_soo()) {
- if (!empty()) destroy(soo_slot());
+ if (!empty()) {
+ ABSL_SWISSTABLE_IGNORE_UNINITIALIZED(destroy(soo_slot()));
+ }
return;
}
destroy_slots();
@@ -3977,5 +3991,7 @@ ABSL_NAMESPACE_END
} // namespace absl
#undef ABSL_SWISSTABLE_ENABLE_GENERATIONS
+#undef ABSL_SWISSTABLE_IGNORE_UNINITIALIZED
+#undef ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN
#endif // ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_