summaryrefslogtreecommitdiff
path: root/AK/Optional.h
diff options
context:
space:
mode:
authorDaniel Bertalan <dani@danielbertalan.dev>2021-07-01 11:29:28 +0200
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2021-07-03 01:56:31 +0430
commitb9f30c6f2a69b0c07d9a61e5dd81f439a1eafc8f (patch)
treee46fd572856b1be2280348ad03af3853fa6fc183 /AK/Optional.h
parent45a82b2a5bd64eb73bb68f1b8a156303edbd29fe (diff)
downloadserenity-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.h8
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 };
};