https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87855
--- Comment #22 from Jonathan Wakely <redi at gcc dot gnu.org> --- Author: redi Date: Wed Jan 9 10:17:10 2019 New Revision: 267759 URL: https://gcc.gnu.org/viewcvs?rev=267759&root=gcc&view=rev Log: PR libstdc++/87855 fix optional for types with non-trivial copy/move Backport both parts of the fix for PR libstdc++/87855, as well as a test tweak from r263657 to avoid having to adjust dg-error line numbers. * testsuite/20_util/optional/cons/value_neg.cc: Change dg-error to dg-prune-output. Remove unused header. Backport from mainline 2019-01-08 Jonathan Wakely <jwak...@redhat.com> 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. Backport from mainline 2018-11-19 Ville Voutilainen <ville.voutilai...@gmail.com> PR libstdc++/87855 Also implement P0602R4 (variant and optional should propagate copy/move triviality) for std::optional. * include/std/optional (_Optional_payload): Change the main constraints to check constructibility in addition to assignability. (operator=): Make constexpr. (_M_reset): Likewise. (_M_construct): Likewise. (operator->): Likewise. * testsuite/20_util/optional/assignment/8.cc: Adjust. * testsuite/20_util/optional/assignment/9.cc: New. Added: branches/gcc-8-branch/libstdc++-v3/testsuite/20_util/optional/assignment/9.cc Modified: branches/gcc-8-branch/libstdc++-v3/ChangeLog branches/gcc-8-branch/libstdc++-v3/include/std/optional branches/gcc-8-branch/libstdc++-v3/testsuite/20_util/optional/assignment/8.cc branches/gcc-8-branch/libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc