public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/108619] New: Compilation error if the construct method of the allocator isn't implemented and the detructor of value_type is private
@ 2023-01-31 20:21 gccbugzilla at thepirate42 dot org
  2023-01-31 20:27 ` [Bug libstdc++/108619] " pinskia at gcc dot gnu.org
                   ` (15 more replies)
  0 siblings, 16 replies; 17+ messages in thread
From: gccbugzilla at thepirate42 dot org @ 2023-01-31 20:21 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 108619
           Summary: Compilation error if the construct method of the
                    allocator isn't implemented and the detructor of
                    value_type is private
           Product: gcc
           Version: 12.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gccbugzilla at thepirate42 dot org
  Target Milestone: ---

When I try to compile this code:


#include <memory>
#include <vector>
#include <type_traits>

class a {

    ~a() = default;

    friend class b;

};

class b {

    template<typename C>
        struct alloc : std::allocator<C> {

                template<typename U>
                void destroy(U* p){
                        if constexpr (std::is_array_v<U>){
                                for(auto& elem : *p){
                                        (destroy)(std::addressof(elem));
                                }
                        } else {
                                p->~U();
                        }
                }

        };

        std::vector<a,alloc<a>> v;

public:

    void f(){
        v.emplace_back();
    }

};


with this command line


g++ -v -Wall -Wextra -Wpedantic -std=c++20 test.cpp


I get this output:


Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure
--enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --enable-bootstrap
--prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man
--infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/
--with-build-config=bootstrap-lto --with-linker-hash-style=gnu
--with-system-zlib --enable-__cxa_atexit --enable-cet=auto
--enable-checking=release --enable-clocale=gnu --enable-default-pie
--enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object
--enable-libstdcxx-backtrace --enable-link-serialization=1
--enable-linker-build-id --enable-lto --enable-multilib --enable-plugin
--enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch
--disable-werror
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.2.1 20230111 (GCC) 
COLLECT_GCC_OPTIONS='-v' '-Wall' '-Wextra' '-Wpedantic' '-std=c++20'
'-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'a-'
 /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/cc1plus -quiet -v -D_GNU_SOURCE
test.cpp -quiet -dumpdir a- -dumpbase test.cpp -dumpbase-ext .cpp
-mtune=generic -march=x86-64 -Wall -Wextra -Wpedantic -std=c++20 -version -o
/tmp/ccZ8wizU.s
GNU C++20 (GCC) version 12.2.1 20230111 (x86_64-pc-linux-gnu)
        compiled by GNU C version 12.2.1 20230111, GMP version 6.2.1, MPFR
version 4.2.0, MPC version 1.3.1, isl version isl-0.25-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../x86_64-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1

/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/x86_64-pc-linux-gnu

/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/backward
 /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/include
 /usr/local/include
 /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/include-fixed
 /usr/include
End of search list.
GNU C++20 (GCC) version 12.2.1 20230111 (x86_64-pc-linux-gnu)
        compiled by GNU C version 12.2.1 20230111, GMP version 6.2.1, MPFR
version 4.2.0, MPC version 1.3.1, isl version isl-0.25-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: d14869452663722b786a6617dcf7b0b2
In file included from /usr/include/c++/12.2.1/vector:70,
                 from test.cpp:2:
/usr/include/c++/12.2.1/bits/vector.tcc: In instantiation of ‘constexpr
std::vector<_Tp, _Alloc>::reference std::vector<_Tp,
_Alloc>::emplace_back(_Args&& ...) [with _Args = {}; _Tp = a; _Alloc =
b::alloc<a>; reference = a&]’:
test.cpp:36:23:   required from here
/usr/include/c++/12.2.1/bits/vector.tcc:117:37: error: no matching function for
call to ‘__gnu_cxx::__alloc_traits<b::alloc<a>,
a>::construct(std::_Vector_base<a, b::alloc<a> >::_Vector_impl&, a*&)’
  117 |             _Alloc_traits::construct(this->_M_impl,
this->_M_impl._M_finish,
      |            
~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  118 |                                      std::forward<_Args>(__args)...);
      |                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/12.2.1/ext/alloc_traits.h:34,
                 from /usr/include/c++/12.2.1/bits/stl_uninitialized.h:64,
                 from /usr/include/c++/12.2.1/memory:65,
                 from test.cpp:1:
/usr/include/c++/12.2.1/bits/alloc_traits.h:360:9: note: candidate:
‘template<class _Tp, class ... _Args> static constexpr decltype
(std::allocator_traits< <template-parameter-1-1> >::_S_construct(__a, __p,
(forward<_Args>)(std::allocator_traits< <template-parameter-1-1>
>::construct::__args)...)) std::allocator_traits< <template-parameter-1-1>
>::construct(_Alloc&, _Tp*, _Args&& ...) [with _Args = _Tp; _Alloc =
b::alloc<a>]’
  360 |         construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
      |         ^~~~~~~~~
/usr/include/c++/12.2.1/bits/alloc_traits.h:360:9: note:   template argument
deduction/substitution failed:
/usr/include/c++/12.2.1/bits/alloc_traits.h: In substitution of ‘template<class
_Tp, class ... _Args> static constexpr decltype
(std::allocator_traits<b::alloc<a> >::_S_construct(__a, __p,
(forward<_Args>)(std::allocator_traits< <template-parameter-1-1>
>::construct::__args)...)) std::allocator_traits<b::alloc<a>
>::construct(b::alloc<a>&, _Tp*, _Args&& ...) [with _Tp = a; _Args = {}]’:
/usr/include/c++/12.2.1/bits/vector.tcc:117:30:   required from ‘constexpr
std::vector<_Tp, _Alloc>::reference std::vector<_Tp,
_Alloc>::emplace_back(_Args&& ...) [with _Args = {}; _Tp = a; _Alloc =
b::alloc<a>; reference = a&]’
test.cpp:36:23:   required from here
/usr/include/c++/12.2.1/bits/alloc_traits.h:363:33: error: no matching function
for call to ‘std::allocator_traits<b::alloc<a> >::_S_construct(b::alloc<a>&,
a*&)’
  363 |         -> decltype(_S_construct(__a, __p,
std::forward<_Args>(__args)...))
      |                    
~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/12.2.1/bits/alloc_traits.h:249:9: note: candidate:
‘template<class _Tp, class ... _Args> static constexpr std::_Require<typename
std::allocator_traits< <template-parameter-1-1> >::__construct_helper<_Tp,
_Args>::type> std::allocator_traits< <template-parameter-1-1>
>::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with _Args = _Tp; _Alloc =
b::alloc<a>]’
  249 |         _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
      |         ^~~~~~~~~~~~
/usr/include/c++/12.2.1/bits/alloc_traits.h:249:9: note:   template argument
deduction/substitution failed:
In file included from /usr/include/c++/12.2.1/bits/move.h:57,
                 from /usr/include/c++/12.2.1/bits/new_allocator.h:36,
                 from
/usr/include/c++/12.2.1/x86_64-pc-linux-gnu/bits/c++allocator.h:33,
                 from /usr/include/c++/12.2.1/bits/allocator.h:46,
                 from /usr/include/c++/12.2.1/memory:63:
/usr/include/c++/12.2.1/type_traits: In substitution of ‘template<bool _Cond,
class _Tp> using __enable_if_t = typename std::enable_if::type [with bool _Cond
= false; _Tp = void]’:
/usr/include/c++/12.2.1/type_traits:2238:11:   required by substitution of
‘template<class ... _Cond> using _Require = std::__enable_if_t<std::__and_<
<template-parameter-1-1> >::value> [with _Cond = {std::integral_constant<bool,
false>}]’
/usr/include/c++/12.2.1/bits/alloc_traits.h:249:2:   required by substitution
of ‘template<class _Tp, class ... _Args> static constexpr
std::_Require<typename std::allocator_traits<b::alloc<a>
>::__construct_helper<_Tp, _Args>::type> std::allocator_traits<b::alloc<a>
>::_S_construct(b::alloc<a>&, _Tp*, _Args&& ...) [with _Tp = a; _Args = {}]’
/usr/include/c++/12.2.1/bits/alloc_traits.h:363:26:   required by substitution
of ‘template<class _Tp, class ... _Args> static constexpr decltype
(std::allocator_traits<b::alloc<a> >::_S_construct(__a, __p,
(forward<_Args>)(std::allocator_traits< <template-parameter-1-1>
>::construct::__args)...)) std::allocator_traits<b::alloc<a>
>::construct(b::alloc<a>&, _Tp*, _Args&& ...) [with _Tp = a; _Args = {}]’
/usr/include/c++/12.2.1/bits/vector.tcc:117:30:   required from ‘constexpr
std::vector<_Tp, _Alloc>::reference std::vector<_Tp,
_Alloc>::emplace_back(_Args&& ...) [with _Args = {}; _Tp = a; _Alloc =
b::alloc<a>; reference = a&]’
test.cpp:36:23:   required from here
/usr/include/c++/12.2.1/type_traits:2234:11: error: no type named ‘type’ in
‘struct std::enable_if<false, void>’
 2234 |     using __enable_if_t = typename enable_if<_Cond, _Tp>::type;
      |           ^~~~~~~~~~~~~
/usr/include/c++/12.2.1/bits/alloc_traits.h: In substitution of ‘template<class
_Tp, class ... _Args> static constexpr decltype
(std::allocator_traits<b::alloc<a> >::_S_construct(__a, __p,
(forward<_Args>)(std::allocator_traits< <template-parameter-1-1>
>::construct::__args)...)) std::allocator_traits<b::alloc<a>
>::construct(b::alloc<a>&, _Tp*, _Args&& ...) [with _Tp = a; _Args = {}]’:
/usr/include/c++/12.2.1/bits/vector.tcc:117:30:   required from ‘constexpr
std::vector<_Tp, _Alloc>::reference std::vector<_Tp,
_Alloc>::emplace_back(_Args&& ...) [with _Args = {}; _Tp = a; _Alloc =
b::alloc<a>; reference = a&]’
test.cpp:36:23:   required from here
/usr/include/c++/12.2.1/bits/alloc_traits.h:257:9: note: candidate:
‘template<class _Tp, class ... _Args> static constexpr
std::_Require<std::__and_<std::__not_<typename std::allocator_traits<
<template-parameter-1-1> >::__construct_helper<_Tp, _Args>::type>,
std::is_constructible<_Tp, _Args ...> > > std::allocator_traits<
<template-parameter-1-1> >::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with
_Args = _Tp; _Alloc = b::alloc<a>]’
  257 |         _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
      |         ^~~~~~~~~~~~
/usr/include/c++/12.2.1/bits/alloc_traits.h:257:9: note:   template argument
deduction/substitution failed:
/usr/include/c++/12.2.1/bits/vector.tcc: In instantiation of ‘constexpr
std::vector<_Tp, _Alloc>::reference std::vector<_Tp,
_Alloc>::emplace_back(_Args&& ...) [with _Args = {}; _Tp = a; _Alloc =
b::alloc<a>; reference = a&]’:
test.cpp:36:23:   required from here
/usr/include/c++/12.2.1/ext/alloc_traits.h:81:7: note: candidate:
‘template<class _Ptr, class ... _Args> static constexpr
std::__enable_if_t<std::__and_<std::is_same<typename
std::allocator_traits<_Alloc>::pointer, _Ptr>,
std::__not_<std::is_pointer<_Ptr> > >::value> __gnu_cxx::__alloc_traits<_Alloc,
<template-parameter-1-2> >::construct(_Alloc&, _Ptr, _Args&& ...) [with _Args =
_Ptr; _Alloc = b::alloc<a>; <template-parameter-1-2> = a]’
   81 |       construct(_Alloc& __a, _Ptr __p, _Args&&... __args)
      |       ^~~~~~~~~
/usr/include/c++/12.2.1/ext/alloc_traits.h:81:7: note:   template argument
deduction/substitution failed:


Here's a compiler explorer link for convenience:
https://godbolt.org/z/qK1nxhbnW

The code compiles if I add a dummy constructor method to the custom allocator,
that internally just calls std::construct_at (https://godbolt.org/z/bM7rzoWaK),
but I think this shouldn't be necessary; the construct method is optional, and
std::allocator_traits<alloc<a>>::construct should work as intended in both
cases. I suppose this is caused by some sort of check of the "constructability"
of a that fails because of the private destructor, but as far as I know
allocator_traits::construct in c++20 should just forward to std::construct_at
without doing additional checks, which makes this behavior wrong.

I don't know if it's relevant, but msvc compiles this without problems
(https://godbolt.org/z/oEb6Ej4sr).

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2024-09-23 19:24 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-31 20:21 [Bug libstdc++/108619] New: Compilation error if the construct method of the allocator isn't implemented and the detructor of value_type is private gccbugzilla at thepirate42 dot org
2023-01-31 20:27 ` [Bug libstdc++/108619] " pinskia at gcc dot gnu.org
2023-01-31 20:30 ` pinskia at gcc dot gnu.org
2023-01-31 21:16 ` gccbugzilla at thepirate42 dot org
2023-01-31 21:19 ` gccbugzilla at thepirate42 dot org
2023-01-31 21:21 ` pinskia at gcc dot gnu.org
2023-01-31 21:22 ` pinskia at gcc dot gnu.org
2023-01-31 21:28 ` gccbugzilla at thepirate42 dot org
2023-01-31 21:38 ` gccbugzilla at thepirate42 dot org
2023-01-31 21:59 ` redi at gcc dot gnu.org
2023-01-31 22:07 ` redi at gcc dot gnu.org
2023-01-31 22:08 ` redi at gcc dot gnu.org
2024-07-10 22:07 ` redi at gcc dot gnu.org
2024-08-01 21:42 ` redi at gcc dot gnu.org
2024-08-23 12:40 ` cvs-commit at gcc dot gnu.org
2024-08-23 12:47 ` redi at gcc dot gnu.org
2024-09-23 19:24 ` cvs-commit at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).