diff options
| author | 2022-07-09 20:33:03 -0400 | |
|---|---|---|
| committer | 2022-07-09 22:43:45 -0400 | |
| commit | a1c1ad096d23d76de2924ce299ecd49e66674e77 (patch) | |
| tree | 2da5d6548a80d05831010160182d07a2f6546aa2 /src/common/bit_field.h | |
| parent | Merge pull request #8501 from liamwhite/backtrace-again (diff) | |
| download | yuzu-a1c1ad096d23d76de2924ce299ecd49e66674e77.tar.gz yuzu-a1c1ad096d23d76de2924ce299ecd49e66674e77.tar.xz yuzu-a1c1ad096d23d76de2924ce299ecd49e66674e77.zip | |
common: fix bitfield aliasing on GCC/Clang
Diffstat (limited to 'src/common/bit_field.h')
| -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: | |||
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | constexpr void Assign(const T& value) { | 148 | constexpr void Assign(const T& value) { |
| 149 | #ifdef _MSC_VER | ||
| 149 | storage = static_cast<StorageType>((storage & ~mask) | FormatValue(value)); | 150 | storage = static_cast<StorageType>((storage & ~mask) | FormatValue(value)); |
| 151 | #else | ||
| 152 | // Explicitly reload with memcpy to avoid compiler aliasing quirks | ||
| 153 | // regarding optimization: GCC/Clang clobber chained stores to | ||
| 154 | // different bitfields in the same struct with the last value. | ||
| 155 | StorageTypeWithEndian storage_; | ||
| 156 | std::memcpy(&storage_, &storage, sizeof(storage_)); | ||
| 157 | storage = static_cast<StorageType>((storage_ & ~mask) | FormatValue(value)); | ||
| 158 | #endif | ||
| 150 | } | 159 | } |
| 151 | 160 | ||
| 152 | [[nodiscard]] constexpr T Value() const { | 161 | [[nodiscard]] constexpr T Value() const { |