Issue 52956
Summary clang-13 fails to compile libstdc++'s std::variant<std::vector<int>>: error: attempt to use a deleted function
Labels new issue
Assignees
Reporter trofi
    Initially I observed the error as a `mold-1.0.0` build failure on `clang-13` which uses gcc-12's `libstdc++`. Here is a one line reproducer:

```c++
#include <variant>
#include <vector>

std::variant<std::vector<long> > v;
```

`gcc-12` builds it fine, `clang-13` fails:

```
$ /tmp/gcc-12/bin/c++ -std=c++20 -c tapi.cc
$ /tmp/clang-13/bin/c++ -std=c++20 -c tapi.cc
/<<NIX>>/gcc-12.0.0/include/c++/12.0.0/variant:460:2: error: attempt to use a deleted function
        _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
        ^
/<<NIX>>/gcc-12.0.0/include/c++/12.0.0/variant:747:4: note: in instantiation of function template specialization 'std::__detail::__variant::_Variant_storage<false, std::vector<long>>::_Variant_storage<0UL>' requested here
        : _Base(__i, std::forward<_Args>(__args)...)
          ^
/<<NIX>>/gcc-12.0.0/include/c++/12.0.0/variant:742:9: note: in instantiation of function template specialization 'std::__detail::__variant::_Variant_base<std::vector<long>>::_Variant_base<0UL>' requested here
      : _Variant_base(in_place_index<0>) { }
        ^
/<<NIX>>/gcc-12.0.0/include/c++/12.0.0/variant:1403:7: note: in instantiation of member function 'std::__detail::__variant::_Variant_base<std::vector<long>>::_Variant_base' requested here
      variant() = default;
      ^
tapi.cc:13:34: note: in defaulted default constructor for 'std::variant<std::vector<long>>' first required here
std::variant<std::vector<long> > v;
                                 ^
/<<NIX>>/gcc-12.0.0/include/c++/12.0.0/variant:401:7: note: explicitly defaulted function was implicitly deleted here
      ~_Variadic_union() = default;
      ^
/<<NIX>>/gcc-12.0.0/include/c++/12.0.0/variant:409:30: note: destructor of '_Variadic_union<std::vector<long>>' is implicitly deleted because variant field '_M_first' has a non-trivial destructor
      _Uninitialized<_First> _M_first;
                             ^
/<<NIX>>/gcc-12.0.0/include/c++/12.0.0/variant:480:7: error: attempt to use a deleted function
      ~_Variant_storage()
      ^
/<<NIX>>/gcc-12.0.0/include/c++/12.0.0/variant:558:20: note: in instantiation of member function 'std::__detail::__variant::_Variant_storage<false, std::vector<long>>::~_Variant_storage' requested here
      using _Base::_Base;
                   ^
/<<NIX>>/gcc-12.0.0/include/c++/12.0.0/variant:742:9: note: in instantiation of function template specialization 'std::__detail::__variant::_Variant_base<std::vector<long>>::_Variant_base<0UL>' requested here
      : _Variant_base(in_place_index<0>) { }
        ^
/<<NIX>>/gcc-12.0.0/include/c++/12.0.0/variant:1403:7: note: in instantiation of member function 'std::__detail::__variant::_Variant_base<std::vector<long>>::_Variant_base' requested here
      variant() = default;
      ^
tapi.cc:13:34: note: in defaulted default constructor for 'std::variant<std::vector<long>>' first required here
std::variant<std::vector<long> > v;
                                 ^
/<<NIX>>/gcc-12.0.0/include/c++/12.0.0/variant:401:7: note: explicitly defaulted function was implicitly deleted here
      ~_Variadic_union() = default;
      ^
/<<NIX>>/gcc-12.0.0/include/c++/12.0.0/variant:409:30: note: destructor of '_Variadic_union<std::vector<long>>' is implicitly deleted because variant field '_M_first' has a non-trivial destructor
      _Uninitialized<_First> _M_first;
                             ^
2 errors generated.
```

I attempted to shrink down preprocessed file to extract compiler difference. My result:

```c++
struct _Vector_base {
  ~_Vector_base();
};
template <typename> union _Variadic_union {
  ~_Variadic_union() requires(!__has_trivial_destructor(_Variadic_union));
  _Vector_base _M_first;
};
struct _Variant_storage {
  _Variant_storage();
  _Variadic_union<int> _M_u;
};
struct _Variant_storage v;
```

`gcc` / `clang` handling difference:

```
$ /tmp/gcc-12/bin/c++ -std=c++20 -c tapi.cc.cc
$ /tmp/clang-13/bin/c++ -std=c++20 -c tapi.cc.cc
tapi.cc.cc:6:32: error: incomplete type '_Variadic_union<int>' used in type trait _expression_
  ~_Variadic_union() requires(!__has_trivial_destructor(_Variadic_union));
                               ^
tapi.cc.cc:11:24: note: in instantiation of template class '_Variadic_union<int>' requested here
  _Variadic_union<int> _M_u;
                       ^
tapi.cc.cc:5:27: note: definition of '_Variadic_union<int>' is not complete until the closing '}'
template <typename> union _Variadic_union {
                          ^
tapi.cc.cc:13:25: error: attempt to use a deleted function
struct _Variant_storage v;
                        ^
tapi.cc.cc:11:24: note: destructor of '_Variant_storage' is implicitly deleted because field '_M_u' has a deleted destructor
  _Variadic_union<int> _M_u;
                       ^
tapi.cc.cc:7:16: note: destructor of '_Variadic_union<int>' is implicitly deleted because variant field '_M_first' has a non-trivial destructor
  _Vector_base _M_first;
               ^
2 errors generated.
```

_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to