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
* detect_ssl uses bool
* launder pointers
--------------------------------------------------------------------------------

View File

@@ -124,6 +124,18 @@ struct is_contiguous_container<T, E, void_t<
>::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
} // beast
} // boost

View File

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

View File

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