diff options
author | Daniel Bertalan <dani@danielbertalan.dev> | 2021-07-01 11:29:28 +0200 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2021-07-03 01:56:31 +0430 |
commit | b9f30c6f2a69b0c07d9a61e5dd81f439a1eafc8f (patch) | |
tree | e46fd572856b1be2280348ad03af3853fa6fc183 /AK/Optional.h | |
parent | 45a82b2a5bd64eb73bb68f1b8a156303edbd29fe (diff) | |
download | serenity-b9f30c6f2a69b0c07d9a61e5dd81f439a1eafc8f.zip |
Everywhere: Fix some alignment issues
When creating uninitialized storage for variables, we need to make sure
that the alignment is correct. Fixes a KUBSAN failure when running
kernels compiled with Clang.
In `Syscalls/socket.cpp`, we can simply use local variables, as
`sockaddr_un` is a POD type.
Along with moving the `alignas` specifier to the correct member,
`AK::Optional`'s internal buffer has been made non-zeroed by default.
GCC emitted bogus uninitialized memory access warnings, so we now use
`__builtin_launder` to tell the compiler that we know what we are doing.
This might disable some optimizations, but judging by how GCC failed to
notice that the memory's initialization is dependent on `m_has_value`,
I'm not sure that's a bad thing.
Diffstat (limited to 'AK/Optional.h')
-rw-r--r-- | AK/Optional.h | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/AK/Optional.h b/AK/Optional.h index 6b8a987006..7348fe9a78 100644 --- a/AK/Optional.h +++ b/AK/Optional.h @@ -14,7 +14,7 @@ namespace AK { template<typename T> -class alignas(T) [[nodiscard]] Optional { +class [[nodiscard]] Optional { public: using ValueType = T; @@ -132,13 +132,13 @@ public: [[nodiscard]] ALWAYS_INLINE T& value() { VERIFY(m_has_value); - return *reinterpret_cast<T*>(&m_storage); + return *__builtin_launder(reinterpret_cast<T*>(&m_storage)); } [[nodiscard]] ALWAYS_INLINE const T& value() const { VERIFY(m_has_value); - return *reinterpret_cast<const T*>(&m_storage); + return *__builtin_launder(reinterpret_cast<const T*>(&m_storage)); } [[nodiscard]] T release_value() @@ -164,7 +164,7 @@ public: ALWAYS_INLINE T* operator->() { return &value(); } private: - u8 m_storage[sizeof(T)] { 0 }; + alignas(T) u8 m_storage[sizeof(T)]; bool m_has_value { false }; }; |