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

            Bug ID: 113841
           Summary: Can't swap two std::hash<T*>
           Product: gcc
           Version: 12.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ostash at ostash dot kiev.ua
  Target Milestone: ---

For the following code snippet:
---
#include <array>
#include <vector>

class Storage;

template <typename T>
class MyAllocator 
{
public:
  using value_type = T;
  using pointer = T*;

  MyAllocator(Storage* s);

  template <typename U>
  MyAllocator(MyAllocator<U> const& other) noexcept;

  T* allocate( std::size_t n );
  void deallocate(T* p, std::size_t n );

private:
  Storage* s_;
};

class Foo{
public:
    Foo(int, int);
};

void x() {
  using std::swap;

  using MyVec = std::vector<int, MyAllocator<int>>;
  using MyArrVec = std::array<MyVec, 1>;
  using MyHash = std::hash<std::pair<const int, MyArrVec>*>;

  MyHash h1, h2;
  swap(h1, h2);
}
---

GCC 12 reports:
In file included from
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/vector:64,
                 from <source>:2:
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h: In
instantiation of 'constexpr std::_Vector_base<_Tp,
_Alloc>::_Vector_impl::_Vector_impl() [with _Tp = int; _Alloc =
MyAllocator<int>]':
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h:312:7:  
required by substitution of 'template<class _Tp> static std::true_type
std::__do_is_implicitly_default_constructible_impl::__test(const _Tp&, decltype
(__helper<const _Tp&>(<brace-enclosed initializer list>()))*) [with _Tp =
std::array<std::vector<int, MyAllocator<int> >, 1>]'
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/type_traits:1249:30:  
required from 'struct
std::__is_implicitly_default_constructible_impl<std::array<std::vector<int,
MyAllocator<int> >, 1> >'
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/type_traits:1253:12:  
required from 'struct
std::__is_implicitly_default_constructible_safe<std::array<std::vector<int,
MyAllocator<int> >, 1> >'
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/type_traits:167:12:  
required from 'struct
std::__and_<std::__is_constructible_impl<std::array<std::vector<int,
MyAllocator<int> >, 1> >,
std::__is_implicitly_default_constructible_safe<std::array<std::vector<int,
MyAllocator<int> >, 1> > >'
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/type_traits:1258:12:  
required from 'struct
std::__is_implicitly_default_constructible<std::array<std::vector<int,
MyAllocator<int> >, 1> >'
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/type_traits:167:12:  
required from 'struct
std::__and_<std::__is_implicitly_default_constructible<const int>,
std::__is_implicitly_default_constructible<std::array<std::vector<int,
MyAllocator<int> >, 1> > >'
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/type_traits:178:41:  
required from 'struct
std::__not_<std::__and_<std::__is_implicitly_default_constructible<const int>,
std::__is_implicitly_default_constructible<std::array<std::vector<int,
MyAllocator<int> >, 1> > > >'
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_pair.h:226:16:  
required from 'struct std::pair<const int, std::array<std::vector<int,
MyAllocator<int> >, 1> >'
<source>:38:14:   required from here
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/type_traits:1240:58:   in
'constexpr' expansion of 'std::vector<int, MyAllocator<int> >()'
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h:526:7:  
in 'constexpr' expansion of '((std::vector<int, MyAllocator<int>
>*)this)->std::vector<int, MyAllocator<int>
>::<anonymous>.std::_Vector_base<int, MyAllocator<int> >::_Vector_base()'
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h:139:26:
error: no matching function for call to 'MyAllocator<int>::MyAllocator()'
  139 |         : _Tp_alloc_type()
      |                          ^
<source>:16:3: note: candidate: 'template<class U>
MyAllocator<T>::MyAllocator(const MyAllocator<U>&) [with T = int]'
   16 |   MyAllocator(MyAllocator<U> const& other) noexcept;
      |   ^~~~~~~~~~~
<source>:16:3: note:   template argument deduction/substitution failed:
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h:139:26:
note:   candidate expects 1 argument, 0 provided
  139 |         : _Tp_alloc_type()
      |                          ^
<source>:13:3: note: candidate: 'MyAllocator<T>::MyAllocator(Storage*) [with T
= int]'
   13 |   MyAllocator(Storage* s);
      |   ^~~~~~~~~~~
<source>:13:3: note:   candidate expects 1 argument, 0 provided
<source>:7:7: note: candidate: 'constexpr MyAllocator<int>::MyAllocator(const
MyAllocator<int>&)'
    7 | class MyAllocator
      |       ^~~~~~~~~~~
<source>:7:7: note:   candidate expects 1 argument, 0 provided
<source>:7:7: note: candidate: 'constexpr
MyAllocator<int>::MyAllocator(MyAllocator<int>&&)'
<source>:7:7: note:   candidate expects 1 argument, 0 provided
Compiler returned: 1


Clang 15, 16, 17 also fail to compile with similar error about missing default
constructor for custom allocator when they are using libstdc++ >=12

GCC 13 is able to compile this, same as Clang with libc++.

Reply via email to