[libc++] Simplify the string structures a bit more

This simplifies the string structs a bit more and the normal layout should not contain any undefined behaviour anymore. I don't think there is a way to achieve this in the alternate string mode without breaking the ABI.

Reviewed By: ldionne, #libc

Spies: libcxx-commits

Differential Revision: https://reviews.llvm.org/D125496
This commit is contained in:
Nikolas Klauser 2022-05-14 12:38:00 +02:00
parent 9d99cf59a1
commit 5d55ffe94d
1 changed files with 8 additions and 13 deletions

View File

@ -672,6 +672,7 @@ public:
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
private: private:
static_assert(CHAR_BIT == 8, "This implementation assumes that one byte contains 8 bits");
#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT #ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
@ -689,14 +690,13 @@ private:
struct __short struct __short
{ {
value_type __data_[__min_cap]; value_type __data_[__min_cap];
unsigned char __padding[sizeof(value_type) - 1]; unsigned char __padding_[sizeof(value_type) - 1];
unsigned char __size_ : 7; size_type __size_ : 7;
unsigned char __is_long_ : 1; size_type __is_long_ : 1;
}; };
// The __endian_factor is required because the field we use to store the size // The __endian_factor is required because the field we use to store the size
// (either size_type or unsigned char depending on long/short) has one fewer // has one fewer bit than it would if it were not a bitfield.
// bit than it would if it were not a bitfield.
// //
// If the LSB is used to store the short-flag in the short string representation, // If the LSB is used to store the short-flag in the short string representation,
// we have to multiply the size by two when it is stored and divide it by two when // we have to multiply the size by two when it is stored and divide it by two when
@ -735,14 +735,9 @@ private:
struct __short struct __short
{ {
union size_type __is_long_ : 1;
{ size_type __size_ : 7;
struct { char __padding_[sizeof(value_type) - 1];
unsigned char __is_long_ : 1;
unsigned char __size_ : 7;
};
value_type __lx;
};
value_type __data_[__min_cap]; value_type __data_[__min_cap];
}; };