aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
AgeCommit message (Collapse)AuthorFilesLines
2025-01-15libstdc++: Fix comments in test that reference wrong subclause of C++11Jonathan Wakely1-3/+3
libstdc++-v3/ChangeLog: * testsuite/28_regex/traits/char/transform_primary.cc: Fix subclause numbering in references to the standard.
2025-01-15c++: Delete defaulted operator <=> if std::strong_ordering::equal doesn't ↵Jakub Jelinek1-1/+1
convert to its rettype [PR118387] Note, the PR raises another problem. If on the same testcase the B b; line is removed, we silently synthetize operator<=> which will crash at runtime due to returning without a return statement. That is because the standard says that in that case it should return static_cast<int>(std::strong_ordering::equal); but I can't find anywhere wording which would say that if that isn't valid, the function is deleted. https://eel.is/c++draft/class.compare#class.spaceship-2.2 seems to talk just about cases where there are some members and their comparison is invalid it is deleted, but here there are none and it follows https://eel.is/c++draft/class.compare#class.spaceship-3.sentence-2 So, we synthetize with tf_none, see the static_cast is invalid, don't add error_mark_node statement silently, but as the function isn't deleted, we just silently emit it. Should the standard be amended to say that the operator should be deleted even if it has no elements and the static cast from https://eel.is/c++draft/class.compare#class.spaceship-3.sentence-2 On Fri, Jan 10, 2025 at 12:04:53PM -0500, Jason Merrill wrote: > That seems pretty obviously what we want, and is what the other compilers > implement. This patch implements it then. 2025-01-15 Jakub Jelinek <jakub@redhat.com> PR c++/118387 * method.cc (build_comparison_op): Set bad if std::strong_ordering::equal doesn't convert to rettype. * g++.dg/cpp2a/spaceship-err6.C: Expect another error. * g++.dg/cpp2a/spaceship-synth17.C: Likewise. * g++.dg/cpp2a/spaceship-synth-neg6.C: Likewise. * g++.dg/cpp2a/spaceship-synth-neg7.C: New test. * testsuite/25_algorithms/default_template_value.cc (Input::operator<=>): Use auto as return type rather than bool.
2025-01-13Daily bump.GCC Administrator1-0/+10
2025-01-12testsuite: The expect framework might introduce CR in outputTorbjörn SVENSSON2-2/+2
When running tests using the "sim" config, the command is launched in non-readonly mode and the text retrieved from the expect command will then replace all LF with CRLF. (The problem can be found in sim_load where it calls remote_spawn without an input file). libstdc++-v3/ChangeLog: * testsuite/27_io/print/1.cc: Allow both LF and CRLF in test. * testsuite/27_io/print/3.cc: Likewise. Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
2025-01-12testsuite: libstdc++: Use effective-target libatomicTorbjörn SVENSSON1-0/+1
Test assumes libatomic.a is always available, but for some embedded targets, there is no libatomic.a and the test thus fail. libstdc++-v3/ChangeLog: * testsuite/29_atomics/atomic_float/compare_exchange_padding.cc: Use effective-target libatomic_available. Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
2025-01-11Daily bump.GCC Administrator1-0/+5
2025-01-10libstdc++: Fix unused parameter warnings in <bits/atomic_futex.h>Jonathan Wakely1-6/+6
This fixes warnings like the following during bootstrap: sparc-sun-solaris2.11/libstdc++-v3/include/bits/atomic_futex.h:324:53: warning: unused parameter ‘__mo’ [-Wunused-parameter] 324 | _M_load_when_equal(unsigned __val, memory_order __mo) | ~~~~~~~~~~~~~^~~~ libstdc++-v3/ChangeLog: * include/bits/atomic_futex.h (__atomic_futex_unsigned): Remove names of unused parameters in non-futex implementation.
2025-01-09Daily bump.GCC Administrator1-0/+97
2025-01-08libstdc++: Add always_inline to casting/forwarding functions in bits/move.hJonathan Wakely1-7/+8
libstdc++-v3/ChangeLog: * include/bits/move.h (__addressof, forward, forward_like, move) (move_if_noexcept, addressof): Add always_inline attribute. Replace _GLIBCXX_NODISCARD with [[__nodiscard__]].
2025-01-08libstdc++: Make GDB skip over some library functions [PR118260]Jonathan Wakely1-0/+5
libstdc++-v3/ChangeLog: PR libstdc++/118260 * python/hook.in: Run 'skip' commands for some simple accessor functions.
2025-01-08libstdc++: add missing to_underlying to module std [PR106852]Nicolas Werner1-0/+3
std::to_underlying was missing from the std module introduced in r15-5366-g7db55c0ba1baaf. This patch adds the missing export for this utility. libstdc++-v3/ChangeLog: PR libstdc++/106852 * src/c++23/std.cc.in (to_underlying): Add. Signed-off-by: Nicolas Werner <nicolas.werner@hotmail.de>
2025-01-08libstdc++: Use preprocessor conditions in std module [PR118177]Jonathan Wakely2-0/+48
The std-clib.cc module definition file assumes that all names are available unconditionally, but that's not true for all targets. Use the same preprocessor conditions as are present in the <cxxx> headers. A similar change is needed in std.cc.in for the <chrono> features that depend on the SSO std::string, guarded with a __cpp_lib_chrono value indicating full C++20 support. The conditions for <cmath> are omitted from this change, as there are a large number of them. That probably needs to be fixed. libstdc++-v3/ChangeLog: PR libstdc++/118177 * src/c++23/std-clib.cc.in: Use preprocessor conditions for names which are not always defined. * src/c++23/std.cc.in: Likewise.
2025-01-08libstdc++: Adjust indentation of new std::span constructorJonathan Wakely1-7/+6
libstdc++-v3/ChangeLog: * include/std/span: Fix indentation.
2025-01-08libstdc++: add initializer_list constructor to std::span (P2447R6)Giuseppe D'Angelo5-0/+136
This commit implements P2447R6. The code is straightforward (just one extra constructor, with constraints and conditional explicit). I decided to suppress -Winit-list-lifetime because otherwise it would give too many false positives. The new constructor is meant to be used as a parameter-passing interface (this is a design choice, see P2447R6/§2) and, as such, the initializer_list won't dangle despite GCC's warnings. The new constructor isn't 100% backwards compatible. A couple of examples are included in Annex C, but I have also lifted some more from R4. A new test checks for the old and the new behaviors. libstdc++-v3/ChangeLog: * include/bits/version.def: Add the new feature-testing macro. * include/bits/version.h: Regenerate. * include/std/span: Add constructor from initializer_list. * testsuite/23_containers/span/init_list_cons.cc: New test. * testsuite/23_containers/span/init_list_cons_neg.cc: New test. Signed-off-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
2025-01-08libstdc++: Avoid redundant assertions in std::span constructorsJonathan Wakely1-34/+44
Any std::span<T, N> constructor with a runtime length has a precondition that the length is equal to N (except when N == std::dynamic_extent). Currently every constructor with a runtime length does: if constexpr (extent != dynamic_extent) __glibcxx_assert(n == extent); We can move those assertions into the __detail::__extent_storage<N> constructor so they are only done in one place. To avoid checking the assertions when we have a constant length we can add a second constructor which is consteval and takes a integral_constant<size_t, N> argument. The std::span constructors can pass a size_t for runtime lengths and a std::integral_constant<size_t, N> for constant lengths that don't need to be checked. The __detail::__extent_storage<dynamic_extent> specialization only needs one constructor, as a std::integral_constant<size_t, N> argument can implicitly convert to size_t. For the member functions that return a subspan with a constant extent we return std::span<T,C>(ptr, C) which is redundant in two ways. Repeating the constant length C when it's already a template argument is redundant, and using the std::span(T*, size_t) constructor implies a runtime length which will do a redundant assertion check. Even though that assertion won't fail and should be optimized away, it's still unnecessary code that doesn't need to be instantiated and then optimized away again. We can avoid that by adding a new private constructor that only takes a pointer (wrapped in a custom tag struct to avoid accidentally using that constructor) and automatically sets _M_extent to the correct value. libstdc++-v3/ChangeLog: * include/std/span (__detail::__extent_storage): Check precondition in constructor. Add consteval constructor for valid lengths and deleted constructor for invalid constant lengths. Make member functions always_inline. (__detail::__span_ptr): New class template. (span): Adjust constructors to use a std::integral_constant value for constant lengths. Declare all specializations of std::span as friends. (span::first<C>, span::last<C>, span::subspan<O,C>): Use new private constructor. (span(__span_ptr<T>)): New private constructor for constant lengths.
2025-01-08libstdc++: Handle errors from strxfrm in std::collate::transform [PR85824]Jonathan Wakely2-41/+99
std::regex builds a cache of equivalence classes by calling std::regex_traits<char>::transform_primary(c) for every char, which then calls std::collate<char>::transform which calls strxfrm. On several targets strxfrm fails for non-ASCII characters. Because strxfrm has no return value reserved to indicate an error, some implementations return INT_MAX or SIZE_MAX. This causes std::collate::transform to try to allocate a huge buffer, which is either very slow or throws std::bad_alloc. We should check errno after calling strxfrm to detect errors and then throw a more appropriate exception instead of trying to allocate a huge buffer. Unfortunately the std::collate<C>::_M_transform function has a non-throwing exception specifier, so we can't do the error handling there. As well as checking errno, this patch changes std::collate::do_transform to use __builtin_alloca for small inputs, and to use RAII to deallocate the buffers used for large inputs. This change isn't sufficient to fix the three std::regex bugs caused by the lack of error handling in std::collate::do_transform, we also need to make std::regex_traits::transform_primary handle exceptions. This change also attempts to make transform_primary closer to the effects described in the standard, by not even attempting to use std::collate if the locale's std::collate facet has been replaced (see PR 118105). Implementing the correct effects for transform_primary requires RTTI, so that we don't use some user-defined std::collate facet with unknown semantics. When -fno-rtti is used transform_primary just returns an empty string, making equivalence classes unusable in std::basic_regex. That's not ideal, but I don't have any better ideas. I'm unsure if std::regex_traits<C>::transform_primary is supposed to convert the string to lower case or not. The general regex traits requirements ([re.req] p20) do say "when character case is not considered" but the specification for the std::regex_traits<char> and std::regex_traits<wchar_t> specializations ([re.traits] p7) don't say anything about that. With the r15-6317-geb339c29ee42aa change, transform_primary is not called unless the regex actually uses an equivalence class. But using an equivalence class would still fail (or be incredibly slow) on some targets. With this commit, equivalence classes should be usable on all targets, without excessive memory allocations. Arguably, we should not even try to call transform_primary for any char values over 127, since they're never valid in locales that use UTF-8 or 7-bit ASCII, and probably for other charsets too. Handling 128 exceptions for every std::regex compilation is very inefficient, but at least it now works instead of failing with std::bad_alloc, and no longer allocates 128 x 2GB. Maybe for C++26 we could check the locale's std::text_encoding and use that to decide whether to cache equivalence classes for char values over 127. libstdc++-v3/ChangeLog: PR libstdc++/85824 PR libstdc++/94409 PR libstdc++/98723 PR libstdc++/118105 * include/bits/locale_classes.tcc (collate::do_transform): Check errno after calling _M_transform. Use RAII type to manage the buffer and to restore errno. * include/bits/regex.h (regex_traits::transform_primary): Handle exceptions from std::collate::transform and do not try to use std::collate for user-defined facets.
2025-01-08libstdc++: Fix std::future::wait_until for subsecond negative times [PR118093]Jonathan Wakely3-10/+40
The current check for negative times (i.e. before the epoch) only checks for a negative number of seconds. For a time 1ms before the epoch the seconds part will be zero, but the futex syscall will still fail with an EINVAL error. Extend the check to handle this case. This change adds a redundant check in the headers too, so that we avoid even calling into the library for negative times. Both checks can be marked [[unlikely]]. The check in the headers avoids the cost of splitting the time into seconds and nanoseconds and then making a PLT call. The check inside the library matches where we were checking already, and fixes existing binaries that were compiled against older headers but use a newer libstdc++.so.6 at runtime. libstdc++-v3/ChangeLog: PR libstdc++/118093 * include/bits/atomic_futex.h (_M_load_and_test_until_impl): Return false for times before the epoch. * src/c++11/futex.cc (_M_futex_wait_until): Extend check for negative times to check for subsecond times. Add unlikely attribute. (_M_futex_wait_until_steady): Likewise. * testsuite/30_threads/future/members/118093.cc: New test.
2025-01-08libstdc++: Fix std::deque::emplace calling wrong _M_insert_aux [PR90389]Jonathan Wakely3-4/+51
We have several overloads of std::deque::_M_insert_aux, one of which is variadic and called by std::deque::emplace. With a suitable set of arguments to emplace, it's possible for one of the non-variadic _M_insert_aux overloads to be selected by overload resolution, making emplace ill-formed. Rename the variadic _M_insert_aux to _M_emplace_aux so that calls to emplace never select an _M_insert_aux overload. Also add an inline _M_insert_aux for the const lvalue overload that is called from insert(const_iterator, const value_type&). libstdc++-v3/ChangeLog: PR libstdc++/90389 * include/bits/deque.tcc (_M_insert_aux): Rename variadic overload to _M_emplace_aux. * include/bits/stl_deque.h (_M_insert_aux): Define inline. (_M_emplace_aux): Declare. * testsuite/23_containers/deque/modifiers/emplace/90389.cc: New test.
2025-01-08libstdc++: Add Doxygen docs for std::forward_likeJonathan Wakely1-0/+12
Also add "@since C++11" to std::move, std::forward etc. libstdc++-v3/ChangeLog: * include/bits/move.h (forward, move, move_if_noexcept, addressof): Add @since to Doxygen comments. (forward_like): Add Doxygen comment.
2025-01-08libstdc++: Fix incorrect DocBook element in manualJonathan Wakely3-6/+6
libstdc++-v3/ChangeLog: * doc/xml/manual/evolution.xml: Replace invalid <variable> elements with <varname>. * doc/html/*: Regenerate.
2025-01-02Update copyright years.Jakub Jelinek1-1/+1
2025-01-02Update copyright years.Jakub Jelinek10144-10145/+10145
2025-01-02Rotate ChangeLog files.Jakub Jelinek5-7160/+7161
Rotate ChangeLog files for ChangeLogs with yearly cadence. Also remove empty lines before Form Feed line.
2025-01-02Daily bump.GCC Administrator1-0/+9
2025-01-01libstdc++: Delete further Profile Mode leftoversGerald Pfeifer6-409/+0
Commit 544be2beb1fa in 2019 remove Profile Mode and associated docs. Now also remove generated HTML files. libstdc++-v3: * doc/html/manual/profile_mode.html: Delete. * doc/html/manual/profile_mode_api.html: Ditto. * doc/html/manual/profile_mode_cost_model.html: Ditto. * doc/html/manual/profile_mode_design.html: Ditto. * doc/html/manual/profile_mode_devel.html: Ditto. * doc/html/manual/profile_mode_impl.html: Ditto.
2024-12-30Daily bump.GCC Administrator1-0/+11
2024-12-29libstdc++: Delete leftover from Profile Mode removalGerald Pfeifer1-557/+0
Commit 544be2beb1fa in 2019 remove Profile Mode and associated docs including the XML version of profile_mode_diagnostics.html. Somehow the latter survived until now. Simply delete it as well. libstdc++-v3: * doc/html/manual/profile_mode_diagnostics.html: Delete.
2024-12-29libstdc++-v3/testsuite/.../year_month_day/3.cc, 4.cc: Cut down for simulatorsHans-Peter Nilsson2-2/+19
These two long-running tests happened to fail for me when run in parallel (nprocs - 1) compared to a serial run, for target mmix on my laptop. The runtime is 3m40s for 3.cc before this change, and 0.9s afterwards. * testsuite/std/time/year_month_day/3.cc (test01): Add ifdeffery to limit the tested dates. For simulators, pass start and end dates limiting the tested range to 100000 days, centered on days (0). * testsuite/std/time/year_month_day/4.cc: Ditto.
2024-12-29Daily bump.GCC Administrator1-0/+6
2024-12-28libstdc++: Fix up pr118196.cc test [PR118196]Jakub Jelinek1-1/+1
The test used #include "<generator>", so FAILed everywhere with fatal error: <generator>: No such file or directory 2024-12-28 Jakub Jelinek <jakub@redhat.com> PR libstdc++/118196 * testsuite/24_iterators/range_generators/pr118196.cc: Include <generator> rather than "<generator>".
2024-12-28Daily bump.GCC Administrator1-0/+15
2024-12-27libstdc++: add missing return in generator assignment operator [PR118196]Arsen Arsenović2-0/+14
libstdc++-v3/ChangeLog: PR libstdc++/118196 * include/std/generator (generator::operator=(generator)): Add missing 'return *this;'. * testsuite/24_iterators/range_generators/pr118196.cc: New test.
2024-12-27libstdc++: don't implicit-construct _Yielded_decvref [PR118022]Arsen Arsenović2-1/+17
This overload requires constructible_from<remove_cvref_t<yielded>, const remove_reference_t<yielded>&> ... but then tries to construct remove_cvref_t<yielded> implicitly, which means it imposes an additional constraint not in the standard. libstdc++-v3/ChangeLog: PR libstdc++/118022 * include/std/generator (_Promise_erased::yield_value(const _Yielded_deref&)): Don't implicit-constuct _Yielded_decvref. * testsuite/24_iterators/range_generators/pr118022.cc: New test.
2024-12-20Daily bump.GCC Administrator1-0/+89
2024-12-19libstdc++: Add fancy pointer support to std::map and std::set [PR57272]François Dumont7-379/+1221
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<K, V, KoV, C, A> should use the old _Rb_tree_node<V> or new __rb_tree::_Node<A::pointer> 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. * testsuite/23_containers/set/allocator/ext_ptr.cc: New test case. * testsuite/23_containers/set/requirements/explicit_instantiation/alloc_ptr.cc: New test case. * testsuite/23_containers/set/requirements/explicit_instantiation/alloc_ptr_ignored.cc: New test case.
2024-12-19libstdc++: Implement C++23 <flat_set> (P1222R4)Patrick Palka9-0/+1368
This implements the C++23 container adaptors std::flat_set and std::flat_multiset from P1222R4. The implementation is essentially an simpler and pared down version of std::flat_map. libstdc++-v3/ChangeLog: * include/Makefile.am: Add new header <flat_set>. * include/Makefile.in: Regenerate. * include/bits/version.def (__cpp_flat_set): Define. * include/bits/version.h: Regenerate * include/precompiled/stdc++.h: Include <flat_set>. * include/std/flat_set: New file. * src/c++23/std.cc.in: Export <flat_set>. * testsuite/23_containers/flat_multiset/1.cc: New test. * testsuite/23_containers/flat_set/1.cc: New test. Co-authored-by: Jonathan Wakely <jwakely@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2024-12-19libstdc++: Implement C++23 <flat_map> (P0429R9)Patrick Palka14-0/+1961
This implements the C++23 container adaptors std::flat_map and std::flat_multimap from P0429R9. The implementation is shared as much as possible between the two adaptors via a common base class that's parameterized according to key uniqueness. libstdc++-v3/ChangeLog: * include/Makefile.am: Add new header <flat_map>. * include/Makefile.in: Regenerate. * include/bits/alloc_traits.h (__not_allocator_like): New concept. * include/bits/stl_function.h (__transparent_comparator): Likewise. * include/bits/stl_iterator_base_types.h (__has_input_iter_cat): Likewise. * include/bits/uses_allocator.h (__allocator_for): Likewise. * include/bits/utility.h (sorted_unique_t): Define for C++23. (sorted_unique): Likewise. (sorted_equivalent_t): Likewise. (sorted_equivalent): Likewise. * include/bits/version.def (flat_map): Define. * include/bits/version.h: Regenerate. * include/precompiled/stdc++.h: Include <flat_map>. * include/std/flat_map: New file. * src/c++23/std.cc.in: Export <flat_map>. * testsuite/23_containers/flat_map/1.cc: New test. * testsuite/23_containers/flat_multimap/1.cc: New test. Co-authored-by: Jonathan Wakely <jwakely@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2024-12-19libstdc++: Define P1206R7 range-key-type and range-mapped-type aliasesPatrick Palka1-0/+8
libstdc++-v3/ChangeLog: * include/bits/ranges_base.h (__detail::__range_key_type): Define as per P1206R7. (__detail::__range_mapped_type): Likewise. Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2024-12-19Daily bump.GCC Administrator1-0/+34
2024-12-18libstdc++: Have std::addressof use __builtin_addressofFrançois Dumont1-1/+1
Rather than calling std::__addressof in std::addressof we can directly call __builtin_addressof to bypass 1 function call. libstdc++-v3/ChangeLog: * include/bits/move.h (std::addressof): Call __builtin_addressof.
2024-12-18libstdc++: Adjust probabilities of hashmap loop conditionsTamar Christina1-2/+2
We are currently generating a loop which has more comparisons than you'd typically need as the probablities on the small size loop are such that it assumes the likely case is that an element is not found. This again generates a pattern that's harder for branch predictors to follow, but also just generates more instructions for the what one could say is the typical case: That your hashtable contains the entry you are looking for. This patch adds a __builtin_expect in _M_find_before_node where at the moment the loop is optimized for the case where we don't do any iterations. A simple testcase is (compiled with -fno-split-path to simulate the loop in libstdc++): #include <stdbool.h> bool foo (int **a, int n, int val, int *tkn) { for (int i = 0; i < n; i++) { if (!a[i] || a[i]==tkn) return false; if (*a[i] == val) return true; } } which generataes: foo: cmp w1, 0 ble .L1 add x1, x0, w1, uxtw 3 b .L4 .L9: ldr w4, [x4] cmp w4, w2 beq .L6 cmp x0, x1 beq .L1 .L4: ldr x4, [x0] add x0, x0, 8 cmp x4, 0 ccmp x4, x3, 4, ne bne .L9 mov w0, 0 .L1: ret .L6: mov w0, 1 ret i.e. BB rotation makes is generate an unconditional branch to a conditional branch. However this method is only called when the size is above a certain threshold, and so it's likely that we have to do that first iteration. Adding: #include <stdbool.h> bool foo (int **a, int n, int val, int *tkn) { for (int i = 0; i < n; i++) { if (__builtin_expect(!a[i] || a[i]==tkn, 0)) return false; if (*a[i] == val) return true; } } to indicate that we will likely do an iteration more generates: foo: cmp w1, 0 ble .L1 add x1, x0, w1, uxtw 3 .L4: ldr x4, [x0] add x0, x0, 8 cmp x4, 0 ccmp x4, x3, 4, ne beq .L5 ldr w4, [x4] cmp w4, w2 beq .L6 cmp x0, x1 bne .L4 .L1: ret .L5: mov w0, 0 ret .L6: mov w0, 1 ret which results in ~0-10% extra on top of the previous patch. In table form: +-------------+---------------+-------+--------------------+-------------------+-----------------+ | benchmark | Type | Size | Inline vs baseline | final vs baseline | final vs inline | +-------------+---------------+-------+--------------------+-------------------+-----------------+ | find many | uint64_t | 11253 | -15.67% | -22.96% | -8.65% | | find many | uint64_t | 11253 | -16.74% | -23.37% | -7.96% | | find single | uint64_t | 345 | -5.88% | -11.54% | -6.02% | | find many | string | 11253 | -4.50% | -9.56% | -5.29% | | find single | uint64_t | 345 | -4.38% | -9.41% | -5.26% | | find single | shared string | 11253 | -6.67% | -11.00% | -4.64% | | find single | shared string | 11253 | -4.63% | -9.03% | -4.61% | | find single | shared string | 345 | -10.41% | -14.44% | -4.50% | | find many | string | 11253 | -3.41% | -7.51% | -4.24% | | find many | shared string | 11253 | -2.30% | -5.72% | -3.50% | | find many | string | 13 | 2.86% | -0.30% | -3.07% | | find single | string | 11253 | 4.47% | 1.34% | -3.00% | | find many | custom string | 11253 | 0.25% | -2.75% | -2.99% | | find single | uint64_t | 345 | 2.99% | 0.01% | -2.90% | | find single | shared string | 345 | -11.53% | -13.67% | -2.41% | | find single | uint64_t | 11253 | 0.49% | -1.59% | -2.07% | +-------------+---------------+-------+--------------------+-------------------+-----------------+ libstdc++-v3/ChangeLog: * include/bits/hashtable.h (_M_find_before_node): Make it likely that the map has at least one entry and so we do at least one iteration.
2024-12-18libstdc++: Clear std::priority_queue after moving from it [PR118088]Jonathan Wakely2-3/+106
We don't know what state an arbitrary sequence container will be in after moving from it, so a moved-from std::priority_queue needs to clear the moved-from container to ensure it doesn't contain elements that are in an invalid order for the queue. An alternative would be to call std::make_heap again to re-establish the rvalue queue's invariant, but that could potentially cause an exception to be thrown. Just clearing it so the sequence is empty seems safer and more likely to match user expectations. libstdc++-v3/ChangeLog: PR libstdc++/118088 * include/bits/stl_queue.h (priority_queue(priority_queue&&)): Clear the source object after moving from it. (priority_queue(priority_queue&&, const Alloc&)): Likewise. (operator=(priority_queue&&)): Likewise. * testsuite/23_containers/priority_queue/118088.cc: New test. Reviewed-by: Patrick Palka <ppalka@redhat.com>
2024-12-18libstdc++: Add inline keyword to _M_locateTamar Christina1-1/+1
In GCC 12 there was a ~40% regression in the performance of hashmap->find. This regression came about accidentally: Before GCC 12 the find function was small enough that IPA would inline it even though it wasn't marked inline. In GCC-12 an optimization was added to perform a linear search when the entries in the hashmap are small. This increased the size of the function enough that IPA would no longer inline. Inlining had two benefits: 1. The return value is a reference. so it has to be returned and dereferenced even though the search loop may have already dereference it. 2. The pattern is a hard pattern to track for branch predictors. This causes a large number of branch misses if the value is immediately checked and branched on. i.e. if (a != m.end()) which is a common pattern. The patch fixes both these issues by adding the inline keyword to _M_locate to allow the inliner to consider inlining again. This and the other patches have been ran through serveral benchmarks where the size, number of elements searched for and type (reference vs value) etc were tested. The change shows no statistical regression, but an average find improvement of ~27% and a range between ~10-60% improvements. A selection of the results: +-----------+--------------------+-------+----------+ | Group | Benchmark | Size | % Inline | +-----------+--------------------+-------+----------+ | Find | unord<uint64_t | 11274 | 53.52% | | Find | unord<uint64_t | 11254 | 47.98% | | Find Mult | unord<uint64_t | 12 | 47.62% | | Find Mult | unord<std::string | 12 | 44.94% | | Find Mult | unord<std::string | 10 | 44.89% | | Find Mult | unord<uint64_t | 11 | 40.90% | | Find Mult | unord<uint64_t | 352 | 30.57% | | Find | unord<uint64_t | 351 | 28.27% | | Find Mult | unord<uint64_t | 342 | 26.80% | | Find | unord<std::string | 12 | 25.66% | | Find Mult | unord<std::string | 352 | 23.12% | | Find | unord<std::string | 13 | 20.36% | | Find Mult | unord<std::string | 355 | 19.23% | | Find | unord<std::string | 353 | 18.59% | | Find | unord<uint64_t | 350 | 15.43% | | Find | unord<std::string | 11260 | 11.80% | | Find | unord<std::string | 352 | 11.12% | | Find | unord<std::string | 11262 | 9.97% | +-----------+--------------------+-------+----------+ libstdc++-v3/ChangeLog: * include/bits/hashtable.h: Inline _M_locate.
2024-12-18libstdc++: Add missing character to __to_wstring_numeric mapJonathan Wakely1-0/+2
The mapping from char to wchar_t needs to handle 'i' and 'I' but those were absent from the table that is used for some non-ASCII encodings. libstdc++-v3/ChangeLog: * include/bits/basic_string.h (__to_wstring_numeric): Add 'i' and 'I' to mapping.
2024-12-18libstdc++: Call regex_traits::transform_primary() only when necessary [PR98723]Luca Bacci1-4/+7
This is both a performance optimization and a partial fix for PR 98723. This commit fixes the issue for bracket expressions that do not depend on the locale's collation facet. Examples: * Character ranges ([a-z]) when std::regex::collate is not set * Character classes ([:alnum:]) * Individual characters ([abc]) Signed-off-by: Luca Bacci <luca.bacci982@gmail.com> libstdc++-v3/ChangeLog: PR libstdc++/98723 * include/bits/regex_compiler.tcc (_BracketMatcher::_M_apply): Only use transform_primary when an equivalence set is used.
2024-12-18Daily bump.GCC Administrator1-0/+13
2024-12-17libstdc++: Fix -Wparentheses warning in Debug Mode macroJonathan Wakely1-1/+1
libstdc++-v3/ChangeLog: * include/debug/safe_local_iterator.h (_GLIBCXX_DEBUG_VERIFY_OPERANDS): Add parentheses to avoid -Wparentheses warning.
2024-12-17libstdc++: Fix std::deque::insert(pos, first, last) undefined behaviour ↵Jonathan Wakely2-0/+29
[PR118035] Inserting an empty range into a std::deque results in undefined calls to either std::copy, std::copy_backward, std::move, or std::move_backward. We call those algos with invalid arguments where the output range is the same as the input range, e.g. std::copy(first, last, first) which violates the preconditions for the algorithms. This fix simply returns early if there's nothing to insert. Most callers already ensure that we don't even call _M_range_insert_aux with an empty range, but some callers don't. Rather than checking for n == 0 in each of the callers, this just does the check once and uses __builtin_expect to treat empty insertions as unlikely. libstdc++-v3/ChangeLog: PR libstdc++/118035 * include/bits/deque.tcc (_M_range_insert_aux): Return immediately if inserting an empty range. * testsuite/23_containers/deque/modifiers/insert/118035.cc: New test.
2024-12-17Daily bump.GCC Administrator1-0/+62
2024-12-16libstdc++: Initialize all members of hashtable local iteratorsJonathan Wakely1-5/+5
Currently the _M_bucket members are left uninitialized for default-initialized local iterators, and then copy construction copies indeterminate values. We should just ensure they're initialized on construction. Setting them to zero makes default-initialization consistent with value-initialization and avoids indeterminate values. For the _Local_iterator_base<..., false> specialization we preserve the existing behaviour of setting _M_bucket_count to -1 in the default constructor, as a sentinel value to indicate there's no hash object present. libstdc++-v3/ChangeLog: * include/bits/hashtable_policy.h (_Local_iterator_base): Use default member-initializers.