https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87855

            Bug ID: 87855
           Summary: std::optional<T> only copy-constructible if T is
                    trivially copy-constructible
           Product: gcc
           Version: 8.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: fiesh at zefix dot tv
  Target Milestone: ---

For a type T that is non-trivially copy constructible, std::optional<T> is not
copy constructible.  However, only clang catches this behavior.  I think clang
is right in doing so because a union's copy constructor is deleted if at least
one of its members has a non-trivial one.  (If this is true, is it a separate
gcc bug that it does not delete the union's constructor?)

The following program exemplifies this:

#include <optional>

struct S
{
        S() = default;
        S(S const &) {}
};

void f()
{
        using T = std::optional<S>;

        const T t0;

        const auto t1 = t0;
        (void) t1;
}

clang reports:

/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include/g++-v8/optional:268:9: error:
call to implicitly-deleted copy constructor of 'std::_Optional_payload<S,
true, true, true>'
      : _Optional_payload(__engaged ?
        ^                 ~~~~~~~~~~~
/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include/g++-v8/optional:733:4: note: in
instantiation of member function 'std::_Optional_payload<S, true, true,
true>::_Optional_payload' requested here
        : _M_payload(__other._M_payload._M_engaged,
          ^
/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include/g++-v8/optional:985:11: note: in
instantiation of member function 'std::_Optional_base<S, false, false>:
:_Optional_base' requested here
    class optional
          ^
/tmp/t.cpp:15:18: note: in implicit copy constructor for 'std::optional<S>'
first required here
        const auto t1 = t0;
                        ^
/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include/g++-v8/optional:288:24: note:
copy constructor of '_Optional_payload<S, true, true, true>' is implicitly
 deleted because variant field '_M_payload' has a non-trivial copy constructor
          _Stored_type _M_payload;

Reply via email to