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

--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Egor Pugin from comment #1)
> All major compilers (MSVC, GCC, Clang) of all (tried) modern versions (in
> case of GCC — before 12) build this code without problems. Is this a GCC
> regression?

Your links clearly show you're compiling with Clang though, not GCC. The paste
starts with:
[1/135] /usr/lib/ccache/bin/clang++


The code can be reduced to:

template<class T>
struct vector
{
  T* ptr;
  vector();
  vector(const vector&);
  ~vector() { ++ptr; } // requires T to be complete
};

struct nullopt_t { };
constexpr nullopt_t nullopt{};

template<class T>
struct optional_payload
{
  optional_payload() = default;
  ~optional_payload() { if (engaged) value.~T(); }
  union {
    unsigned char dummy;
    T value;
  };
  bool engaged = false;
};

template<class T>
struct optional_base
{
  optional_base() = default;
  ~optional_base() = default;
  optional_payload<T> payload;
};

template<class T>
struct optional : optional_base<T>
{
  constexpr optional(nullopt_t) { }
};

struct ScanInfo;

struct List {
  List(optional<vector<ScanInfo>>&& = nullopt);
};

GCC compiles this, but Clang doesn't:

$ clang++ -std=c++17 -c inc.cc
inc.cc:36:13: error: call to implicitly-deleted default constructor of
'optional_base<vector<ScanInfo>>'
  constexpr optional(nullopt_t) { }
            ^
inc.cc:47:39: note: in instantiation of member function
'optional<vector<ScanInfo>>::optional' requested here
  List(optional<vector<ScanInfo>>&& = nullopt);
                                      ^
inc.cc:28:3: note: explicitly defaulted function was implicitly deleted here
  optional_base() = default;
  ^
inc.cc:30:23: note: default constructor of 'optional_base<vector<ScanInfo>>' is
implicitly deleted because field 'payload' has a deleted default constructor
  optional_payload<T> payload;
                      ^
inc.cc:16:3: note: explicitly defaulted function was implicitly deleted here
  optional_payload() = default;
  ^
inc.cc:20:7: note: default constructor of 'optional_payload<vector<ScanInfo>>'
is implicitly deleted because variant field 'value' has a non-trivial default
constructor
    T value;
      ^
1 error generated.


Neither does EDG:

$ edg --c++17 -c inc.cc
"inc.cc", line 36: error: the default constructor of
          "optional_base<vector<ScanInfo>>" cannot be referenced -- it is a
          deleted function
    constexpr optional(nullopt_t) { }
                                  ^
          detected during instantiation of "optional<T>::optional(nullopt_t)
                    [with T=vector<ScanInfo>]" at line 42

"inc.cc", line 7: error: expression must be a pointer to a complete object type
    ~vector() { ++ptr; } // requires T to be complete
                  ^
          detected during:
            instantiation of "vector<T>::~vector() [with T=ScanInfo]" at line
                      17
            instantiation of "optional_payload<T>::~optional_payload() [with
                      T=vector<ScanInfo>]" at line 43

2 errors detected in the compilation of "inc.cc".

Nor MSVC:

<source>(7): error C2036: 'ScanInfo *': unknown size
<source>(7): note: while compiling class template member function
'vector<ScanInfo>::~vector(void)'
<source>(44): note: see reference to function template instantiation
'vector<ScanInfo>::~vector(void)' being compiled
<source>(20): note: see reference to class template instantiation
'vector<ScanInfo>' being compiled
<source>(30): note: see reference to class template instantiation
'optional_payload<T>' being compiled
        with
        [
            T=vector<ScanInfo>
        ]
<source>(35): note: see reference to class template instantiation
'optional_base<T>' being compiled
        with
        [
            T=vector<ScanInfo>
        ]
<source>(42): note: see reference to class template instantiation
'optional<vector<ScanInfo>>' being compiled
Compiler returned: 2


Maybe the code is ill-formed (no diagnostic required), or maybe G++ is being
too generous to compile it, but I don't think there's a libstdc++ bug here.

Reply via email to