diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-03-18 22:31:59 +0100 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-03-18 22:39:35 +0100 |
commit | 4884b594330dea41d04d776d14a5cb18d9a354bc (patch) | |
tree | b159defa21f10017baab0800c3848b3e9706940c /asl | |
parent | a7475b6af21717f59c1b3d0dcb0fd6c1198a9fdc (diff) |
Make status implementation more correct wrt type punning
Diffstat (limited to 'asl')
-rw-r--r-- | asl/base/utility.hpp | 7 | ||||
-rw-r--r-- | asl/containers/buffer.hpp | 4 | ||||
-rw-r--r-- | asl/types/status.cpp | 21 | ||||
-rw-r--r-- | asl/types/status.hpp | 8 |
4 files changed, 23 insertions, 17 deletions
diff --git a/asl/base/utility.hpp b/asl/base/utility.hpp index 206a5b1..85c873d 100644 --- a/asl/base/utility.hpp +++ b/asl/base/utility.hpp @@ -35,6 +35,13 @@ template<typename T, typename U> return static_cast<return_type>(x); } +template<typename T> +[[nodiscard]] constexpr T* launder(T* ptr) noexcept // NOLINT + requires (!asl::is_func<T> && !asl::is_void<T>) +{ + return __builtin_launder(ptr); +} + } // namespace std namespace asl diff --git a/asl/containers/buffer.hpp b/asl/containers/buffer.hpp index c3d865f..f5ba975 100644 --- a/asl/containers/buffer.hpp +++ b/asl/containers/buffer.hpp @@ -110,7 +110,9 @@ private: constexpr void set_size_inline(isize_t new_size) { ASL_ASSERT(new_size >= 0 && new_size <= kInlineCapacity); - const size_t size_encoded = (load_size_encoded() & size_t{0x00ff'ffff'ffff'ffff}) | (bit_cast<size_t>(new_size) << 56U); + const size_t size_encoded = + (load_size_encoded() & size_t{0x00ff'ffff'ffff'ffff}) + | (bit_cast<size_t>(new_size) << 56U); store_size_encoded(size_encoded); } diff --git a/asl/types/status.cpp b/asl/types/status.cpp index 43f3b9e..246d017 100644 --- a/asl/types/status.cpp +++ b/asl/types/status.cpp @@ -15,7 +15,7 @@ using Allocator = asl::DefaultAllocator; // NOLINTNEXTLINE(*-non-const-global-variables) static Allocator g_allocator{}; -namespace +namespace asl { struct StatusInternal @@ -33,7 +33,7 @@ struct StatusInternal } }; -} // anonymous namespace +} // namespace asl asl::status::status(status_code code, string_view msg) : m_payload{alloc_new<StatusInternal>(g_allocator, msg, code)} @@ -49,34 +49,29 @@ asl::status::status(status_code code, string_view fmt, span<format_internals::ty asl::status_code asl::status::code_internal() const { ASL_ASSERT(!is_inline()); - // NOLINTNEXTLINE(*-reinterpret-cast) - return reinterpret_cast<const StatusInternal*>(m_payload)->code; + return m_payload->code; } asl::string_view asl::status::message_internal() const { ASL_ASSERT(!is_inline()); - // NOLINTNEXTLINE(*-reinterpret-cast) - return reinterpret_cast<const StatusInternal*>(m_payload)->msg; + return m_payload->msg; } void asl::status::ref() { ASL_ASSERT(!is_inline()); - // NOLINTNEXTLINE(*-reinterpret-cast) - auto* internal = reinterpret_cast<StatusInternal*>(m_payload); - atomic_fetch_increment(&internal->ref_count, memory_order::relaxed); + atomic_fetch_increment(&m_payload->ref_count, memory_order::relaxed); } void asl::status::unref() { ASL_ASSERT(!is_inline()); - // NOLINTNEXTLINE(*-reinterpret-cast) - auto* internal = reinterpret_cast<StatusInternal*>(m_payload); - if (atomic_fetch_decrement(&internal->ref_count, memory_order::release) == 1) + if (atomic_fetch_decrement(&m_payload->ref_count, memory_order::release) == 1) { atomic_fence(memory_order::acquire); - alloc_delete(g_allocator, internal); + alloc_delete(g_allocator, m_payload); + m_payload = nullptr; } } diff --git a/asl/types/status.hpp b/asl/types/status.hpp index df96cd8..de95670 100644 --- a/asl/types/status.hpp +++ b/asl/types/status.hpp @@ -22,15 +22,17 @@ enum class status_code : uint8_t invalid_argument = 4, }; +struct StatusInternal; + class status { - void* m_payload{}; + StatusInternal* m_payload{}; - static constexpr void* status_to_payload(status_code code) + static constexpr StatusInternal* status_to_payload(status_code code) { return code == status_code::ok ? nullptr - : bit_cast<void*>((static_cast<uintptr_t>(code) << 1) | 1); + : bit_cast<StatusInternal*>((static_cast<uintptr_t>(code) << 1) | 1); } static constexpr status_code payload_to_status(void* payload) |