PR #1860: Add unsigned to character buffers to ensure they can provide storage (https://eel.is/c++draft/intro.object#3)

Imported from GitHub PR https://github.com/abseil/abseil-cpp/pull/1860

I just learned today that `char` cannot "provide storage" in the way I previously thought. Only `std::byte` and `unsigned char` are allowed. So I decided to fix my past mistakes in `absl::InlinedVector` and `absl::Cleanup` as well as any others I could find in Abseil. See: https://eel.is/c++draft/intro.object#3

Merge ae9c1ef57a into c4ff4d561c

Merging this change closes #1860

COPYBARA_INTEGRATE_REVIEW=https://github.com/abseil/abseil-cpp/pull/1860 from CJ-Johnson:master ae9c1ef57a
PiperOrigin-RevId: 739220589
Change-Id: I533b040e4cf4ee2f48008affb6603c25f34d5b4b
This commit is contained in:
CJ Johnson
2025-03-21 10:10:53 -07:00
committed by Copybara-Service
parent d95be7ff22
commit 930a70d12e
8 changed files with 13 additions and 12 deletions

View File

@@ -88,7 +88,7 @@ class Storage {
private:
bool is_callback_engaged_;
alignas(Callback) char callback_buffer_[sizeof(Callback)];
alignas(Callback) unsigned char callback_buffer_[sizeof(Callback)];
};
} // namespace cleanup_internal

View File

@@ -447,7 +447,8 @@ class ABSL_ATTRIBUTE_WARN_UNUSED FixedArray {
private:
ABSL_ADDRESS_SANITIZER_REDZONE(redzone_begin_);
alignas(StorageElement) char buff_[sizeof(StorageElement[inline_elements])];
alignas(StorageElement) unsigned char buff_[sizeof(
StorageElement[inline_elements])];
ABSL_ADDRESS_SANITIZER_REDZONE(redzone_end_);
};

View File

@@ -543,7 +543,7 @@ class Storage {
(std::max)(N, sizeof(Allocated) / sizeof(ValueType<A>));
struct Inlined {
alignas(ValueType<A>) char inlined_data[sizeof(
alignas(ValueType<A>) unsigned char inlined_data[sizeof(
ValueType<A>[kOptimalInlinedSize])];
};

View File

@@ -783,7 +783,7 @@ class FlagImpl final : public CommandLineFlag {
// heap allocation during initialization, which is both slows program startup
// and can fail. Using reserved space + placement new allows us to avoid both
// problems.
alignas(absl::Mutex) mutable char data_guard_[sizeof(absl::Mutex)];
alignas(absl::Mutex) mutable unsigned char data_guard_[sizeof(absl::Mutex)];
};
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
@@ -876,7 +876,8 @@ class FlagImplPeer {
template <typename T>
void* FlagOps(FlagOp op, const void* v1, void* v2, void* v3) {
struct AlignedSpace {
alignas(MaskedPointer::RequiredAlignment()) alignas(T) char buf[sizeof(T)];
alignas(MaskedPointer::RequiredAlignment()) alignas(
T) unsigned char buf[sizeof(T)];
};
using Allocator = std::allocator<AlignedSpace>;
switch (op) {

View File

@@ -73,7 +73,7 @@ void FinalizeRegistry();
//
// Retire flag with name "name" and type indicated by ops.
void Retire(const char* name, FlagFastTypeId type_id, char* buf);
void Retire(const char* name, FlagFastTypeId type_id, unsigned char* buf);
constexpr size_t kRetiredFlagObjSize = 3 * sizeof(void*);
constexpr size_t kRetiredFlagObjAlignment = alignof(void*);
@@ -87,7 +87,7 @@ class RetiredFlag {
}
private:
alignas(kRetiredFlagObjAlignment) char buf_[kRetiredFlagObjSize];
alignas(kRetiredFlagObjAlignment) unsigned char buf_[kRetiredFlagObjSize];
};
} // namespace flags_internal

View File

@@ -289,11 +289,10 @@ class RetiredFlagObj final : public CommandLineFlag {
} // namespace
void Retire(const char* name, FlagFastTypeId type_id, char* buf) {
void Retire(const char* name, FlagFastTypeId type_id, unsigned char* buf) {
static_assert(sizeof(RetiredFlagObj) == kRetiredFlagObjSize, "");
static_assert(alignof(RetiredFlagObj) == kRetiredFlagObjAlignment, "");
auto* flag = ::new (static_cast<void*>(buf))
flags_internal::RetiredFlagObj(name, type_id);
auto* flag = ::new (buf) flags_internal::RetiredFlagObj(name, type_id);
FlagRegistry::GlobalRegistry().RegisterFlag(*flag, nullptr);
}

View File

@@ -174,7 +174,7 @@ union TypeErasedState {
} remote;
// Local-storage for the type-erased object when small and trivial enough
alignas(kAlignment) char storage[kStorageSize];
alignas(kAlignment) unsigned char storage[kStorageSize];
};
// A typed accessor for the object in `TypeErasedState` storage

View File

@@ -1725,7 +1725,7 @@ TEST(Mutex, Logging) {
TEST(Mutex, LoggingAddressReuse) {
// Repeatedly re-create a Mutex with debug logging at the same address.
ScopedInvariantDebugging scoped_debugging;
alignas(absl::Mutex) char storage[sizeof(absl::Mutex)];
alignas(absl::Mutex) unsigned char storage[sizeof(absl::Mutex)];
auto invariant =
+[](void *alive) { EXPECT_TRUE(*static_cast<bool *>(alive)); };
constexpr size_t kIters = 10;