d942bc80e4
When the contained value is not trivially copy (or move) constructible the union's copy (or move) constructor will be deleted, and so the _Optional_payload delegating constructors are invalid. G++ fails to diagnose this because it incorrectly performs copy elision in the delegating constructors. Clang does diagnose it (llvm.org/PR40245). The solution is to avoid performing any copy (or move) when the contained value's copy (or move) constructor isn't trivial. Instead the contained value can be constructed by calling _M_construct. This is OK, because the relevant constructor doesn't need to be constexpr when the contained value isn't trivially copy (or move) constructible. Additionally, this patch removes a lot of code duplication in the _Optional_payload partial specializations and the _Optional_base partial specialization, by hoisting it into common base classes. The Python pretty printer for std::optional needs to be adjusted to support the new layout. Retain support for the old layout, and add a test to verify that the support still works. PR libstdc++/87855 * include/std/optional (_Optional_payload_base): New class template for common code hoisted from _Optional_payload specializations. Use a template for the union, to allow a partial specialization for types with non-trivial destructors. Add constructors for in-place initialization to the union. (_Optional_payload(bool, const _Optional_payload&)): Use _M_construct to perform non-trivial copy construction, instead of relying on non-standard copy elision in a delegating constructor. (_Optional_payload(bool, _Optional_payload&&)): Likewise for non-trivial move construction. (_Optional_payload): Derive from _Optional_payload_base and use it for everything except the non-trivial assignment operators, which are defined as needed. (_Optional_payload<false, C, M>): Derive from the specialization _Optional_payload<true, false, false> and add a destructor. (_Optional_base_impl::_M_destruct, _Optional_base_impl::_M_reset): Forward to corresponding members of _Optional_payload. (_Optional_base_impl::_M_is_engaged, _Optional_base_impl::_M_get): Hoist common members from _Optional_base. (_Optional_base): Make all members and base class public. (_Optional_base::_M_get, _Optional_base::_M_is_engaged): Move to _Optional_base_impl. * python/libstdcxx/v6/printers.py (StdExpOptionalPrinter): Add support for new std::optional layout. * testsuite/libstdc++-prettyprinters/compat.cc: New test. From-SVN: r267742 |
||
---|---|---|
.. | ||
libstdcxx | ||
hook.in | ||
Makefile.am | ||
Makefile.in |