[gcc r14-9525] libstdc++: Fix N3344 behavior on _Safe_iterator::_M_can_advance
https://gcc.gnu.org/g:dda96a9d942d73a587e174dd5efe061208a195af commit r14-9525-gdda96a9d942d73a587e174dd5efe061208a195af Author: François Dumont Date: Sun Mar 17 19:06:55 2024 +0100 libstdc++: Fix N3344 behavior on _Safe_iterator::_M_can_advance We shall be able to advance from a 0 offset a value-initialized iterator. libstdc++-v3/ChangeLog: * include/debug/safe_iterator.tcc (_Safe_iterator<>::_M_can_advance): Accept 0 offset advance on value-initialized iterator. * testsuite/23_containers/vector/debug/n3644.cc: New test case. Diff: --- libstdc++-v3/include/debug/safe_iterator.tcc | 3 +++ .../testsuite/23_containers/vector/debug/n3644.cc| 16 2 files changed, 19 insertions(+) diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc b/libstdc++-v3/include/debug/safe_iterator.tcc index 4b2baf2980e..deaa84d0a1f 100644 --- a/libstdc++-v3/include/debug/safe_iterator.tcc +++ b/libstdc++-v3/include/debug/safe_iterator.tcc @@ -86,6 +86,9 @@ namespace __gnu_debug _Safe_iterator<_Iterator, _Sequence, _Category>:: _M_can_advance(difference_type __n, bool __strict) const { + if (this->_M_value_initialized() && __n == 0) + return true; + if (this->_M_singular()) return false; diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/n3644.cc b/libstdc++-v3/testsuite/23_containers/vector/debug/n3644.cc new file mode 100644 index 000..052c52f26b7 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/debug/n3644.cc @@ -0,0 +1,16 @@ +// { dg-do run { target c++11 } } +// { dg-require-debug-mode "" } + +#include +#include + +#include + +int main() +{ + std::vector::iterator it{}; + auto cpy = it; + std::advance(it, 0); + VERIFY( it == cpy ); + return 0; +}
[gcc r13-8470] libstdc++: Fix _Safe_local_iterator<>::_M_valid_range
https://gcc.gnu.org/g:86183487993315214091d593334893a883954f17 commit r13-8470-g86183487993315214091d593334893a883954f17 Author: François Dumont Date: Sun Mar 17 17:30:58 2024 +0100 libstdc++: Fix _Safe_local_iterator<>::_M_valid_range Unordered container local_iterator range shall not contain any singular iterator unless both iterators are both value-initialized. libstdc++-v3/ChangeLog: * include/debug/safe_local_iterator.tcc (_Safe_local_iterator::_M_valid_range): Add _M_value_initialized and _M_singular checks. * testsuite/23_containers/unordered_set/debug/114316.cc: New test case. (cherry picked from commit 5f6e0853c30fec72d977afaa6f7a5633a8d910be) Diff: --- libstdc++-v3/include/debug/safe_local_iterator.tcc | 8 ++- .../23_containers/unordered_set/debug/114316.cc| 28 ++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/include/debug/safe_local_iterator.tcc b/libstdc++-v3/include/debug/safe_local_iterator.tcc index 6fba344f16a..2444f41bb85 100644 --- a/libstdc++-v3/include/debug/safe_local_iterator.tcc +++ b/libstdc++-v3/include/debug/safe_local_iterator.tcc @@ -78,7 +78,13 @@ namespace __gnu_debug _M_valid_range(const _Safe_local_iterator& __rhs, std::pair& __dist) const { - if (!_M_can_compare(__rhs)) + if (_M_value_initialized() && __rhs._M_value_initialized()) + { + __dist = { 0, __dp_exact }; + return true; + } + + if (_M_singular() || __rhs._M_singular() || !_M_can_compare(__rhs)) return false; if (bucket() != __rhs.bucket()) diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/114316.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/114316.cc new file mode 100644 index 000..41b649a9cbd --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/114316.cc @@ -0,0 +1,28 @@ +// { dg-do run { target c++11 } } +// { dg-require-debug-mode "" } + +// PR libstdc++/114316 + +#include +#include + +#include + +void test01() +{ + std::unordered_set::iterator it{}; + VERIFY( std::find(it, it, 0) == it ); +} + +void test02() +{ + std::unordered_set::local_iterator it{}; + VERIFY( std::find(it, it, 0) == it ); +} + +int main() +{ + test01(); + test02(); + return 0; +}
[gcc r13-8471] libstdc++: Fix N3344 behavior on _Safe_iterator::_M_can_advance
https://gcc.gnu.org/g:51e2f7a22e82a7cb2d321b82613b477b58ee4c60 commit r13-8471-g51e2f7a22e82a7cb2d321b82613b477b58ee4c60 Author: François Dumont Date: Sun Mar 17 19:06:55 2024 +0100 libstdc++: Fix N3344 behavior on _Safe_iterator::_M_can_advance We shall be able to advance from a 0 offset a value-initialized iterator. libstdc++-v3/ChangeLog: * include/debug/safe_iterator.tcc (_Safe_iterator<>::_M_can_advance): Accept 0 offset advance on value-initialized iterator. * testsuite/23_containers/vector/debug/n3644.cc: New test case. (cherry picked from commit dda96a9d942d73a587e174dd5efe061208a195af) Diff: --- libstdc++-v3/include/debug/safe_iterator.tcc | 3 +++ .../testsuite/23_containers/vector/debug/n3644.cc| 16 2 files changed, 19 insertions(+) diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc b/libstdc++-v3/include/debug/safe_iterator.tcc index 2640fc8a473..4e213c4a0f6 100644 --- a/libstdc++-v3/include/debug/safe_iterator.tcc +++ b/libstdc++-v3/include/debug/safe_iterator.tcc @@ -86,6 +86,9 @@ namespace __gnu_debug _Safe_iterator<_Iterator, _Sequence, _Category>:: _M_can_advance(difference_type __n, bool __strict) const { + if (this->_M_value_initialized() && __n == 0) + return true; + if (this->_M_singular()) return false; diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/n3644.cc b/libstdc++-v3/testsuite/23_containers/vector/debug/n3644.cc new file mode 100644 index 000..052c52f26b7 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/debug/n3644.cc @@ -0,0 +1,16 @@ +// { dg-do run { target c++11 } } +// { dg-require-debug-mode "" } + +#include +#include + +#include + +int main() +{ + std::vector::iterator it{}; + auto cpy = it; + std::advance(it, 0); + VERIFY( it == cpy ); + return 0; +}
[gcc r14-9580] libstdc++: [_GLIBCXX_DEBUG] Define __cpp_lib_null_iterators
https://gcc.gnu.org/g:d2b25083a41347ce3d2875fcd932dcb08756058a commit r14-9580-gd2b25083a41347ce3d2875fcd932dcb08756058a Author: François Dumont Date: Wed Mar 20 06:47:20 2024 +0100 libstdc++: [_GLIBCXX_DEBUG] Define __cpp_lib_null_iterators _GLIBCXX_DEBUG has now fully N3344 compliant iterator checks, we can define __cpp_lib_null_iterators macros like the normal mode. libstdc++-v3/ChangeLog: * include/bits/version.def (null_iterators): Remove extra_cond. * include/bits/version.h: Regenerate. Diff: --- libstdc++-v3/include/bits/version.def | 1 - libstdc++-v3/include/bits/version.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def index be5af18e818..26e62c6a9b2 100644 --- a/libstdc++-v3/include/bits/version.def +++ b/libstdc++-v3/include/bits/version.def @@ -209,7 +209,6 @@ ftms = { values = { v = 201304; cxxmin = 14; -extra_cond = "!defined(_GLIBCXX_DEBUG)"; }; }; diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h index 9107b45a484..23c8c09ab4b 100644 --- a/libstdc++-v3/include/bits/version.h +++ b/libstdc++-v3/include/bits/version.h @@ -214,7 +214,7 @@ #undef __glibcxx_want_make_reverse_iterator #if !defined(__cpp_lib_null_iterators) -# if (__cplusplus >= 201402L) && (!defined(_GLIBCXX_DEBUG)) +# if (__cplusplus >= 201402L) # define __glibcxx_null_iterators 201304L # if defined(__glibcxx_want_all) || defined(__glibcxx_want_null_iterators) # define __cpp_lib_null_iterators 201304L
[gcc r15-2646] libstdc++: Make dg-error pattern more accurate
https://gcc.gnu.org/g:0d514c11ef5931d61917c0c663646e73154f8473 commit r15-2646-g0d514c11ef5931d61917c0c663646e73154f8473 Author: Jonathan Wakely Date: Thu Aug 1 06:53:03 2024 +0200 libstdc++: Make dg-error pattern more accurate Remove useless test variable and use a more accurate dg-error pattern so that only the ill-formed expression compilation error is considered. libstdc++-v3/ChangeLog: * testsuite/23_containers/map/operators/1_neg.cc (test01): Remove test variable and use 'no match' dg-error patter. * testsuite/23_containers/set/operators/1_neg.cc (test01): Likewise. Diff: --- libstdc++-v3/testsuite/23_containers/map/operators/1_neg.cc | 4 ++-- libstdc++-v3/testsuite/23_containers/set/operators/1_neg.cc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/testsuite/23_containers/map/operators/1_neg.cc b/libstdc++-v3/testsuite/23_containers/map/operators/1_neg.cc index 0eb1eee640b8..6ce7b3249d8c 100644 --- a/libstdc++-v3/testsuite/23_containers/map/operators/1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/map/operators/1_neg.cc @@ -35,6 +35,6 @@ void test01() std::map::iterator itr(mapByIndex.begin()); // NB: notice, it's not mapByIndex!! - bool __attribute__((unused)) test = itr != mapByName.end(); // { dg-error "no" } - test &= itr == mapByName.end(); // { dg-error "no" } + itr != mapByName.end(); // { dg-error "no match" } + itr == mapByName.end(); // { dg-error "no match" } } diff --git a/libstdc++-v3/testsuite/23_containers/set/operators/1_neg.cc b/libstdc++-v3/testsuite/23_containers/set/operators/1_neg.cc index 28d08f308e17..b5f69ae920c2 100644 --- a/libstdc++-v3/testsuite/23_containers/set/operators/1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/set/operators/1_neg.cc @@ -32,6 +32,6 @@ void test01() std::set::iterator itr(setByIndex.begin()); // NB: it's not setByIndex!! - bool __attribute__((unused)) test = itr != setByName.end(); // { dg-error "no" } - test &= itr == setByName.end(); // { dg-error "no" } + itr != setByName.end(); // { dg-error "no match" } + itr == setByName.end(); // { dg-error "no match" } }
[gcc r15-4614] libstdc++: Fix test broken when using COW std::string
https://gcc.gnu.org/g:d01dc97a26d2f5034ca135f46094aa52c44cc90a commit r15-4614-gd01dc97a26d2f5034ca135f46094aa52c44cc90a Author: François Dumont Date: Thu Oct 24 20:30:16 2024 +0200 libstdc++: Fix test broken when using COW std::string libstdc++-v3/ChangeLog: * testsuite/23_containers/unordered_map/96088.cc (test03): Fix increments value when _GLIBCXX_USE_CXX11_ABI is equal to 0. Diff: --- libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc index b5be7d06aa03..ee41675a16ba 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc @@ -233,9 +233,8 @@ test03() um.insert(v.begin(), v.end()); VERIFY( um.size() == 1 ); -// Allocate array of buckets, a node, the std::string value and the -// std::string key (unless COW). -constexpr std::size_t increments = _GLIBCXX_USE_CXX11_ABI ? 4 : 3; +// Allocate array of buckets, a node, and the 2 std::string (unless COW). +constexpr std::size_t increments = _GLIBCXX_USE_CXX11_ABI ? 4 : 2; VERIFY( __gnu_test::counter::count() == origin + increments ); VERIFY( __gnu_test::counter::get()._M_increments == increments );
[gcc r15-6376] libstdc++: Add fancy pointer support to std::map and std::set [PR57272]
https://gcc.gnu.org/g:23df3c3a4aa33a08e82ac8b98d7ff6e7f1b65b63 commit r15-6376-g23df3c3a4aa33a08e82ac8b98d7ff6e7f1b65b63 Author: François Dumont Date: Mon Jul 22 21:54:36 2024 +0200 libstdc++: Add fancy pointer support to std::map and std::set [PR57272] The fancy allocator pointer type support is added to std::map, std::multimap, std::multiset and std::set through the underlying std::_Rb_tree class. To respect ABI a new parralel hierarchy of node types has been added. This change introduces new class template parameterized on the allocator's void_pointer type, __rb_tree::_Node_base, and new class templates parameterized on the allocator's pointer type, __rb_tree::_Node, __rb_tree::_Iterator. The iterator class template is used for both iterator and const_iterator. Whether std::_Rb_tree should use the old _Rb_tree_node or new __rb_tree::_Node type family internally is controlled by a new __rb_tree::_Node_traits traits template. Because std::pointer_traits and std::__to_address are not defined for C++98, there is no way to support fancy pointers in C++98. For C++98 the _Node_traits traits always choose the old _Rb_tree_node family. In case anybody is currently using std::_Rb_tree with an allocator that has a fancy pointer, this change would be an ABI break, because their std::_Rb_tree instantiations would start to (correctly) use the fancy pointer type. If the fancy pointer just contains a single pointer and so has the same size, layout, and object representation as a raw pointer, the code might still work (despite being an ODR violation). But if their fancy pointer has a different representation, they would need to recompile all their code using that allocator with std::_Rb_tree. Because std::_Rb_tree will never use fancy pointers in C++98 mode, recompiling everything to use fancy pointers isn't even possible if mixing C++98 and C++11 code that uses std::_Rb_tree. To alleviate this problem, compiling with -D_GLIBCXX_USE_ALLOC_PTR_FOR_RB_TREE=0 will force std::_Rb_tree to have the old, non-conforming behaviour and use raw pointers internally. For testing purposes, compiling with -D_GLIBCXX_USE_ALLOC_PTR_FOR_RB_TREE=9001 will force std::_Rb_tree to always use the new node types. This macro is currently undocumented, which needs to be fixed. As _Rb_tree is using _Base_ptr to represent the tree this change also simplifies the implementation by removing all the const pointer types and associated methods. libstdc++-v3/ChangeLog: PR libstdc++/57272 * include/bits/stl_tree.h [_GLIBCXX_USE_ALLOC_PTR_FOR_RB_TREE]: New macro to control usage of the code required to support fancy allocator pointer type. (_Rb_tree_node_base::_Const_Base_ptr): Remove. (_Rb_tree_node_base::_S_minimum, _Rb_tree_node_base::_S_maximum): Remove overloads for _Const_Base_ptr. (_Rb_tree_node_base::_M_base_ptr()): New. (_Rb_tree_node::_Link_type): Remove. (_Rb_tree_node::_M_node_ptr()): New. (__rb_tree::_Node_base<>): New. (__rb_tree::_Header<>): New. (__rb_tree::_Node<>): New. (_Rb_tree_increment(const _Rb_tree_node_base*)): Remove declaration. (_Rb_tree_decrement(const _Rb_tree_node_base*)): Remove declaration. (_Rb_tree_iterator<>::_Self): Remove. (_Rb_tree_iterator<>::_Link_type): Rename into... (_Rb_tree_iterator<>::_Node_ptr): ...this. (_Rb_tree_const_iterator<>::_Link_type): Rename into... (_Rb_tree_const_iterator<>::_Node_ptr): ...this. (_Rb_tree_const_iterator<>::_M_const_cast): Remove. (_Rb_tree_const_iterator<>::_M_node): Change type into _Base_ptr. (__rb_tree::_Iterator<>): New. (__rb_tree::_Node_traits<>): New. (_Rb_tree<>::_Node_base, _Rb_tree::_Node): New. (_Rb_tree<>::_Link_type): Rename into... (_Rb_tree<>::_Node_ptr): ...this. (_Rb_tree<>::_Const_Base_ptr, _Rb_tree<>::_Const_Node_ptr): Remove. (_Rb_tree<>::_M_mbegin): Remove. (_Rb_tree<>::_M_begin_node()): New. (_S_key(const _Node&)): New. (_S_key(_Base_ptr)): New, call latter. (_S_key(_Node_ptr)): Likewise. (_Rb_tree<>::_S_left(_Const_Base_ptr)): Remove. (_Rb_tree<>::_S_right(_Const_Base_ptr)): Remove. (_Rb_tree<>::_S_maximum(_Const_Base_ptr)): Remove. (_Rb_tree<>::_S_minimum(_Const_Base_ptr)): Remove. * testsuite/23_containers/map/allocator/ext_ptr.cc: New test case. * testsuite/23_containers/multimap/allocator/ext_ptr.cc: New test case. * testsuite/23_containers/multiset/allocator/ext_ptr.cc: New test case.
[gcc r15-9600] libstdc++: [_GLIBCXX_INLINE_VERSION] Fix tests failures
https://gcc.gnu.org/g:9483020ea576516448f6e820fba4b14257d6268e commit r15-9600-g9483020ea576516448f6e820fba4b14257d6268e Author: François Dumont Date: Mon Apr 28 18:53:36 2025 +0200 libstdc++: [_GLIBCXX_INLINE_VERSION] Fix tests failures Adapt testsuite v3_target_compile to strip version namespace from compiler output so that dg-error and dg-warning directives do not need to consider it. Avoid a aligned_storage check as behavior has been fixed only when using gnu-versioned-namespace as it is an abi breaking change. libstdc++-v3/ChangeLog: * testsuite/lib/libstdc++.exp (v3_target_compile): Strip version namespace from compiler output. * testsuite/20_util/aligned_storage/value.cc [_GLIBCXX_INLINE_VERSION]: Avoid align_msa check. * testsuite/20_util/function/cons/70692.cc: Remove now useless __8 namespace pattern. * testsuite/23_containers/map/48101_neg.cc: Likewise. * testsuite/23_containers/multimap/48101_neg.cc: Likewise. Co-authored-by: Jonathan Wakely (cherry picked from commit 8709d6a17830c8a9f48cb3ac6dfc6af76f2e1e81) Diff: --- libstdc++-v3/testsuite/20_util/aligned_storage/value.cc| 6 -- libstdc++-v3/testsuite/20_util/function/cons/70692.cc | 2 +- libstdc++-v3/testsuite/23_containers/map/48101_neg.cc | 4 ++-- libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc | 4 ++-- libstdc++-v3/testsuite/lib/libstdc++.exp | 5 + 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/libstdc++-v3/testsuite/20_util/aligned_storage/value.cc b/libstdc++-v3/testsuite/20_util/aligned_storage/value.cc index e2c6f7b5b494..6a2c42489e87 100644 --- a/libstdc++-v3/testsuite/20_util/aligned_storage/value.cc +++ b/libstdc++-v3/testsuite/20_util/aligned_storage/value.cc @@ -21,14 +21,14 @@ #include #include -struct MSAlignType { } __attribute__((__aligned__)); +struct MSAlignType { } __attribute__((__aligned__)); void test01() { using std::aligned_storage; using std::alignment_of; using namespace __gnu_test; - + const std::size_t align_c = alignment_of::value; static_assert(sizeof(aligned_storage<4, align_c>::type) >= 4, ""); static_assert(__alignof__(aligned_storage<4, align_c>::type) == align_c, ""); @@ -55,9 +55,11 @@ void test01() static_assert(__alignof__(aligned_storage<11, align_ct>::type) == align_ct, ""); +#if !_GLIBCXX_INLINE_VERSION const std::size_t align_msa = alignment_of::value; static_assert(sizeof(aligned_storage<5>::type) >= 5, ""); static_assert(__alignof__(aligned_storage<5>::type) == align_msa, ""); +#endif } // { dg-warning "deprecated" "" { target c++23 } 0 } diff --git a/libstdc++-v3/testsuite/20_util/function/cons/70692.cc b/libstdc++-v3/testsuite/20_util/function/cons/70692.cc index b15208a25317..f9e8fe31570c 100644 --- a/libstdc++-v3/testsuite/20_util/function/cons/70692.cc +++ b/libstdc++-v3/testsuite/20_util/function/cons/70692.cc @@ -11,4 +11,4 @@ int main() std::function ff(f); // { dg-error "no matching function" } std::function f2(f); // { dg-error "no matching function" } } -// { dg-error "std::(__8::)?enable_if" "" { target *-*-* } 0 } +// { dg-error "std::enable_if" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc index 0661eeb839cf..251beee24be1 100644 --- a/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc @@ -28,8 +28,8 @@ test01() c2.find(2); // { dg-error "here" } } -// { dg-error "_Compare = std::(__8::)?less" "" { target *-*-* } 0 } -// { dg-error "_Compare = std::(__8::)?allocator" "" { target *-*-* } 0 } +// { dg-error "_Compare = std::less" "" { target *-*-* } 0 } +// { dg-error "_Compare = std::allocator" "" { target *-*-* } 0 } // { dg-error "comparison object must be invocable" "" { target *-*-* } 0 } // { dg-prune-output "no match for call" } // { dg-prune-output "invalid conversion" } diff --git a/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc index f597ef3dc7ac..1c1c79d96639 100644 --- a/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc @@ -28,8 +28,8 @@ test01() c2.find(2); // { dg-error "here" } } -// { dg-error "_Compare = std::(__8::)?less" "" { target *-*-* } 0 } -// { dg-error "_Compare = std::(__8::)?allocator" "" { target *-*-* } 0 } +// { dg-error "_Compare = std::less" "" { target *-*-* } 0 } +// { dg-error "_Compare = std::allocator" "" { target *-*-* } 0 } // { dg-error "comparison object must be invocable" "" { target *-*-* } 0 } // { dg-prune-output "no match for call" } // { dg-prune-output "invalid conversion" } diff --git a/libstdc++-
[gcc r16-294] libstdc++: [_GLIBCXX_INLINE_VERSION] Fix tests failures
https://gcc.gnu.org/g:8709d6a17830c8a9f48cb3ac6dfc6af76f2e1e81 commit r16-294-g8709d6a17830c8a9f48cb3ac6dfc6af76f2e1e81 Author: François Dumont Date: Mon Apr 28 18:53:36 2025 +0200 libstdc++: [_GLIBCXX_INLINE_VERSION] Fix tests failures Adapt testsuite v3_target_compile to strip version namespace from compiler output so that dg-error and dg-warning directives do not need to consider it. Avoid a aligned_storage check as behavior has been fixed only when using gnu-versioned-namespace as it is an abi breaking change. libstdc++-v3/ChangeLog: * testsuite/lib/libstdc++.exp (v3_target_compile): Strip version namespace from compiler output. * testsuite/20_util/aligned_storage/value.cc [_GLIBCXX_INLINE_VERSION]: Avoid align_msa check. * testsuite/20_util/function/cons/70692.cc: Remove now useless __8 namespace pattern. * testsuite/23_containers/map/48101_neg.cc: Likewise. * testsuite/23_containers/multimap/48101_neg.cc: Likewise. Co-authored-by: Jonathan Wakely Diff: --- libstdc++-v3/testsuite/20_util/aligned_storage/value.cc| 6 -- libstdc++-v3/testsuite/20_util/function/cons/70692.cc | 2 +- libstdc++-v3/testsuite/23_containers/map/48101_neg.cc | 4 ++-- libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc | 4 ++-- libstdc++-v3/testsuite/lib/libstdc++.exp | 5 + 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/libstdc++-v3/testsuite/20_util/aligned_storage/value.cc b/libstdc++-v3/testsuite/20_util/aligned_storage/value.cc index e2c6f7b5b494..6a2c42489e87 100644 --- a/libstdc++-v3/testsuite/20_util/aligned_storage/value.cc +++ b/libstdc++-v3/testsuite/20_util/aligned_storage/value.cc @@ -21,14 +21,14 @@ #include #include -struct MSAlignType { } __attribute__((__aligned__)); +struct MSAlignType { } __attribute__((__aligned__)); void test01() { using std::aligned_storage; using std::alignment_of; using namespace __gnu_test; - + const std::size_t align_c = alignment_of::value; static_assert(sizeof(aligned_storage<4, align_c>::type) >= 4, ""); static_assert(__alignof__(aligned_storage<4, align_c>::type) == align_c, ""); @@ -55,9 +55,11 @@ void test01() static_assert(__alignof__(aligned_storage<11, align_ct>::type) == align_ct, ""); +#if !_GLIBCXX_INLINE_VERSION const std::size_t align_msa = alignment_of::value; static_assert(sizeof(aligned_storage<5>::type) >= 5, ""); static_assert(__alignof__(aligned_storage<5>::type) == align_msa, ""); +#endif } // { dg-warning "deprecated" "" { target c++23 } 0 } diff --git a/libstdc++-v3/testsuite/20_util/function/cons/70692.cc b/libstdc++-v3/testsuite/20_util/function/cons/70692.cc index b15208a25317..f9e8fe31570c 100644 --- a/libstdc++-v3/testsuite/20_util/function/cons/70692.cc +++ b/libstdc++-v3/testsuite/20_util/function/cons/70692.cc @@ -11,4 +11,4 @@ int main() std::function ff(f); // { dg-error "no matching function" } std::function f2(f); // { dg-error "no matching function" } } -// { dg-error "std::(__8::)?enable_if" "" { target *-*-* } 0 } +// { dg-error "std::enable_if" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc index 0661eeb839cf..251beee24be1 100644 --- a/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc @@ -28,8 +28,8 @@ test01() c2.find(2); // { dg-error "here" } } -// { dg-error "_Compare = std::(__8::)?less" "" { target *-*-* } 0 } -// { dg-error "_Compare = std::(__8::)?allocator" "" { target *-*-* } 0 } +// { dg-error "_Compare = std::less" "" { target *-*-* } 0 } +// { dg-error "_Compare = std::allocator" "" { target *-*-* } 0 } // { dg-error "comparison object must be invocable" "" { target *-*-* } 0 } // { dg-prune-output "no match for call" } // { dg-prune-output "invalid conversion" } diff --git a/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc index f597ef3dc7ac..1c1c79d96639 100644 --- a/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc @@ -28,8 +28,8 @@ test01() c2.find(2); // { dg-error "here" } } -// { dg-error "_Compare = std::(__8::)?less" "" { target *-*-* } 0 } -// { dg-error "_Compare = std::(__8::)?allocator" "" { target *-*-* } 0 } +// { dg-error "_Compare = std::less" "" { target *-*-* } 0 } +// { dg-error "_Compare = std::allocator" "" { target *-*-* } 0 } // { dg-error "comparison object must be invocable" "" { target *-*-* } 0 } // { dg-prune-output "no match for call" } // { dg-prune-output "invalid conversion" } diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp inde
[gcc r16-29] libstdc++: Add _GLIBCXX_DEBUG checks on unordered container local_iterator
https://gcc.gnu.org/g:9662c9526f8c60a192b1358671463402829279d6 commit r16-29-g9662c9526f8c60a192b1358671463402829279d6 Author: François Dumont Date: Tue Apr 8 19:35:28 2025 +0200 libstdc++: Add _GLIBCXX_DEBUG checks on unordered container local_iterator Complete tests on _GLIBCXX_DEBUG checks in include/debug/safe_local_iterator.h. Fix several tests not testing the container corresponding to their location in the testsuite directory. libstdc++-v3/ChangeLog: * testsuite/util/debug/unordered_checks.h (fill_container): New helper method. (use_erased_local_iterator, invalid_local_iterator_pre_increment) (invalid_local_iterator_post_increment, invalid_local_iterator_compare) (invalid_local_iterator_range): Use latter. (fill_and_get_local_iterator): New, use fill_container. (use_invalid_local_iterator): Use latter. (invalid_local_iterator_arrow_operator): New test function. (invalid_local_iterator_copy_instantiation): New test function. (invalid_local_iterator_move_instantiation): New test function. (invalid_local_iterator_copy_assignment): New test function. (invalid_local_iterator_move_assignment): New test function. (invalid_local_iterator_const_conversion): New test function. * testsuite/23_containers/unordered_map/debug/invalid_local_iterator_arrow_operator_neg.cc: New test case. * testsuite/23_containers/unordered_map/debug/invalid_local_iterator_const_conversion_neg.cc: New test case. * testsuite/23_containers/unordered_map/debug/invalid_local_iterator_copy_assignment_neg.cc: New test case. * testsuite/23_containers/unordered_map/debug/invalid_local_iterator_copy_construction_neg.cc: New test case. * testsuite/23_containers/unordered_map/debug/invalid_local_iterator_move_assignment_neg.cc: New test case. * testsuite/23_containers/unordered_map/debug/invalid_local_iterator_move_construction_neg.cc: New test case. * testsuite/23_containers/unordered_map/debug/max_load_factor_neg.cc: Test unordered_map. * testsuite/23_containers/unordered_multimap/debug/begin2_neg.cc: Test unordered_multimap. * testsuite/23_containers/unordered_multimap/debug/bucket_size_neg.cc: Likewise. * testsuite/23_containers/unordered_multimap/debug/cbegin_neg.cc: Likewise. * testsuite/23_containers/unordered_multimap/debug/cend_neg.cc: Likewise. * testsuite/23_containers/unordered_multimap/debug/end1_neg.cc: Likewise. * testsuite/23_containers/unordered_multimap/debug/end2_neg.cc: Likewise. * testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_arrow_operator_neg.cc: New test case. * testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_const_conversion_neg.cc: New test case. * testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_copy_assignment_neg.cc: New test case. * testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_copy_construction_neg.cc: New test case. * testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_move_assignment_neg.cc: New test case. * testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_move_construction_neg.cc: New test case. * testsuite/23_containers/unordered_multimap/debug/max_load_factor_neg.cc: Test unordered_multimap. * testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_arrow_operator_neg.cc: New test case. * testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_const_conversion_neg.cc: New test case. * testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_copy_assignment_neg.cc: New test case. * testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_copy_construction_neg.cc: New test case. * testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_move_assignment_neg.cc: New test case. * testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_move_construction_neg.cc: New test case. * testsuite/23_containers/unordered_set/debug/invalid_local_iterator_arrow_operator_neg.cc: New test case. * testsuite/23_containers/unordered_set/debug/invalid_local_iterator_const_conversion_neg.cc: New test case. * testsuite/23_containers/unordered_set/debug/invalid_local_iterator_copy_assignment_neg.c
[gcc r15-7702] libstdc++: [_Hashtable] Fix hash code cache usage when stateful hash functor
https://gcc.gnu.org/g:bcc8dea6a45b46febfa76df6f5e3e5b13f3b4a58 commit r15-7702-gbcc8dea6a45b46febfa76df6f5e3e5b13f3b4a58 Author: François Dumont Date: Sun Feb 16 19:27:49 2025 +0100 libstdc++: [_Hashtable] Fix hash code cache usage when stateful hash functor It is wrong to reuse a cached hash code from another container when this code depends on the state of the container's Hash functor. Add checks that Hash functor is stateless before reusing the cached hash code. libstdc++-v3/ChangeLog: * include/bits/hashtable_policy.h (_Hash_code_base::_M_copy_code, _Hash_code_base::_M_store_code): Remove. * include/bits/hashtable.h (_M_hash_code_ext): New. (_M_merge_multi(_Hashtable&)): Use latter. (_M_copy_code): New. (_M_assign): Use latter. (_M_bucket_index_ex): New. (_M_equals): Use latter. (_M_store_code): New. (_M_src_hash_code): Remove key_type parameter. * testsuite/23_containers/unordered_map/modifiers/merge.cc (test10): New test case. Diff: --- libstdc++-v3/include/bits/hashtable.h | 71 -- libstdc++-v3/include/bits/hashtable_policy.h | 18 -- .../23_containers/unordered_map/modifiers/merge.cc | 46 ++ 3 files changed, 98 insertions(+), 37 deletions(-) diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h index d6d76a743bbe..246e62afc6af 100644 --- a/libstdc++-v3/include/bits/hashtable.h +++ b/libstdc++-v3/include/bits/hashtable.h @@ -808,6 +808,42 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_bucket_index(__hash_code __c) const { return __hash_code_base::_M_bucket_index(__c, _M_bucket_count); } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr + // Get hash code for a node that comes from another _Hashtable. + // Reuse a cached hash code if the hash function is stateless, + // otherwise recalculate it using our own hash function. + __hash_code + _M_hash_code_ext(const __node_value_type& __from) const + { + if constexpr (__and_<__hash_cached, is_empty<_Hash>>::value) + return __from._M_hash_code; + else + return this->_M_hash_code(_ExtractKey{}(__from._M_v())); + } + + // Like _M_bucket_index but when the node is coming from another + // container instance. + size_type + _M_bucket_index_ext(const __node_value_type& __from) const + { return _RangeHash{}(_M_hash_code_ext(__from), _M_bucket_count); } + + void + _M_copy_code(__node_value_type& __to, + const __node_value_type& __from) const + { + if constexpr (__hash_cached::value) + __to._M_hash_code = _M_hash_code_ext(__from); + } + + void + _M_store_code(__node_value_type& __to, __hash_code __code) const + { + if constexpr (__hash_cached::value) + __to._M_hash_code = __code; + } +#pragma GCC diagnostic pop + // Find and insert helper functions and types // Find the node before the one matching the criteria. @@ -1210,15 +1246,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // with a hash function that might not match this->hash_function(). template __hash_code - _M_src_hash_code(const _H2&, const key_type& __k, -const __node_value_type& __src_n) const + _M_src_hash_code(const _H2&, const __node_value_type& __src_n) const { - if constexpr (std::is_same_v<_H2, _Hash>) - if constexpr (std::is_empty_v<_Hash>) - // If the node has a cached hash code, it's OK to use it. - return this->_M_hash_code(__src_n); - - return this->_M_hash_code(__k); + if constexpr (__and_<__hash_cached, + is_same<_H2, _Hash>, is_empty<_Hash>>::value) + // If the node has a cached hash code, it's OK to use it. + return __src_n._M_hash_code; + else + return this->_M_hash_code(_ExtractKey{}(__src_n._M_v())); } public: @@ -1327,9 +1362,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION do { const auto& __node = static_cast<__node_type&>(*__prev->_M_nxt); - const key_type& __k = _ExtractKey{}(__node._M_v()); - // Hash code from this->hash_function(): - auto __code = _M_src_hash_code(__src.hash_function(), __k, __node); + // Hash code from this: + auto __code = _M_hash_code_ext(__node); // Bucket index in __src, using code from __src.hash_function(): size_type __src_bkt = __src._M_bucket_index(__node); auto __nh = __src._M_extract_node(__src_bkt, __prev); @@ -1355,9 +1389,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION for (auto __i = __src.cbegin(), __end = __src.cend(); __i != __end