launder pointers:

close #1570

`std::launder` must be used whenever placement-new of an unknown type
is performed and the result of the placement-new expression is discarded.

Signed-off-by: Damian Jarek <damian.jarek93@gmail.com>
This commit is contained in:
Damian Jarek
2019-04-13 01:38:10 +02:00
committed by Vinnie Falco
parent 9b10f08692
commit 8703038e37
4 changed files with 27 additions and 14 deletions

View File

@@ -2,6 +2,7 @@ Version 251:
* Clean up CI scripts * Clean up CI scripts
* detect_ssl uses bool * detect_ssl uses bool
* launder pointers
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@@ -124,6 +124,18 @@ struct is_contiguous_container<T, E, void_t<
>::type>>: std::true_type >::type>>: std::true_type
{}; {};
template <class T, class U>
T launder_cast(U* u)
{
#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
return std::launder(reinterpret_cast<T>(u));
#elif defined(BOOST_GCC) && BOOST_GCC_VERSION > 80000
return __builtin_launder(reinterpret_cast<T>(u));
#else
return reinterpret_cast<T>(u);
#endif
}
} // detail } // detail
} // beast } // beast
} // boost } // boost

View File

@@ -45,7 +45,7 @@ class variant
{ {
using T = using T =
mp11::mp_at_c<variant, I::value - 1>; mp11::mp_at_c<variant, I::value - 1>;
reinterpret_cast<T&>(self.buf_).~T(); detail::launder_cast<T*>(&self.buf_)->~T();
} }
}; };
@@ -64,7 +64,7 @@ class variant
using T = using T =
mp11::mp_at_c<variant, I::value - 1>; mp11::mp_at_c<variant, I::value - 1>;
::new(&self.buf_) T( ::new(&self.buf_) T(
reinterpret_cast<T const&>(other.buf_)); *detail::launder_cast<T const*>(&other.buf_));
self.i_ = I::value; self.i_ = I::value;
} }
}; };
@@ -83,9 +83,9 @@ class variant
{ {
using T = using T =
mp11::mp_at_c<variant, I::value - 1>; mp11::mp_at_c<variant, I::value - 1>;
::new(&self.buf_) T( ::new(&self.buf_) T(std::move(
reinterpret_cast<T&&>(other.buf_)); *detail::launder_cast<T*>(&other.buf_)));
reinterpret_cast<T&>(other.buf_).~T(); detail::launder_cast<T*>(&other.buf_)->~T();
self.i_ = I::value; self.i_ = I::value;
} }
}; };
@@ -106,8 +106,8 @@ class variant
using T = using T =
mp11::mp_at_c<variant, I::value - 1>; mp11::mp_at_c<variant, I::value - 1>;
return return
reinterpret_cast<T const&>(self.buf_) == *detail::launder_cast<T const*>(&self.buf_) ==
reinterpret_cast<T const&>(other.buf_); *detail::launder_cast<T const*>(&other.buf_);
} }
}; };
@@ -208,7 +208,7 @@ public:
get() get()
{ {
BOOST_ASSERT(i_ == I); BOOST_ASSERT(i_ == I);
return *reinterpret_cast< return *detail::launder_cast<
mp11::mp_at_c<variant, I - 1>*>(&buf_); mp11::mp_at_c<variant, I - 1>*>(&buf_);
} }
@@ -217,7 +217,7 @@ public:
get() const get() const
{ {
BOOST_ASSERT(i_ == I); BOOST_ASSERT(i_ == I);
return *reinterpret_cast< return *detail::launder_cast<
mp11::mp_at_c<variant, I - 1> const*>(&buf_); mp11::mp_at_c<variant, I - 1> const*>(&buf_);
} }

View File

@@ -213,7 +213,7 @@ struct decorator::vtable_impl<F, true>
void void
move(storage& dst, storage& src) noexcept move(storage& dst, storage& src) noexcept
{ {
auto& f = *reinterpret_cast<F*>(&src.buf_); auto& f = *beast::detail::launder_cast<F*>(&src.buf_);
::new (&dst.buf_) F(std::move(f)); ::new (&dst.buf_) F(std::move(f));
} }
@@ -221,7 +221,7 @@ struct decorator::vtable_impl<F, true>
void void
destroy(storage& dst) noexcept destroy(storage& dst) noexcept
{ {
reinterpret_cast<F*>(&dst.buf_)->~F(); beast::detail::launder_cast<F*>(&dst.buf_)->~F();
} }
static static
@@ -229,7 +229,7 @@ struct decorator::vtable_impl<F, true>
invoke_req(storage& dst, request_type& req) invoke_req(storage& dst, request_type& req)
{ {
maybe_invoke<F, request_type>{}( maybe_invoke<F, request_type>{}(
*reinterpret_cast<F*>(&dst.buf_), req); *beast::detail::launder_cast<F*>(&dst.buf_), req);
} }
static static
@@ -237,7 +237,7 @@ struct decorator::vtable_impl<F, true>
invoke_res(storage& dst, response_type& res) invoke_res(storage& dst, response_type& res)
{ {
maybe_invoke<F, response_type>{}( maybe_invoke<F, response_type>{}(
*reinterpret_cast<F*>(&dst.buf_), res); *beast::detail::launder_cast<F*>(&dst.buf_), res);
} }
static static