diff options
| author | Liam <byteslice@airmail.cc> | 2022-07-09 20:33:03 -0400 | 
|---|---|---|
| committer | Liam <byteslice@airmail.cc> | 2022-07-09 22:43:45 -0400 | 
| commit | a1c1ad096d23d76de2924ce299ecd49e66674e77 (patch) | |
| tree | 2da5d6548a80d05831010160182d07a2f6546aa2 | |
| parent | 313f047f974249c0fa004056ced3f18a8c61eae4 (diff) | |
common: fix bitfield aliasing on GCC/Clang
| -rw-r--r-- | src/common/bit_field.h | 9 | 
1 files changed, 9 insertions, 0 deletions
| diff --git a/src/common/bit_field.h b/src/common/bit_field.h index 16d805694..7e1df62b1 100644 --- a/src/common/bit_field.h +++ b/src/common/bit_field.h @@ -146,7 +146,16 @@ public:      }      constexpr void Assign(const T& value) { +#ifdef _MSC_VER          storage = static_cast<StorageType>((storage & ~mask) | FormatValue(value)); +#else +        // Explicitly reload with memcpy to avoid compiler aliasing quirks +        // regarding optimization: GCC/Clang clobber chained stores to +        // different bitfields in the same struct with the last value. +        StorageTypeWithEndian storage_; +        std::memcpy(&storage_, &storage, sizeof(storage_)); +        storage = static_cast<StorageType>((storage_ & ~mask) | FormatValue(value)); +#endif      }      [[nodiscard]] constexpr T Value() const { | 
