The union members I used in the new _Node types for fancy pointers only work for value types that are trivially default constructible. This change adds an unsigned char member to the union, so the node's default constructor is not defined as deleted.
libstdc++-v3/ChangeLog: * include/bits/forward_list.h (__fwd_list::_Node): Add trivial member to the union. * include/bits/stl_list.h (__list::_Node): Likewise. * testsuite/23_containers/forward_list/requirements/explicit_instantiation/alloc_ptr.cc: Check explicit instantiation of non-trivial value type. * testsuite/23_containers/list/requirements/explicit_instantiation/alloc_ptr.cc: Likewise. --- This fixes an oopsie in my recent std::list and std::forward_list changes. Tested x86_64-linux. libstdc++-v3/include/bits/forward_list.h | 1 + libstdc++-v3/include/bits/stl_list.h | 1 + .../requirements/explicit_instantiation/alloc_ptr.cc | 11 +++++++++++ .../requirements/explicit_instantiation/alloc_ptr.cc | 11 +++++++++++ 4 files changed, 24 insertions(+) diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h index f4a53bb4d7e..e650bbaa6de 100644 --- a/libstdc++-v3/include/bits/forward_list.h +++ b/libstdc++-v3/include/bits/forward_list.h @@ -425,6 +425,7 @@ namespace __fwdlist _Node(_Node&&) = delete; union { + unsigned char _M_uninit{}; #if ! _GLIBCXX_INLINE_VERSION // For ABI compatibility we need to overalign this member. alignas(__alignof__(value_type)) // XXX GLIBCXX_ABI Deprecated diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h index 9f7d27242b6..ca9a2a1f0b9 100644 --- a/libstdc++-v3/include/bits/stl_list.h +++ b/libstdc++-v3/include/bits/stl_list.h @@ -291,6 +291,7 @@ namespace __list using _Node_ptr = __ptr_rebind<_ValPtr, _Node>; union { + unsigned char _M_uninit{}; value_type _M_data; }; diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/explicit_instantiation/alloc_ptr.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/explicit_instantiation/alloc_ptr.cc index 621ff4c652c..e3bf8a13095 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/explicit_instantiation/alloc_ptr.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/explicit_instantiation/alloc_ptr.cc @@ -59,6 +59,17 @@ struct Allocator template class std::forward_list<int, Allocator<int>>; +struct NonTrivial +{ + NonTrivial() { } + NonTrivial(const NonTrivial&) { } + ~NonTrivial() { } + bool operator==(const NonTrivial&) const { return true; } // for remove(T) + bool operator<(const NonTrivial&) const { return false; } // for sort() +}; + +template class std::forward_list<NonTrivial, Allocator<NonTrivial>>; + #include <testsuite_iterators.h> void diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/explicit_instantiation/alloc_ptr.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/explicit_instantiation/alloc_ptr.cc index d3b2cfe6d92..c52591b3cf8 100644 --- a/libstdc++-v3/testsuite/23_containers/list/requirements/explicit_instantiation/alloc_ptr.cc +++ b/libstdc++-v3/testsuite/23_containers/list/requirements/explicit_instantiation/alloc_ptr.cc @@ -57,6 +57,17 @@ struct Allocator template class std::list<int, Allocator<int>>; +struct NonTrivial +{ + NonTrivial() { } + NonTrivial(const NonTrivial&) { } + ~NonTrivial() { } + bool operator==(const NonTrivial&) const { return true; } // for remove(T) + bool operator<(const NonTrivial&) const { return false; } // for sort() +}; + +template class std::list<NonTrivial, Allocator<NonTrivial>>; + #include <testsuite_iterators.h> void -- 2.47.1