diff --git a/CHANGELOG.md b/CHANGELOG.md index a69f5598..07b82bf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Version 251: * Clean up CI scripts * detect_ssl uses bool +* launder pointers -------------------------------------------------------------------------------- diff --git a/include/boost/beast/core/detail/type_traits.hpp b/include/boost/beast/core/detail/type_traits.hpp index 3d895403..31bcda17 100644 --- a/include/boost/beast/core/detail/type_traits.hpp +++ b/include/boost/beast/core/detail/type_traits.hpp @@ -124,6 +124,18 @@ struct is_contiguous_container::type>>: std::true_type {}; +template +T launder_cast(U* u) +{ +#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606 + return std::launder(reinterpret_cast(u)); +#elif defined(BOOST_GCC) && BOOST_GCC_VERSION > 80000 + return __builtin_launder(reinterpret_cast(u)); +#else + return reinterpret_cast(u); +#endif +} + } // detail } // beast } // boost diff --git a/include/boost/beast/core/detail/variant.hpp b/include/boost/beast/core/detail/variant.hpp index 94bd4c04..f6f5b3c6 100644 --- a/include/boost/beast/core/detail/variant.hpp +++ b/include/boost/beast/core/detail/variant.hpp @@ -45,7 +45,7 @@ class variant { using T = mp11::mp_at_c; - reinterpret_cast(self.buf_).~T(); + detail::launder_cast(&self.buf_)->~T(); } }; @@ -64,7 +64,7 @@ class variant using T = mp11::mp_at_c; ::new(&self.buf_) T( - reinterpret_cast(other.buf_)); + *detail::launder_cast(&other.buf_)); self.i_ = I::value; } }; @@ -83,9 +83,9 @@ class variant { using T = mp11::mp_at_c; - ::new(&self.buf_) T( - reinterpret_cast(other.buf_)); - reinterpret_cast(other.buf_).~T(); + ::new(&self.buf_) T(std::move( + *detail::launder_cast(&other.buf_))); + detail::launder_cast(&other.buf_)->~T(); self.i_ = I::value; } }; @@ -106,8 +106,8 @@ class variant using T = mp11::mp_at_c; return - reinterpret_cast(self.buf_) == - reinterpret_cast(other.buf_); + *detail::launder_cast(&self.buf_) == + *detail::launder_cast(&other.buf_); } }; @@ -181,7 +181,7 @@ public: } return *this; } - + variant& operator=(variant const& other) { if(this != &other) @@ -208,7 +208,7 @@ public: get() { BOOST_ASSERT(i_ == I); - return *reinterpret_cast< + return *detail::launder_cast< mp11::mp_at_c*>(&buf_); } @@ -217,7 +217,7 @@ public: get() const { BOOST_ASSERT(i_ == I); - return *reinterpret_cast< + return *detail::launder_cast< mp11::mp_at_c const*>(&buf_); } diff --git a/include/boost/beast/websocket/detail/decorator.hpp b/include/boost/beast/websocket/detail/decorator.hpp index cab7f9a2..b4b512de 100644 --- a/include/boost/beast/websocket/detail/decorator.hpp +++ b/include/boost/beast/websocket/detail/decorator.hpp @@ -213,7 +213,7 @@ struct decorator::vtable_impl void move(storage& dst, storage& src) noexcept { - auto& f = *reinterpret_cast(&src.buf_); + auto& f = *beast::detail::launder_cast(&src.buf_); ::new (&dst.buf_) F(std::move(f)); } @@ -221,7 +221,7 @@ struct decorator::vtable_impl void destroy(storage& dst) noexcept { - reinterpret_cast(&dst.buf_)->~F(); + beast::detail::launder_cast(&dst.buf_)->~F(); } static @@ -229,7 +229,7 @@ struct decorator::vtable_impl invoke_req(storage& dst, request_type& req) { maybe_invoke{}( - *reinterpret_cast(&dst.buf_), req); + *beast::detail::launder_cast(&dst.buf_), req); } static @@ -237,7 +237,7 @@ struct decorator::vtable_impl invoke_res(storage& dst, response_type& res) { maybe_invoke{}( - *reinterpret_cast(&dst.buf_), res); + *beast::detail::launder_cast(&dst.buf_), res); } static