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

* [Bug libstdc++/108619] 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 [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 ` pinskia at gcc dot gnu.org
  2023-01-31 20:30 ` pinskia at gcc dot gnu.org
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-01-31 20:27 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
The trunk gives a better error message:
/opt/compiler-explorer/gcc-trunk-20230131/include/c++/13.0.1/bits/alloc_traits.h:70:31:
error: static assertion failed:
allocator_traits<A>::rebind_alloc<A::value_type> must be A

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

* [Bug libstdc++/108619] 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 [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
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-01-31 20:30 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Once I add:

        template <class Type> struct rebind {
            typedef alloc<Type> other;
        };

To alloc, it works correctly.
The error message on the trunk gives the best error message of what is going
wrong even.
So this is invalid.

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

* [Bug libstdc++/108619] 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 [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
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: gccbugzilla at thepirate42 dot org @ 2023-01-31 21:16 UTC (permalink / raw)
  To: gcc-bugs

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

gccbugzilla at thepirate42 dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|INVALID                     |FIXED

--- Comment #3 from gccbugzilla at thepirate42 dot org ---
(In reply to Andrew Pinski from comment #2)
> Once I add:
> 
>         template <class Type> struct rebind {
>             typedef alloc<Type> other;
>         };
> 
> To alloc, it works correctly.
> The error message on the trunk gives the best error message of what is going
> wrong even.
> So this is invalid.

I just tried, but apparently it doesn't work (https://godbolt.org/z/ehhzYd5Wo)

Have I misinterpreted your response? Also rebind is too optional, it's still a
bug if it doesn't compile without it.

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

* [Bug libstdc++/108619] 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 [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
                   ` (2 preceding siblings ...)
  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
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: gccbugzilla at thepirate42 dot org @ 2023-01-31 21:19 UTC (permalink / raw)
  To: gcc-bugs

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

gccbugzilla at thepirate42 dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|FIXED                       |---
             Status|RESOLVED                    |UNCONFIRMED

--- Comment #4 from gccbugzilla at thepirate42 dot org ---
I accidentally changed the status to fixed

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

* [Bug libstdc++/108619] 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 [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
                   ` (3 preceding siblings ...)
  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
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-01-31 21:21 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to gccbugzilla from comment #3)
> (In reply to Andrew Pinski from comment #2)
> > Once I add:
> > 
> >         template <class Type> struct rebind {
> >             typedef alloc<Type> other;
> >         };
> > 
> > To alloc, it works correctly.
> > The error message on the trunk gives the best error message of what is going
> > wrong even.
> > So this is invalid.
> 
> I just tried, but apparently it doesn't work
> (https://godbolt.org/z/ehhzYd5Wo)
> 
> Have I misinterpreted your response? Also rebind is too optional, it's still
> a bug if it doesn't compile without it.

I missed -std=c++20 part before. The rebind fixes the compiliation issue
without -std=c++20 ....

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

* [Bug libstdc++/108619] 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 [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
                   ` (4 preceding siblings ...)
  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
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-01-31 21:22 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
With clang and libc++ we get:

/opt/compiler-explorer/clang-trunk-20230131/bin/../include/c++/v1/__memory/uninitialized_algorithms.h:597:3:
error: static assertion failed due to requirement
'__is_cpp17_move_insertable<b::alloc<a>, void>::value': The specified type does
not meet the requirements of Cpp17MoveInsertable
  static_assert(__is_cpp17_move_insertable<_Alloc>::value,
  ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Which I think is the best error message really. libstdc++v3 should add a
similar static assert I think.

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

* [Bug libstdc++/108619] 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 [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
                   ` (5 preceding siblings ...)
  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
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: gccbugzilla at thepirate42 dot org @ 2023-01-31 21:28 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from gccbugzilla at thepirate42 dot org ---
(In reply to Andrew Pinski from comment #6)
> With clang and libc++ we get:
> 
> /opt/compiler-explorer/clang-trunk-20230131/bin/../include/c++/v1/__memory/
> uninitialized_algorithms.h:597:3: error: static assertion failed due to
> requirement '__is_cpp17_move_insertable<b::alloc<a>, void>::value': The
> specified type does not meet the requirements of Cpp17MoveInsertable
>   static_assert(__is_cpp17_move_insertable<_Alloc>::value,
>   ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> Which I think is the best error message really. libstdc++v3 should add a
> similar static assert I think.

I don't understand, why should there be an error at all?

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

* [Bug libstdc++/108619] 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 [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
                   ` (6 preceding siblings ...)
  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
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: gccbugzilla at thepirate42 dot org @ 2023-01-31 21:38 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #8 from gccbugzilla at thepirate42 dot org ---
The same code (with added rebind, https://godbolt.org/z/6fabvnvE7) compiles in
c++17 mode, while in c++20 mode (also with added rebind,
https://godbolt.org/z/ehhzYd5Wo) it doesn't, which means this is a bug right?
I'm not an expert, but to my knowledge there shouldn't be any change in c++20
that makes this code ill formed.

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

* [Bug libstdc++/108619] 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 [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
                   ` (7 preceding siblings ...)
  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
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: redi at gcc dot gnu.org @ 2023-01-31 21:59 UTC (permalink / raw)
  To: gcc-bugs

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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2023-01-31

--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #5)
> I missed -std=c++20 part before. The rebind fixes the compiliation issue
> without -std=c++20 ....

Right, but the bug report is about c++20 mode, and the rebind isn't needed in
C++20 (because std::allocator<T>::rebind doesn't exist, so the default
implementation of rebinding does the right thing for alloc<T>).

(In reply to Andrew Pinski from comment #6)
> With clang and libc++ we get:
> 
> /opt/compiler-explorer/clang-trunk-20230131/bin/../include/c++/v1/__memory/
> uninitialized_algorithms.h:597:3: error: static assertion failed due to
> requirement '__is_cpp17_move_insertable<b::alloc<a>, void>::value': The
> specified type does not meet the requirements of Cpp17MoveInsertable
>   static_assert(__is_cpp17_move_insertable<_Alloc>::value,
>   ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> Which I think is the best error message really. libstdc++v3 should add a
> similar static assert I think.

I think this is a libc++ bug in their __cpp17_move_insertable trait, which just
uses is_move_constructible here, which is false because of the private
destructor.

I agree there's a bug here, but I'm not sure where yet.

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

* [Bug libstdc++/108619] 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 [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
                   ` (8 preceding siblings ...)
  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
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: redi at gcc dot gnu.org @ 2023-01-31 22:07 UTC (permalink / raw)
  To: gcc-bugs

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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
           Keywords|                            |rejects-valid

--- Comment #10 from Jonathan Wakely <redi at gcc dot gnu.org> ---
The bug is here in std::allocator_traits:

      template<typename _Tp, typename... _Args>
        static _GLIBCXX14_CONSTEXPR
        _Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
                               is_constructible<_Tp, _Args...>>>
        _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)

It uses std::is_constructible, which is false because std::is_destructible<a>
is false.

We need to check if a placement new expression is valid, so that we don't
consider the destructor.

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

* [Bug libstdc++/108619] 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 [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
                   ` (9 preceding siblings ...)
  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
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: redi at gcc dot gnu.org @ 2023-01-31 22:08 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #11 from Jonathan Wakely <redi at gcc dot gnu.org> ---
And it would be nice to simplify allocator_traits::construct using if-constexpr
too.

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

* [Bug libstdc++/108619] 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 [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
                   ` (10 preceding siblings ...)
  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
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: redi at gcc dot gnu.org @ 2024-07-10 22:07 UTC (permalink / raw)
  To: gcc-bugs

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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |redi at gcc dot gnu.org

--- Comment #12 from Jonathan Wakely <redi at gcc dot gnu.org> ---
This fails for all modes from C++11 to C++20:

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

class a {

  ~a() = default;

  friend class b;

};

class b {

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

      alloc() { }

      template<typename U> alloc(const alloc<U>&) { }

      using value_type = C;

      C* allocate(std::size_t n) { return a.allocate(n); }
      void deallocate(C* p, std::size_t n) { return a.deallocate(p, n); }

      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();
  }

};


I have a patch ...

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

* [Bug libstdc++/108619] 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 [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
                   ` (11 preceding siblings ...)
  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
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: redi at gcc dot gnu.org @ 2024-08-01 21:42 UTC (permalink / raw)
  To: gcc-bugs

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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch

--- Comment #13 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Patch posted: https://gcc.gnu.org/pipermail/gcc-patches/2024-August/659184.html

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

* [Bug libstdc++/108619] 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 [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
                   ` (12 preceding siblings ...)
  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
  15 siblings, 0 replies; 17+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-08-23 12:40 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #14 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:8cf51d7516b92b352c358c14ab4e456ae53c3371

commit r15-3132-g8cf51d7516b92b352c358c14ab4e456ae53c3371
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Jul 10 23:14:19 2024 +0100

    libstdc++: Fix std::allocator_traits::construct constraints [PR108619]

    Using std::is_constructible in the constraints introduces a spurious
    dependency on the type being destructible, which should not be required
    for constructing with an allocator. The test case shows a case where the
    type has a private destructor, which can be destroyed by the allocator,
    but std::is_destructible and std::is_constructible are false.

    Similarly, using is_nothrow_constructible in the noexcept-specifiers
    for the construct members of allocator_traits and std::allocator,
    __gnu_cxx::__new_allocator, and __gnu_cxx::__malloc_allocator gives the
    wrong answer if the type isn't destructible.
    We need a new type trait to define those correctly, so that we only
    check if the placement new-expression is nothrow after using
    is_constructible to check that it would be well-formed.

    Instead of just fixing the overly restrictive constraint to check for
    placement new, rewrite allocator_traits in terms of 'if constexpr' using
    variable templates and the detection idiom.

    Although we can use 'if constexpr' and variable templates in C++11 with
    appropriate uses of diagnostic pragmas, we can't have constexpr
    functions with multiple return statements. This means that in C++11 mode
    the _S_nothrow_construct and _S_nothrow_destroy helpers used for
    noexcept-specifiers still need to be overlaods using enable_if. Nearly
    everything else can be simplified to reduce overload resolution and
    enable_if checks.

    libstdc++-v3/ChangeLog:

            PR libstdc++/108619
            * include/bits/alloc_traits.h (__allocator_traits_base): Add
            variable templates for detecting which allocator operations are
            supported.
            (allocator_traits): Use 'if constexpr' instead of dispatching to
            overloads constrained with enable_if.
            (allocator_traits<allocator<T>>::construct): Use Construct if
            construct_at is not supported. Use
            __is_nothrow_new_constructible for noexcept-specifier.
            (allocator_traits<allocator<void>>::construct): Use
            __is_nothrow_new_constructible for noexcept-specifier.
            * include/bits/new_allocator.h (construct): Likewise.
            * include/ext/malloc_allocator.h (construct): Likewise.
            * include/std/type_traits (__is_nothrow_new_constructible): New
            variable template.
            * testsuite/20_util/allocator/89510.cc: Adjust expected results.
            * testsuite/ext/malloc_allocator/89510.cc: Likewise.
            * testsuite/ext/new_allocator/89510.cc: Likewise.
            * testsuite/20_util/allocator_traits/members/108619.cc: New test.

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

* [Bug libstdc++/108619] 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 [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
                   ` (13 preceding siblings ...)
  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
  15 siblings, 0 replies; 17+ messages in thread
From: redi at gcc dot gnu.org @ 2024-08-23 12:47 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #15 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Fixed on trunk only so far.

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

* [Bug libstdc++/108619] 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 [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
                   ` (14 preceding siblings ...)
  2024-08-23 12:47 ` redi at gcc dot gnu.org
@ 2024-09-23 19:24 ` cvs-commit at gcc dot gnu.org
  15 siblings, 0 replies; 17+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-09-23 19:24 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #16 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-14 branch has been updated by Jonathan Wakely
<redi@gcc.gnu.org>:

https://gcc.gnu.org/g:1be3e4e43839d313364ffa99012ada41b4fae8da

commit r14-10705-g1be3e4e43839d313364ffa99012ada41b4fae8da
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Jul 10 23:14:19 2024 +0100

    libstdc++: Fix std::allocator_traits::construct constraints [PR108619]

    Using std::is_constructible in the constraints introduces a spurious
    dependency on the type being destructible, which should not be required
    for constructing with an allocator. The test case shows a case where the
    type has a private destructor, which can be destroyed by the allocator,
    but std::is_destructible and std::is_constructible are false.

    Similarly, using is_nothrow_constructible in the noexcept-specifiers
    for the construct members of allocator_traits and std::allocator,
    __gnu_cxx::__new_allocator, and __gnu_cxx::__malloc_allocator gives the
    wrong answer if the type isn't destructible.
    We need a new type trait to define those correctly, so that we only
    check if the placement new-expression is nothrow after using
    is_constructible to check that it would be well-formed.

    On trunk all members of std::allocator_traits were rewritten in terms of
    'if constexpr' using variable templates and the detection idiom. For the
    release branch this backport only changes the 'construct' member.

    Although we can use 'if constexpr' and variable templates in C++11 with
    appropriate uses of diagnostic pragmas, we can't have constexpr
    functions with multiple return statements. This means that in C++11 mode
    the _S_nothrow_construct helper used for noexcept-specifiers still needs
    to be a pair of overloads using enable_if.

    libstdc++-v3/ChangeLog:

            PR libstdc++/108619
            * include/bits/alloc_traits.h (__allocator_traits_base): Add
            variable templates for detecting whether the allocator has a
            construct member, or if placement new can be used instead.
            (allocator_traits::__construct_helper): Remove.
            (allocator_traits::__has_construct): Remove.
            (allocator_traits::construct): Use 'if constexpr' instead of
            dispatching to overloads constrained with enable_if.
            (allocator_traits<allocator<T>>::construct): Use _Construct if
            construct_at is not supported. Use
            __is_nothrow_new_constructible for noexcept-specifier.
            (allocator_traits<allocator<void>>::construct): Use
            __is_nothrow_new_constructible for noexcept-specifier.
            * include/bits/new_allocator.h (construct): Likewise.
            * include/ext/malloc_allocator.h (construct): Likewise.
            * include/std/type_traits (__is_nothrow_new_constructible): New
            variable template.
            * testsuite/20_util/allocator/89510.cc: Adjust expected results.
            * testsuite/ext/malloc_allocator/89510.cc: Likewise.
            * testsuite/ext/new_allocator/89510.cc: Likewise.
            * testsuite/20_util/allocator_traits/members/108619.cc: New test.

    (cherry picked from commit 8cf51d7516b92b352c358c14ab4e456ae53c3371)

^ 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).