Age | Commit message (Collapse) | Author | Files | Lines |
|
As I can't think of how the middle-end would treat
__builtin_start_lifetime_as other than a blackbox and probably would
need to be implemented as such inline asm in RTL, this patch
just implements it using inline asm in the library.
If not anything else, it can serve as fallback before we and/or clang
get some builtin for it.
Right now the inline asms pretend (potential) read from and write to the whole
memory region and make optimizers forget where the return value points to.
If the optimizers don't know where it points to, I think that should be
good enough, but I'm a little bit afraid of possibly future optimizations
trying to optimize
q->c = 1;
q->d = 2;
auto p = std::start_lifetime_as<S>(q);
if (p == reinterpret_cast<decltype (p)>(q))
return p->a + p->b;
that because of the guarding condition or perhaps assertion we could
simply use the q pointer in MEM_REFs with S type and be surprised by TBAA.
Though if it is a must-alias case, then we should be fine as well.
Though guess that would be the same case with a builtin.
2025-09-18 Jakub Jelinek <jakub@redhat.com>
PR c++/106658
* include/bits/version.def: Implement C++23 P2590R2 - Explicit
lifetime management.
(start_lifetime_as): New.
* include/bits/version.h: Regenerate.
* include/std/memory (std::start_lifetime_as,
std::start_lifetime_as_array): New function templates.
* src/c++23/std.cc.in (std::start_lifetime_as,
std::start_lifetime_as_array): Export.
* testsuite/std/memory/start_lifetime_as/start_lifetime_as.cc: New test.
|
|
As in r16-3912-g412a1f78b53709, this fixes some other spots where we
wrongly use a deduced type and non-direct-initialization when trying
to initialize a value type from an iterator's reference type.
PR libstdc++/111861
libstdc++-v3/ChangeLog:
* include/bits/ranges_algo.h (ranges::unique_copy): When
initializing a value type object from *iter, use
direct-initialization and don't use a deduced type.
(ranges::push_heap): Use direct-initialization when initializing
a value type object from ranges::iter_move.
(ranges::max): As in ranges::unique_copy.
* include/bits/ranges_util.h (ranges::min): Likewise.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
|
|
[PR121913]
The r16-3835-g7801236069a95c change to use ranges::iter_move should also
have used iter_value_t<_Iter> to ensure we get an object of the value
type, not a proxy reference.
libstdc++-v3/ChangeLog:
PR libstdc++/121913
* include/bits/ranges_algo.h (__rotate_fn::operator()): Use
auto_value_t<_Iter> instead of deduced type.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
|
|
The _GLIBCXX_MAKE_MOVE_ITERATOR macro is needed for code that needs to
compile as C++98, where it just produces the original iterator. In
std::uninitialized_move and std::uninitialized_move_n we can just call
std::make_move_iterator directly.
libstdc++-v3/ChangeLog:
* include/bits/stl_uninitialized.h (uninitialized_move)
(uninitialized_move_n): Replace _GLIBCXX_MAKE_MOVE_ITERATOR with
std::make_move_iterator.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
|
|
libstdc++-v3/ChangeLog:
PR libstdc++/119820
* include/bits/ranges_algo.h (__shuffle_fn): Use
ranges::distance to get difference type value to add to
iterator.
* include/std/format (__formatter_str::_M_format_range):
Use ranges::next to increment iterator by a size_t value.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
|
|
ranges::shuffle has a two-at-a-time PRNG optimization (copied from
std::shuffle) that considers the PRNG width vs the size of the range.
But in C++20 a random access sentinel isn't always sized so we can't
unconditionally do __last - __first to obtain the size in constant
time.
We could instead use ranges::distance, but that'd take linear time for a
non-sized sentinel which makes the optimization less clear of a win. So
this patch instead makes us only consider this optimization for sized
ranges.
PR libstdc++/121917
libstdc++-v3/ChangeLog:
* include/bits/ranges_algo.h (__shuffle_fn::operator()): Only
consider the two-at-a-time PRNG optimization if the range is
sized.
* testsuite/25_algorithms/shuffle/constrained.cc (test03): New
test.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
|
|
Using std::move(*it) is incorrect for iterators that use proxy refs, we
should use ranges::iter_move(it) instead.
libstdc++-v3/ChangeLog:
PR libstdc++/121913
* include/bits/ranges_algo.h (__rotate_fn::operator()): Use
ranges::iter_move(it) instead of std::move(*it).
* testsuite/25_algorithms/rotate/121913.cc: New test.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
|
|
[PR121890]
Whenever we use operator+ or similar operators on random access
iterators we need to be careful to use the iterator's difference_type
rather than some other integer type. It's not guaranteed that an
expression with an arbitrary integer type, such as `it + 1u`, has the
same effects as `it + iter_difference_t<It>(1)`.
Some of our algorithms need changes to cast values to the correct type,
or to use std::next or ranges::next instead of `it + n`. Several tests
also need fixes where the arithmetic occurs directly in the test.
The __gnu_test::random_access_iterator_wrapper class template is
adjusted to have deleted operators that make programs ill-formed if the
argument to relevant operators is not the difference_type. This will
make it easier to avoid regressing in future.
libstdc++-v3/ChangeLog:
PR libstdc++/121890
* include/bits/ranges_algo.h (ranges::rotate, ranges::shuffle)
(__insertion_sort, __unguarded_partition_pivot, __introselect):
Use ranges::next to advance iterators. Use local variables in
rotate to avoid duplicate expressions.
(ranges::push_heap, ranges::pop_heap, ranges::partial_sort)
(ranges::partial_sort_copy): Use ranges::prev.
(__final_insertion_sort): Use iter_difference_t<Iter>
for operand of operator+ on iterator.
* include/bits/ranges_base.h (ranges::advance): Use iterator's
difference_type for all iterator arithmetic.
* include/bits/stl_algo.h (__search_n_aux, __rotate)
(__insertion_sort, __unguarded_partition_pivot, __introselect)
(__final_insertion_sort, for_each_n, random_shuffle): Likewise.
Use local variables in __rotate to avoid duplicate expressions.
* include/bits/stl_algobase.h (__fill_n_a, __lc_rai::__newlast1):
Likewise.
* include/bits/stl_heap.h (push_heap): Likewise.
(__is_heap_until): Add static_assert.
(__is_heap): Convert distance to difference_type.
* include/std/functional (boyer_moore_searcher::operator()): Use
iterator's difference_type for iterator arithmetic.
* testsuite/util/testsuite_iterators.h
(random_access_iterator_wrapper): Add deleted overloads of
operators that should be called with difference_type.
* testsuite/24_iterators/range_operations/advance.cc: Use
ranges::next.
* testsuite/25_algorithms/heap/constrained.cc: Use ranges::next
and ranges::prev.
* testsuite/25_algorithms/nth_element/58800.cc: Use std::next.
* testsuite/25_algorithms/nth_element/constrained.cc: Use
ptrdiff_t for loop variable.
* testsuite/25_algorithms/nth_element/random_test.cc: Use
iterator's difference_type instead of int.
* testsuite/25_algorithms/partial_sort/check_compare_by_value.cc:
Use std::next.
* testsuite/25_algorithms/partial_sort/constrained.cc: Use
ptrdiff_t for loop variable.
* testsuite/25_algorithms/partial_sort/random_test.cc: Use
iterator's difference_type instead of int.
* testsuite/25_algorithms/partial_sort_copy/constrained.cc:
Use ptrdiff_t for loop variable.
* testsuite/25_algorithms/partial_sort_copy/random_test.cc:
Use iterator's difference_type instead of int.
* testsuite/std/ranges/adaptors/drop.cc: Use ranges::next.
* testsuite/25_algorithms/fill_n/diff_type.cc: New test.
* testsuite/25_algorithms/lexicographical_compare/diff_type.cc:
New test.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
This adds checks when incrementing the shared count and weak count and
will trap if they would be be incremented past its maximum. The maximum
value is the value at which incrementing it produces an invalid
use_count(). So that is either the maximum positive value of
_Atomic_word, or for targets where we now allow the counters to wrap
around to negative values, the "maximum" value is -1, because that is
the value at which one more increment overflows the usable range and
resets the counter to zero.
For the weak count the maximum is always -1 as we always allow that
count to use nagative values, so we only tap if it wraps all the way
back to zero.
libstdc++-v3/ChangeLog:
PR libstdc++/71945
* include/bits/shared_ptr_base.h (_Sp_counted_base::_S_chk):
Trap if a reference count cannot be incremented any higher.
(_Sp_counted_base::_M_add_ref_copy): Use _S_chk.
(_Sp_counted_base::_M_add_weak_ref): Likewise.
(_Sp_counted_base<_S_mutex>::_M_add_ref_lock_nothrow): Likewise.
(_Sp_counted_base<_S_atomic>::_M_add_ref_lock_nothrow): Likewise.
(_Sp_counted_base<_S_single>::_M_add_ref_copy): Use _S_chk.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
This change doubles the effective range of the std::shared_ptr and
std::weak_ptr reference counts for most 64-bit targets.
The counter type, _Atomic_word, is usually a signed 32-bit int (except
on Solaris v9 where it is a signed 64-bit long). The return type of
std::shared_ptr::use_count() is long. For targets where long is wider
than _Atomic_word (most 64-bit targets) we can treat the _Atomic_word
reference counts as unsigned and allow them to wrap around from their
most positive value to their most negative value without any problems.
The logic that operates on the counts only cares if they are zero or
non-zero, and never performs relational comparisons. The atomic
fetch_add operations on integers are required by the standard to behave
like unsigned types, so that overflow is well-defined:
"the result is as if the object value and parameters were converted to
their corresponding unsigned types, the computation performed on those
types, and the result converted back to the signed type."
So if we allow the counts to wrap around to negative values, all we need
to do is cast the value to make_unsigned_t<_Atomic_word> before
returning it as long from the use_count() function.
In practice even exceeding INT_MAX is extremely unlikely, as it would
require billions of shared_ptr or weak_ptr objects to have been
constructed and never destroyed. However, if that happens we now have
double the range before the count returns to zero and causes problems.
Some of the member functions for the _Sp_counted_base<_S_single>
specialization are adusted to use the __atomic_add_single and
__exchange_and_add_single helpers instead of plain ++ and -- operations.
This is done because those helpers use unsigned arithmetic, where the
plain increments and decrements would have undefined behaviour on
overflow.
libstdc++-v3/ChangeLog:
PR libstdc++/71945
* include/bits/shared_ptr_base.h
(_Sp_counted_base::_M_get_use_count): Cast _M_use_count to
unsigned before returning as long.
(_Sp_counted_base<_S_single>::_M_add_ref_copy): Use atomic
helper function to adjust ref count using unsigned arithmetic.
(_Sp_counted_base<_S_single>::_M_weak_release): Likewise.
(_Sp_counted_base<_S_single>::_M_get_use_count): Cast
_M_use_count to unsigned before returning as long.
(_Sp_counted_base<_S_single>::_M_add_ref_lock_nothrow): Use
_M_add_ref_copy to do increment using unsigned arithmetic.
(_Sp_counted_base<_S_single>::_M_release): Use atomic helper and
_M_weak_release to do decrements using unsigned arithmetic.
(_Sp_counted_base<_S_mutex>::_M_release): Add comment.
(_Sp_counted_base<_S_single>::_M_weak_add_ref): Remove
specialization.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
These _S_noexcept() functions are only used in noexcept-specifiers and
never need to be called at runtime. They can be immediate functions,
i.e. consteval.
libstdc++-v3/ChangeLog:
* include/bits/iterator_concepts.h (_IterMove::_S_noexcept)
(_IterSwap::_S_noexcept): Change constexpr to consteval.
* include/bits/ranges_base.h (_Begin::_S_noexcept)
(_End::_S_noexcept, _RBegin::_S_noexcept, _REnd::_S_noexcept)
(_Size::_S_noexcept, _Empty::_S_noexcept, _Data::_S_noexcept):
Likewise.
* include/std/concepts (_Swap::_S_noexcept): Likewise.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
Most of the basis operations for ranges such as ranges::begin and
ranges::next are trivial one-line function bodies, so can be made
always_inline to reduce the abstraction penalty for -O0 code.
Now that we no longer need to support the -fconcepts-ts grammar, we can
also move some [[nodiscard]] attributes to the more natural position
before the function declaration, instead of between the declarator-id
and the function parameters, e.g. we can use:
template<typename T> requires C<T> [[nodiscard]] auto operator()(T&&)
instead of:
template<typename T> requires C<T> auto operator() [[nodiscard]] (T&&)
The latter form was necessary because -fconcepts-ts used a different
grammar for the requires-clause, parsing 'C<T>[[x]]' as a subscripting
operator with an ill-formed argument '[x]'. In the C++20 grammar you
would need to use parentheses to use a subscript in a constraint, so
without parentheses it's parsed as an attribute.
libstdc++-v3/ChangeLog:
* include/bits/ranges_base.h (__detail::__to_unsigned_like)
(__access::__possible_const_range, __access::__as_const)
(__distance_fn::operator(), __next_fn::operator())
(__prev_fn::operator()): Add always_inline attribute.
(_Begin::operator(), _End::operator(), _RBegin::operator())
(_REnd::operator(), _Size::operator(), _SSize::operator())
(_Empty::operator(), _Data::operator(), _SSize::operator()):
Likewise. Move nodiscard attribute to start of declaration.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
Converting a weak_ptr<Derived> to a weak_ptr<Base> requires calling
lock() on the source object in the general case.
Although the source weak_ptr<Derived> does contain a raw pointer to
Derived, we can't just get it and (up)cast it to Base, as that will
dereference the pointer in case Base is a virtual base class of Derived.
We don't know if the managed object is still alive, and therefore if
this operation is safe to do; we therefore temporarily lock() the source
weak_ptr, do the cast using the resulting shared_ptr, and then discard
this shared_ptr. Simply checking the strong counter isn't sufficient,
because if multiple threads are involved then we'd have a race / TOCTOU
problem; the object may get destroyed after we check the strong counter
and before we cast the pointer.
However lock() is not necessary if we know that Base is *not* a virtual
base class of Derived; in this case we can avoid the relatively
expensive call to lock() and just cast the pointer. This commit uses
the newly added builtin to detect this case and optimize std::weak_ptr's
converting constructors and assignment operations.
Apart from non-virtual bases, there's also another couple of interesting
cases where we can also avoid locking. Specifically:
1) converting a weak_ptr<T[N]> to a weak_ptr<T cv[]>;
2) converting a weak_ptr<T*> to a weak_ptr<T const * const> or similar.
Since this logic is going to be used by multiple places, I've
centralized it in a new static helper.
libstdc++-v3/ChangeLog:
* include/bits/shared_ptr_base.h (__weak_ptr): Avoid calling
lock() when converting or assigning a weak_ptr<Derived> to
a weak_ptr<Base> in case Base is not a virtual base of Derived.
This logic is centralized in _S_safe_upcast, called by the
various converting constructors/assignment operators.
(_S_safe_upcast): New helper function.
* testsuite/20_util/weak_ptr/cons/virtual_bases.cc: New test.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
|
|
libstdc++-v3/ChangeLog:
* include/bits/unique_ptr.h: Remove blank line.
|
|
This is a partial implementation of P2781R9. It adds std::cw and
std::constant_wrapper, but doesn't modify __integral_constant_like for
span/mdspan.
libstdc++-v3/ChangeLog:
* include/bits/version.def (constant_wrapper): Add.
* include/bits/version.h: Regenerate.
* include/std/type_traits (_CwFixedValue): New class.
(_IndexSequence): New struct.
(_BuildIndexSequence): New struct.
(_ConstExprParam): New concept.
(_CwOperators): New struct.
(constant_wrapper): New struct.
(cw): New global constant.
* src/c++23/std.cc.in (constant_wrapper): Add.
(cw): Add.
* testsuite/20_util/constant_wrapper/adl.cc: New test.
* testsuite/20_util/constant_wrapper/ex.cc: New test.
* testsuite/20_util/constant_wrapper/generic.cc: New test.
* testsuite/20_util/constant_wrapper/instantiate.cc: New test.
* testsuite/20_util/constant_wrapper/op_comma_neg.cc: New test.
* testsuite/20_util/constant_wrapper/version.cc: New test.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Co-authored-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
This patch refactors ranges::_Partial to be implemented using _Bind_back_t.
This allows it to benefit from the changes in r16-3398-g250dd5b5604fbc,
specifically making the closure trivially copyable. Since _Bind_back_t
already provides an optimized implementation for a single bound argument,
specializations for _Partial with a single argument are now removed.
We still preserve a specialization of _Partial for trivially copy-constructible
arguments that define only a const overload of operator(). To avoid
re-checking invocability constraints, this specialization calls the now-public,
unconstrained _Binder::_S_call static method instead of the constrained
_Binder::operator().
The primary specialization of _Partial retains its operator(), which
uses a simpler __adaptor_invocable constraint that does not consider
member pointers, as they are not relevant here. This implementation also
calls _Binder::_S_call to avoid re-performing overload resolution and
invocability checks for _Binder::operator().
Finally, the _M_binder member (_Bind_back_t) is now marked
[[no_unique_address]]. This is beneficial as ranges::_Partial is used with
ranges::to, which commonly has zero or empty bound arguments (e.g., stateless
allocators, comparators, or hash functions).
libstdc++-v3/ChangeLog:
* include/bits/binders.h (_Binder::_S_call): Make public.
* include/std/ranges (ranges::_Partial<_Adaptor, _Args...>):
Replace tuple<_Args...> with _Bind_back_t<_Adaptor, _Args...>.
(ranges::_Partial<_Adaptor, _Arg>): Remove.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
bits/binders.h is already mapped in libstdc++-v3/doc/doxygen/stdheader.cc.
libstdc++-v3/ChangeLog:
* include/Makefile.am: Add bits/binders.h
* include/Makefile.in: Add bits/binders.h
* include/std/functional (std::_Indexed_bound_arg, std::_Binder)
(std::__make_bound_args, std::_Bind_front_t, std::_Bind_back_t):
Moved to bits/binders.h file, that is now included.
* include/bits/binders.h: New file.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
Make the std::get<T> overloads for rvalues use std::forward<T>(p.first)
not std::move(p.first), so that lvalue reference members are not
incorrectly converted to rvalues.
It might appear that std::move(p).first would also work, but the
language rules say that for std::pair<T&&, U> that would produce T&
rather than the expected T&& (see the discussion in P2445R1 §8.2).
Additional tests are added to verify all combinations of reference
members, value categories, and const-qualification.
libstdc++-v3/ChangeLog:
PR libstdc++/121745
* include/bits/stl_pair.h (get): Use forward instead of move in
std::get<T> overloads for rvalue pairs.
* testsuite/20_util/pair/astuple/get_by_type.cc: Check all value
categories and cv-qualification.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
For the pair(T1, T2) explicit deduction type to decay its arguments as
intended, we need the pair(const T1&, const T2&) constructor to not be
used for CTAD. Otherwise we try to instantiate pair<T1, T2> without
decaying, which is ill-formed for function lvalues.
Use std::type_identity_t<T1> to make the constructor unusable for an
implicit deduction guide.
libstdc++-v3/ChangeLog:
PR libstdc++/110853
* include/bits/stl_pair.h [C++20] (pair(const T1&, const T2&)):
Use std::type_identity_t<T1> for first parameter.
* testsuite/20_util/pair/cons/110853.cc: New test.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
The r16-3416-g806de30f51c8b9 change to use __cpp_lib_chrono in
preprocessor conditions broke support for <chrono> for freestanding and
the COW std::string ABI. That happened because __cpp_lib_chrono is only
defined to the C++20 value for hosted and for the new ABI, because the
full set of C++20 features are not defined for freestanding and tzdb is
not defined for the old ABI.
This introduces a new internal feature test macro that corresponds to
the features that are always supported (e.g. chrono::local_time,
chrono::year, chrono::weekday).
libstdc++-v3/ChangeLog:
* include/bits/version.def (chrono_cxx20): Define.
* include/bits/version.h: Regenerate.
* include/std/chrono: Check __glibcxx_chrono_cxx20 instead of
__cpp_lib_chrono for C++20 features that don't require the new
std::string ABI and/or can be used for freestanding.
* src/c++20/clock.cc: Adjust preprocessor condition.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
As preparation for implementing std::constant_wrapper that's part of the
C++26 version of the <type_traits> header, the two classes _Index_tuple
and _Build_index_tuple are moved to <type_traits>. These two helpers are
needed by std::constant_wrapper to initialize the elements of one C
array with another.
Since, <bits/utility.h> already includes <type_traits> this solution
avoids creating a very small header file for just these two internal
classes. This approach doesn't move std::index_sequence and related code
to <type_traits> and therefore doesn't change which headers provide
user-facing features.
libstdc++-v3/ChangeLog:
* include/bits/utility.h (_Index_tuple): Move to <type_traits>.
(_Build_index_tuple): Ditto.
* include/std/type_traits (_Index_tuple): Ditto.
(_Build_index_tuple): Ditto.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|
|
This implements P2546R5 (Debugging Support), including the P2810R4
(is_debugger_present is_replaceable) changes, allowing
std::is_debugger_present to be replaced by the program.
It would be good to provide a macOS definition of is_debugger_present as
per https://developer.apple.com/library/archive/qa/qa1361/_index.html
but that isn't included in this change.
The src/c++26/debugging.cc file defines a global volatile int which can
be set by debuggers to indicate when they are attached and detached from
a running process. This allows std::is_debugger_present() to give a
reliable answer, and additionally allows a debugger to choose how
std::breakpoint() should behave. Setting the global to a positive value
will cause std::breakpoint() to use that value as an argument to
std::raise, so debuggers that prefer SIGABRT for breakpoints can select
that. By default std::breakpoint() will use a platform-specific action
such as the INT3 instruction on x86, or GCC's __builtin_trap().
On Linux the std::is_debugger_present() function checks whether the
process is being traced by a process named "gdb", "gdbserver" or
"lldb-server", to try to avoid interpreting other tracing processes
(such as strace) as a debugger. There have been comments suggesting this
isn't desirable and that std::is_debugger_present() should just return
true for any tracing process (which is the case for non-Linux targets
that support the ptrace system call).
libstdc++-v3/ChangeLog:
PR libstdc++/119670
* acinclude.m4 (GLIBCXX_CHECK_DEBUGGING): Check for facilities
needed by <debugging>.
* config.h.in: Regenerate.
* configure: Regenerate.
* configure.ac: Use GLIBCXX_CHECK_DEBUGGING.
* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/bits/version.def (debugging): Add.
* include/bits/version.h: Regenerate.
* include/precompiled/stdc++.h: Add new header.
* src/c++26/Makefile.am: Add new file.
* src/c++26/Makefile.in: Regenerate.
* include/std/debugging: New file.
* src/c++26/debugging.cc: New file.
* testsuite/19_diagnostics/debugging/breakpoint.cc: New test.
* testsuite/19_diagnostics/debugging/breakpoint_if_debugging.cc:
New test.
* testsuite/19_diagnostics/debugging/is_debugger_present.cc: New
test.
* testsuite/19_diagnostics/debugging/is_debugger_present-2.cc:
New test.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
Previously, an empty functor (EmptyIdFunc) stored inside a
std::move_only_function being first member of a Composite class could have the
same address as the base of the EmptyIdFunc type (see included test cases),
resulting in two objects of the same type at the same address.
This commit addresses the issue by moving the internal buffer from the start
of the wrapper object to a position after the manager function pointer. This
minimizes aliasing with the stored buffer but doesn't completely eliminate it,
especially when multiple empty base objects are involved (PR121180).
To facilitate this member reordering, the private section of _Mo_base was
eliminated, and the corresponding _M_manager and _M_destroy members were made
protected. They remain inaccessible to users, as user-facing wrappers derive
from _Mo_base privately.
libstdc++-v3/ChangeLog:
* include/bits/funcwrap.h (__polyfunc::_Mo_base): Reorder _M_manage
and _M_storage members. Make _M_destroy protected and remove friend
declaration.
* testsuite/20_util/copyable_function/call.cc: Add test for aliasing
base class.
* testsuite/20_util/move_only_function/call.cc: Likewise.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
This patch introduces a new function, _M_fill_append, which is invoked when
copies of the same value are appended to the end of a vector. Unlike
_M_fill_insert(end(), n, v), _M_fill_append never permute elements in place,
so it does not require:
* vector element type to be assignable;
* a copy of the inserted value, in the case where it points to an
element of the vector.
vector::resize(n, v) now uses _M_fill_append, fixing the non-conformance where
element types were required to be assignable.
In addition, _M_fill_insert(end(), n, v) now delegates to _M_fill_append, which
eliminates an unnecessary copy of v when the existing capacity is used.
PR libstdc++/90192
libstdc++-v3/ChangeLog:
* include/bits/stl_vector.h (vector<T>::_M_fill_append): Declare.
(vector<T>::fill): Use _M_fill_append instead of _M_fill_insert.
* include/bits/vector.tcc (vector<T>::_M_fill_append): Define
(vector<T>::_M_fill_insert): Delegate to _M_fill_append when
elements are appended.
* testsuite/23_containers/vector/modifiers/moveable.cc: Updated
copycount for inserting at the end (appending).
* testsuite/23_containers/vector/modifiers/resize.cc: New test.
* testsuite/backward/hash_set/check_construct_destroy.cc: Updated
copycount, the hash_set constructor uses insert to fill buckets
with nullptrs.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
This patch refactors the implementation of bind_front and bind_back to avoid
using std::tuple for argument storage. Instead, bound arguments are now:
* stored directly if there is only one,
* within a dedicated _Bound_arg_storage otherwise.
_Bound_arg_storage is less expensive to instantiate and access than std::tuple.
It can also be trivially copyable, as it doesn't require a non-trivial assignment
operator for reference types. Storing a single argument directly provides similar
benefits compared to both one element tuple or _Bound_arg_storage.
_Bound_arg_storage holds each argument in an _Indexed_bound_arg base object.
The base class is parameterized by both type and index to allow storing
multiple arguments of the same type. Invocations are handled by _S_apply_front
amd _S_apply_back static functions, which simulate explicit object parameters.
To facilitate this, the __like_t alias template is now unconditionally available
since C++11 in bits/move.h.
libstdc++-v3/ChangeLog:
* include/bits/move.h (std::__like_impl, std::__like_t): Make
available in c++11.
* include/std/functional (std::_Indexed_bound_arg)
(std::_Bound_arg_storage, std::__make_bound_args): Define.
(std::_Bind_front, std::_Bind_back): Use _Bound_arg_storage.
* testsuite/20_util/function_objects/bind_back/1.cc: Expand
test to cover cases of 0, 1, many bound args.
* testsuite/20_util/function_objects/bind_back/111327.cc: Likewise.
* testsuite/20_util/function_objects/bind_front/1.cc: Likewise.
* testsuite/20_util/function_objects/bind_front/111327.cc: Likewise.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
This commit completes the implementation of P2897R7 by implementing and
testing the template class aligned_accessor.
PR libstdc++/120994
libstdc++-v3/ChangeLog:
* include/bits/version.def (aligned_accessor): Add.
* include/bits/version.h: Regenerate.
* include/std/mdspan (aligned_accessor): New class.
* src/c++23/std.cc.in (aligned_accessor): Add.
* testsuite/23_containers/mdspan/accessors/generic.cc: Add tests
for aligned_accessor.
* testsuite/23_containers/mdspan/accessors/aligned_neg.cc: New test.
* testsuite/23_containers/mdspan/version.cc: Add test for
__cpp_lib_aligned_accessor.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|
|
This commit implements and tests the function is_sufficiently_aligned
from P2897R7.
PR libstdc++/120994
libstdc++-v3/ChangeLog:
* include/bits/align.h (is_sufficiently_aligned): New function.
* include/bits/version.def (is_sufficiently_aligned): Add.
* include/bits/version.h: Regenerate.
* include/std/memory: Add __glibcxx_want_is_sufficiently_aligned.
* src/c++23/std.cc.in (is_sufficiently_aligned): Add.
* testsuite/20_util/headers/memory/version.cc: Add test for
__cpp_lib_is_sufficiently_aligned.
* testsuite/20_util/is_sufficiently_aligned/1.cc: New test.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|
|
This commit implements the C++26 feature std::dims described in P2389R2.
It sets the feature testing macro to 202406 and adds tests.
Also fixes the test mdspan/version.cc
libstdc++-v3/ChangeLog:
* include/bits/version.def (mdspan): Set value for C++26.
* include/bits/version.h: Regenerate.
* include/std/mdspan (dims): Add.
* src/c++23/std.cc.in (dims): Add.
* testsuite/23_containers/mdspan/extents/misc.cc: Add tests.
* testsuite/23_containers/mdspan/version.cc: Update test.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|
|
This patch adds the [[nodiscard]] attribute to the operator() of ranges
algorithm function objects if their std counterpart has it.
Furthermore, we [[nodiscard]] the operator() of the following ranges
algorithms that lack a std counterpart:
* find_last, find_last_if, find_last_if_not (to match other find
algorithms)
* contains, contains_subrange (to match find/any_of and search)
Finally, [[nodiscard]] is added to std::min and std::max overloads
that accept std::initializer_list. This appears to be an oversight,
as std::minmax is already marked, and other min overloads are as well.
The same applies to corresponding operator() overloads of ranges::min and
ranges::max.
PR libstdc++/121476
libstdc++-v3/ChangeLog:
* include/bits/ranges_algo.h (__all_of_fn::operator()):
(__any_of_fn::operator(), __none_of_fn::operator())
(__find_first_of_fn::operator(), __count_fn::operator())
(__find_end_fn::operator(), __remove_if_fn::operator())
(__remove_fn::operator(), __unique_fn::operator())
(__is_sorted_until_fn::operator(), __is_sorted_fn::operator())
(__lower_bound_fn::operator(), __upper_bound_fn::operator())
(__equal_range_fn::operator(), __binary_search_fn::operator())
(__is_partitioned_fn::operator(), __partition_point_fn::operator())
(__minmax_fn::operator(), __min_element_fn::operator())
(__includes_fn::operator(), __max_fn::operator())
(__lexicographical_compare_fn::operator(), __clamp__fn::operator())
(__find_last_fn::operator(), __find_last_if_fn::operator())
(__find_last_if_not_fn::operator()): Add [[nodiscard]] attribute.
* include/bits/ranges_algobase.h (__equal_fn::operator()):
Add [[nodiscard]] attribute.
* include/bits/ranges_util.h (__find_fn::operator())
(__find_if_fn::operator(), __find_if_not_fn::operator())
(__mismatch_fn::operator(), __search_fn::operator())
(__min_fn::operator(), __adjacent_find_fn::operator()):
Add [[nodiscard]] attribute.
* include/bits/stl_algo.h (std::min(initializer_list<T>))
(std::min(initializer_list<T>, _Compare))
(std::max(initializer_list<T>))
(std::mmax(initializer_list<T>, _Compare)): Add _GLIBCXX_NODISCARD.
* testsuite/25_algorithms/min/constrained.cc: Silence nodiscard
warning.
* testsuite/25_algorithms/max/constrained.cc: Likewise.
* testsuite/25_algorithms/minmax/constrained.cc: Likewise.
* testsuite/25_algorithms/minmax_element/constrained.cc: Likewise.
|
|
[PR121313]
For __n == 0, the elements were self move-assigned by
std::move_backward(__ins, __old_finish - __n, __old_finish).
PR libstdc++/121313
libstdc++-v3/ChangeLog:
* include/bits/vector.tcc (vector::insert_range): Add check for
empty size.
* testsuite/23_containers/vector/modifiers/insert/insert_range.cc:
New tests.
|
|
Forr rvalues the _Self parameter deduces a non-reference type. Consequently,
((_Self)__self) moved the object to a temporary, which then destroyed on
function exit.
This patch fixes this by using a C-style cast __self to (const indirect&).
This not only resolves the above issue but also correctly handles types that
are derived (publicly and privately) from indirect. Allocator requirements in
[allocator.requirements.general] p22 guarantee that dereferencing const _M_objp
works with equivalent semantics to dereferencing _M_objp.
PR libstdc++/121128
libstdc++-v3/ChangeLog:
* include/bits/indirect.h (indirect::operator*):
Cast __self to approparietly qualified indirect.
* testsuite/std/memory/indirect/access.cc: New test.
* testsuite/std/memory/polymorphic/access.cc: New test.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
When the C++98 std::distance and std::advance functions (and C++11
std::next and std::prev) are used with C++20 iterators there can be
unexpected results, ranging from compilation failure to decreased
performance to undefined behaviour.
An iterator which satisfies std::input_iterator but does not meet the
Cpp17InputIterator requirements might have std::output_iterator_tag for
its std::iterator_traits<I>::iterator_category, which means it currently
cannot be used with std::advance at all. However, the implementation of
std::advance for a Cpp17InputIterator doesn't do anything that isn't
valid for iterator types satsifying C++20 std::input_iterator.
Similarly, a type satisfying C++20 std::bidirectional_iterator might be
usable with std::prev, if it weren't for the fact that its C++17
iterator_category is std::input_iterator_tag.
Finally, a type satisfying C++20 std::random_access_iterator might use a
slower implementation for std::distance or std::advance if its C++17
iterator_category is not std::random_access_iterator_tag.
This commit adds a __promotable_iterator concept to detect C++20
iterators which explicitly define an iterator_concept member, and which
either have no iterator_category, or their iterator_category is weaker
than their iterator_concept. This is used by std::distance and
std::advance to detect iterators which should dispatch based on their
iterator_concept instead of their iterator_category. This means that
those functions just work and do the right thing for C++20 iterators
which would otherwise fail to compile or have suboptimal performance.
This is related to LWG 3197, which considers making it undefined to use
std::prev with types which do not meet the Cpp17BidirectionalIterator
requirements. I think making it work, as in this commit, is a better
solution than banning it (or rejecting it at compile-time as libc++
does).
PR libstdc++/102181
libstdc++-v3/ChangeLog:
* include/bits/stl_iterator_base_funcs.h (distance, advance):
Check C++20 iterator concepts and handle appropriately.
(__detail::__iter_category_converts_to_concept): New concept.
(__detail::__promotable_iterator): New concept.
* testsuite/24_iterators/operations/cxx20_iterators.cc: New
test.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
The unordered_map header incorrectly refers to a non-existent template parameter
_Value in default template argument descriptions. They should refer to _Key instead.
This patch fixes these descriptions to match the actual template parameters.
libstdc++-v3/ChangeLog:
* include/bits/unordered_map.h: Rectify referencing of
non-existent type.
|
|
Currently this new concept will get defined for -std=c++17 -fconcepts
but as it uses std::input_iterator, which is new in C++20, that won't
work. Guard it with __cpp_lib_concepts as well as __cpp_concepts.
libstdc++-v3/ChangeLog:
* include/bits/stl_iterator_base_types.h (__any_input_iterator):
Only define when __cpp_lib_concepts is defined.
|
|
Previously for localized output, if _M_debug option was set, the _M_check_ok
completed succesfully and _M_locale_fmt was called for months/weekdays that
are !ok().
This patch lifts debug checks from each conversion function into _M_check_ok,
that in case of !ok() values return a string_view containing the kind of
calendar data, to be included after "is not a valid" string. The localized
output (_M_locale_fmt) is not used if string is non-empty. Emitting of this
message is now handled in _M_format_to, further reducing each specifier
function.
To handle weekday (%a,%A) and month (%b,%B), _M_check_ok now accepts a
mutable reference to conversion specifier, and updates it to corresponding
numeric value (%w, %m). Extra care needs to be taken to handle a month(0)
that needs to be printed as single digit in debug format.
Finally, the _M_time_point is replaced with _M_needs_ok_check member, that
indicates if input contains any user-suplied values that are checked for
being ok() and these values are referenced in chrono-specs.
PR libstdc++/121154
libstdc++-v3/ChangeLog:
* include/bits/chrono_io.h (_ChronoSpec::_M_time_point): Remove.
(_ChronoSpec::_M_needs_ok_check): Define
(__formatter_chrono::_M_parse): Set _M_needs_ok_check.
(__formatter_chrono::_M_check_ok): Check values also for debug mode,
and return __string_view.
(__formatter_chrono::_M_format_to): Handle results of _M_check_ok.
(__formatter_chrono::_M_wi, __formatter_chrono::_M_a_A)
(__formatter_chrono::_M_b_B, __formatter_chrono::_M_C_y_Y)
(__formatter_chrono::_M_d_e, __formatter_chrono::_M_F):
Removed handling of _M_debug.
(__formatter_chrono::__M_m): Print zero unpadded in _M_debug mode.
(__formatter_duration::_S_spec_for): Remove _M_time_point refernce.
(__formatter_duration::_M_parse): Override _M_needs_ok_check.
* testsuite/std/time/month/io.cc: Test for localized !ok() values.
* testsuite/std/time/weekday/io.cc: Test for localized !ok() values.
|
|
This implements the missing functions in _Utf_iterator to support
reverse iteration. All existing tests pass when the view is reversed, so
that the same code units are seen when iterating forwards or backwards.
libstdc++-v3/ChangeLog:
* include/bits/unicode.h (_Utf_iterator::operator--): Reorder
conditions and update position after reading a code unit.
(_Utf_iterator::_M_read_reverse): Define.
(_Utf_iterator::_M_read_utf8): Return extracted code point.
(_Utf_iterator::_M_read_reverse_utf8): Define.
(_Utf_iterator::_M_read_reverse_utf16): Define.
(_Utf_iterator::_M_read_reverse_utf32): Define.
* testsuite/ext/unicode/view.cc: Add checks for reversed views
and reverse iteration.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
This reorders the data members of _Utf_iterator to avoid padding bytes
between members due to alignment requirements. For x86_64 the previous
layout had padding after _M_buf and after _M_to_increment for the common
case where the iterators and sentinel types are pointers, so the size
shrinks from 40 bytes to 32 bytes. (For i686 there's no change, it's
still 20 bytes).
We could compress the three uint8_t members into one byte by using
bit-fields:
uint8_t _M_buf_index : 2; // [0,3]
uint8_t _M_buf_last : 3; // [0,4]
uint8_t _M_to_increment : 3; // [0,4]
But there doesn't seem to be any point, because it will just be slower
to access them and there will be tail padding so the size isn't any
smaller. We could also reduce _M_buf_last and _M_to_increment to 2 bits
because the 0 value is only used for a default constructed iterator, and
we don't actually care about the values in that case. Again, this
doesn't seem worth doing.
libstdc++-v3/ChangeLog:
* include/bits/unicode.h (_Utf_iterator): Reorder data members
to be more compact.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
Implement std::inplace_vector as specified in P0843R14, without follow
up papers, in particular P3074R7 (trivial unions). In consequence
inplace_vector<T, N> can be used inside constant evaluations only
if T is trivial or N is equal to zero.
We provide a separate specialization for inplace_vector<T, 0> to meet
the requirements of N5008 [inplace.vector.overview] p5. In particular
objects of such types needs to be empty.
To allow constexpr variable of inplace_vector v, where v.size() < v.capacity(),
we need to guaranteed that all elements of the storage array are initialized,
even ones in range [v.data() + v.size(), v.data() + v.capacity()). This is
perfoirmed by _M_init function, that is called by each constructor. By storing
the array in anonymous union, we can perform this initialization in constant
evaluation, avoiding the impact on runtime path.
The size() function conveys the information that _M_size <= _Nm to compiler,
by calling __builtin_unreachable(). In particular this allows us to eliminate
FP warnings by using _Nm - size() instead of _Nm - _M_size, when computing
available elements.
The included test cover almost all code paths at runtime, however some
compile time evaluation test are not yet implemented:
* operations on range, they depend on making testsuite_iterators constexpr
* negative test for invoking operations with preconditions at compile time,
especially for zero size specialization.
PR libstdc++/119137
libstdc++-v3/ChangeLog:
* doc/doxygen/user.cfg.in (INPUT): Add new header.
* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/bits/stl_iterator_base_types.h (__any_input_iterator):
Define.
* include/bits/version.def (inplace_vector): Define.
* include/bits/version.h: Regenerate.
* include/precompiled/stdc++.h: Include new header.
* src/c++23/std.cc.in: Export contents if new header.
* include/std/inplace_vector: New file.
* testsuite/23_containers/inplace_vector/access/capacity.cc: New file.
* testsuite/23_containers/inplace_vector/access/elem.cc: New file.
* testsuite/23_containers/inplace_vector/access/elem_neg.cc: New file.
* testsuite/23_containers/inplace_vector/cons/1.cc: New file.
* testsuite/23_containers/inplace_vector/cons/from_range.cc: New file.
* testsuite/23_containers/inplace_vector/cons/throws.cc: New file.
* testsuite/23_containers/inplace_vector/copy.cc: New file.
* testsuite/23_containers/inplace_vector/erasure.cc: New file.
* testsuite/23_containers/inplace_vector/modifiers/assign.cc: New file.
* testsuite/23_containers/inplace_vector/modifiers/erase.cc: New file.
* testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc:
New file.
* testsuite/23_containers/inplace_vector/modifiers/single_insert.cc:
New file.
* testsuite/23_containers/inplace_vector/move.cc: New file.
* testsuite/23_containers/inplace_vector/relops.cc: New file.
* testsuite/23_containers/inplace_vector/version.cc: New file.
* testsuite/util/testsuite_iterators.h (input_iterator_wrapper::base):
Define.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Co-authored-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
Add comments documenting what it does and how it does it.
Also reorder the if-else in operator++ so that we check whether to
iterate over code units in the local buffer before checking whether to
refill that buffer. That seems the more natural way to structure the
function.
libstdc++-v3/ChangeLog:
* include/bits/unicode.h (__unicode::_Utf_iterator): Add
comments.
(__unicode:_Utf_iterator::operator++()): Check whether to
iterate over the buffer first.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
Do not advertise library support for constexpr exceptions, as our
solution to throwing by __throw_* functions from <bits/functexcept.h>,
caues constant evaluation to fail, as these functions are not constexpr.
PR libstdc++/121114
libstdc++-v3/ChangeLog:
* include/bits/version.def (constexpr_exceptions): Add no_stdname
and changed value.
* include/bits/version.h: Regenerated.
* testsuite/18_support/exception/version.cc: Test that macro is
not exported.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kaminski <tkaminsk@redhat.com>
|
|
This is a minor compile-time optimization for C++20.
libstdc++-v3/ChangeLog:
* include/bits/move.h (swap): Replace enable_if with concepts
when available, and with __enable_if_t alias otherwise.
|
|
The standard specifies some of the effects of ranges::advance in terms
of "Equivalent to:" and it's observable that our current implementation
deviates from the precise specification in the standard. This was
causing some failures in the libc++ testsuite.
For the sized_sentinel_for<I, S> case I optimized our implementation to
avoid redundant calls when we have already checked that there's nothing
to do. We were eliding `advance(i, bound)` when the iterator already
equals the sentinel, and eliding `advance(i, n)` when `n` is zero. In
both cases, removing the seemingly redundant calls is not equivalent to
the spec because `i = std::move(bound)` or `i += 0` operations can be
observed by program-defined iterators. This patch inlines the observable
side effects of advance(i, bound) or advance(i, 0) without actually
calling those functions.
For the non-sized sentinel case, `if (i == bound || n == 0)` is
different from `if (n == 0 || i == bound)` for the case where n is zero
and a program-defined iterator observes the number of comparisons.
This patch changes it to do `n == 0` first. I don't think this is
required by the standard, as this condition is not "Equivalent to:" any
observable sequence of operations, but testing `n == 0` first is
probably cheaper anyway.
libstdc++-v3/ChangeLog:
* include/bits/ranges_base.h (ranges::advance(i, n, bound)):
Ensure that observable side effects on iterators match what is
specified in the standard.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
The new test is currently marked as XFAIL because PR c++/102284 means
that GCC doesn't notice that the lifetimes have ended.
libstdc++-v3/ChangeLog:
PR libstdc++/121024
* include/bits/ranges_uninitialized.h (ranges::destroy): Do not
optimize away trivial destructors during constant evaluation.
(ranges::destroy_n): Likewise.
* testsuite/20_util/specialized_algorithms/destroy/121024.cc:
New test.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
This is a follow-up to r16-2190-g4faa42ac0dee2c which ensures that
std::hash is always enabled for signed and unsigned __int128. The
standard requires std::hash to be enabled for all arithmetic types.
libstdc++-v3/ChangeLog:
PR libstdc++/96710
* include/bits/functional_hash.h (hash<__int128>): Define for
strict modes.
(hash<unsigned __int128>): Likewise.
* testsuite/20_util/hash/int128.cc: New test.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
With changes r16-2063-g8ad5968a8dcb47 the _M_a_A, _M_b_B and _M_p functions
are called only if the locale is equal to the locale::classic(), for which
the behavior is know. This patch changes they implementation, so instead of
reffering to __timepunct facet members, they use hardcoded list of English
weekday, months names. Only one list is needed, as in case of locale::classic()
abbreviated name corresponds to first tree letters of the full name.
For _M_p, _M_r we use a new _M_fill_ampm helper, that fills provided buffer
with "AM"/"PM" depending on the hours value.
In _M_S we no longer guard querying of numpuct facet, with check that requires
potentially equally expensive construction of locale::classic. We also mark
localized path as unlikely.
The _M_locale method is no longer used in __formatter_chrono, and thus was
moved to __formatter_duration.
PR libstdc++/110739
libstdc++-v3/ChangeLog:
* include/bits/chrono_io.h (__formatter_chrono::_S_weekdays)
(__formatter_chrono::_S_months, __formatter_chrono::_S_fill_ampm):
Define.
(__formatter_chrono::_M_format_to): Do not pass context parameter
to functions listed below.
(__formatter_chrono::_M_a_A, __formatter_chrono::_M_b_B): Implement
using harcoded list of names, and remove format context parameter.
(__formatter_chrono::_M_p, __formatter_chrono::_M_r): Implement
using _S_fill_ampm.
(__formatter_chrono::_M_c): Removed format context parameter.
(__formatter_chrono::_M_subsecs): Call __ctx.locale() directly,
instead of _M_locale and do not compare with locale::classic().
Add [[unlikely]] attributes.
(__formatter_chrono::_M_locale): Move to __formatter_duration.
(__formatter_duration::_M_locale): Moved from __formatter_chrono.
|
|
We pre-emptively implemented part of LWG 2766, which still hasn't been
approved. Add comments to the deleted swap overloads saying why they're
there, because the standard doesn't require them.
libstdc++-v3/ChangeLog:
* include/bits/stl_pair.h (swap): Add comment to deleted
overload.
* include/bits/unique_ptr.h (swap): Likewise.
* include/std/array (swap): Likewise.
* include/std/optional (swap): Likewise.
* include/std/tuple (swap): Likewise.
* include/std/variant (swap): Likewise.
* testsuite/23_containers/array/tuple_interface/get_neg.cc:
Adjust dg-error line numbers.
|
|
Only P3068R6 (Allowing exception throwing in constant-evaluation) is
implemented in the library so far, so the value of the
constexpr_exceptions feature test macro should be 202411L. Once we
support the library changes in P3378R2 (constexpr exception types) then
we can set the value to 202502L again.
libstdc++-v3/ChangeLog:
PR libstdc++/117785
* include/bits/version.def (constexpr_exceptions): Define
correct value.
* include/bits/version.h: Regenerate.
* libsupc++/exception: Check correct value.
* testsuite/18_support/exception/version.cc: New test.
|
|
Similar to the previous commit that made is_integral_v<__int128>
unconditionally true, this makes is_floating_point_v<__float128>
unconditionally true. With the new extended floating-point types in
C++23 (std::float64_t etc.) it seems unhelpful for is_floating_point_v
to be true for them, but not for __float128. Especially as it is true on
some targets, because __float128 is just a typedef for long double.
This change makes is_floating_point_v<__float128> true whenever the type
is defined, giving less surprising and more portable behaviour.
libstdc++-v3/ChangeLog:
* include/bits/cpp_type_traits.h (__is_floating<__float128>):
Do not depend on __STRICT_ANSI__.
* include/bits/stl_algobase.h (__size_to_integer(__float128)):
Likewise.
* include/std/type_traits (__is_floating_point_helper<__float128>):
Likewise.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
|
|
Since LWG 3828 (included in C++23) implementations are allowed to have
extended integer types that are wider than intmax_t. This means we no
longer have to make is_integral_v<__int128> false for strict -std=c++23
mode, removing the confusing inconsistency with -std=gnu++23 (where
is_integral_v<__int128> is true).
This change makes __int128 a true integral type for all modes, treating
LWG 3828 as a DR for previous standards. Most of the change just
involves removing special cases where we wanted to treat __int128 and
unsigned __int128 as integral types even when is_integral_v was false.
There are still some preprocessor conditionals needed, because on some
targets the compiler defines the macro __GLIBCXX_TYPE_INT_N_0 as
__int128 in non-strict modes. Because we define explicit specializations
of templates such as is_integral for all the INT_N types, we already
have a specialization of is_integral<__int128> in non-strict modes, and
so to avoid a redefinition we only must only define
is_integral<__int128> for strict modes.
libstdc++-v3/ChangeLog:
PR libstdc++/96710
* include/bits/cpp_type_traits.h (__is_integer): Define explicit
specializations for __int128.
(__memcpyable_integer): Remove explicit specializations for
__int128.
* include/bits/iterator_concepts.h (incrementable_traits):
Likewise.
(__is_signed_int128, __is_unsigned_int128, __is_int128): Remove.
(__is_integer_like, __is_signed_integer_like): Remove check for
__int128.
* include/bits/max_size_type.h: Remove all uses of __is_int128
in constraints.
* include/bits/ranges_base.h (__to_unsigned_like): Remove
overloads for __int128.
(ranges::ssize): Remove special case for __int128.
* include/bits/stl_algobase.h (__size_to_integer): Define
__int128 overloads for strict modes.
* include/ext/numeric_traits.h (__is_integer_nonstrict): Remove
explicit specializations for __int128.
* include/std/charconv (to_chars): Define overloads for
__int128.
* include/std/format (__format::make_unsigned_t): Remove.
(__format::to_chars): Remove.
* include/std/limits (numeric_limits): Define explicit
specializations for __int128.
* include/std/type_traits (__is_integral_helper): Likewise.
(__make_unsigned, __make_signed): Likewise.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
|
|
The following patch implements the C++26 P3068R5 - constexpr exceptions
paper.
As the IL cxx_eval_constant* functions process already contains the low
level calls like __cxa_{allocate,free}_exception, __cxa_{,re}throw etc.,
the patch just makes 10 extern "C" __cxa_* functions magic builtins which
during constant evaluation pretend to be constexpr even when not declared
so and handle them directly, plus does the same for 3 std namespace
functions - std::uncaught_exceptions, std::current_exception and
std::rethrow_exception and adds one new FE builtin -
__builtin_eh_ptr_adjust_ref which the library can use instead of the
_M_addref and _M_release out of line methods (this one instead of
recognizing _M_* as magic too because those are clearly specific to
libstdc++ and e.g. libc++ could use something else).
The patch uses magic VAR_DECLs with heap_{uninit_,,deleted_}identifier
DECL_NAME like for operator new/delete for objects allocated with
__cxa_allocate_exception, just sets their DECL_LANG_SPECIFIC so that
we can track their reference count as well (with std::exception_ptr
the same exception object can be referenced multiple times and we want
to destruct and free only when it reaches zero refcount).
For uncaught exceptions being propagated, the patch uses new kind of
*jump_target, which is that magic VAR_DECL described above.
The largest change in the patch is making jump_target argument non-optional
in cxa_eval_constant_exception and all functions it calls that need it.
This is because exceptions can be thrown from pretty much everywhere, e.g.
binary expression can throw in either operand. And the patch also adds
if (*jump_target) return NULL_TREE; or similar in many spots, so that we
don't crash because cxx_eval_constant_expression returned NULL_TREE
somewhere before actually trying to use it and so that we don't uselessly
dive into other operands etc.
Note, with statement expressions actually this was something we just didn't
handle correctly before, one can validly have:
a = ({ if (x) return 42; 12; }) + b;
or in the other operand, or break/continue instead of return if it is
somewhere in a loop/switch; and it isn't ok to branch from one operand to
another one through some kind of goto.
On the potential_constant_expression_1 side, important change was to
set *jump_target conservatively on calls that could throw for C++26 (the
patch uses magic void_node for potential_constant_expression* instead of
VAR_DECL, so that we don't have to create new VAR_DECLs there uselessly).
Without that change, several methods in libstdc++ wouldn't work correctly.
I'm not sure what exactly potential_constant_expression_1 maps to in the
C++26 standard wording now and whether doing that is ok, because basically
after the first call to non-noexcept function it stops checking stuff.
And, in some spots where I know potential_constant_expression_1 didn't
check some subexpressions (e.g. the EH only cleanups or TRY_BLOCK handlers)
I've added *potential_constant_expression* calls during cxx_eval_constant*,
not sure if I need to do that because potential_constant_expression_1 is
very conservative and just doesn't recurse on subexpressions in many cases.
2025-07-10 Jakub Jelinek <jakub@redhat.com>
PR c++/117785
gcc/c-family/
* c-cppbuiltin.cc (c_cpp_builtins): Predefine
__cpp_constexpr_exceptions=202411L for C++26.
gcc/cp/
* constexpr.cc: Implement C++26 P3068R5 - constexpr exceptions.
(class constexpr_global_ctx): Add caught_exceptions and
uncaught_exceptions members.
(constexpr_global_ctx::constexpr_global_ctx): Initialize
uncaught_exceptions.
(returns, breaks, continues, switches): Move earlier.
(throws): New function.
(exception_what_str, diagnose_std_terminate,
diagnose_uncaught_exception): New functions.
(enum cxa_builtin): New type.
(cxx_cxa_builtin_fn_p, cxx_eval_cxa_builtin_fn): New functions.
(cxx_eval_builtin_function_call): Add jump_target argument. Call
cxx_eval_cxa_builtin_fn for __builtin_eh_ptr_adjust_ref. Adjust
cxx_eval_constant_expression calls, if it results in jmp_target,
set *jump_target to it and return.
(cxx_bind_parameters_in_call): Add jump_target argument. Pass
it through to cxx_eval_constant_expression. If it sets *jump_target,
break.
(fold_operand): Adjust cxx_eval_constant_expression caller.
(cxx_eval_assert): Likewise. If it set jmp_target, return true.
(cxx_eval_internal_function): Add jump_target argument. Pass it
through to cxx_eval_constant_expression. Return early if *jump_target
after recursing on args.
(cxx_eval_dynamic_cast_fn): Likewise. Don't set reference_p for
C++26 with -fexceptions.
(cxx_eval_thunk_call): Add jump_target argument. Pass it through
to cxx_eval_constant_expression.
(cxx_set_object_constness): Likewise. Don't set TREE_READONLY if
throws (jump_target).
(cxx_eval_call_expression): Add jump_target argument. Pass it
through to cxx_eval_internal_function, cxx_eval_builtin_function_call,
cxx_eval_thunk_call, cxx_eval_dynamic_cast_fn and
cxx_set_object_constness. Pass it through also
cxx_eval_constant_expression on arguments, cxx_bind_parameters_in_call
and cxx_fold_indirect_ref and for those cases return early
if *jump_target. Call cxx_eval_cxa_builtin_fn for cxx_cxa_builtin_fn_p
functions. For cxx_eval_constant_expression on body, pass address of
cleared jmp_target automatic variable, if it throws propagate
to *jump_target and make it non-cacheable. For C++26 don't diagnose
calls to non-constexpr functions before cxx_bind_parameters_in_call
could report some argument throwing an exception.
(cxx_eval_unary_expression): Add jump_target argument. Pass it
through to cxx_eval_constant_expression and return early
if *jump_target after the call.
(cxx_fold_pointer_plus_expression): Likewise.
(cxx_eval_binary_expression): Likewise and similarly for
cxx_fold_pointer_plus_expression call.
(cxx_eval_conditional_expression): Pass jump_target to
cxx_eval_constant_expression on first operand and return early
if *jump_target after the call.
(cxx_eval_vector_conditional_expression): Add jump_target argument.
Pass it through to cxx_eval_constant_expression for all 3 arguments
and return early if *jump_target after any of those calls.
(get_array_or_vector_nelts): Add jump_target argument. Pass it
through to cxx_eval_constant_expression.
(eval_and_check_array_index): Add jump_target argument. Pass it
through to cxx_eval_constant_expression calls and return early after
each of them if *jump_target.
(cxx_eval_array_reference): Likewise.
(cxx_eval_component_reference): Likewise.
(cxx_eval_bit_field_ref): Likewise.
(cxx_eval_bit_cast): Likewise. Assert CHECKING_P call doesn't
throw or return.
(cxx_eval_logical_expression): Add jump_target argument. Pass it
through to cxx_eval_constant_expression calls and return early after
each of them if *jump_target.
(cxx_eval_bare_aggregate): Likewise.
(cxx_eval_vec_init_1): Add jump_target argument. Pass it through
to cxx_eval_bare_aggregate and recursive call. Pass it through
to get_array_or_vector_nelts and cxx_eval_constant_expression
and return early after it if *jump_target.
(cxx_eval_vec_init): Add jump_target argument. Pass it through
to cxx_eval_constant_expression and cxx_eval_vec_init_1.
(cxx_union_active_member): Add jump_target argument. Pass it
through to cxx_eval_constant_expression and return early after it
if *jump_target.
(cxx_fold_indirect_ref_1): Add jump_target argument. Pass it
through to cxx_union_active_member and recursive calls.
(cxx_eval_indirect_ref): Add jump_target argument. Pass it through
to cxx_fold_indirect_ref_1 calls and to recursive call, in which
case return early after it if *jump_target.
(cxx_fold_indirect_ref): Add jump_target argument. Pass it through
to cxx_fold_indirect_ref and cxx_eval_constant_expression calls and
return early after those if *jump_target.
(cxx_eval_trinary_expression): Add jump_target argument. Pass it
through to cxx_eval_constant_expression calls and return early after
those if *jump_target.
(cxx_eval_store_expression): Add jump_target argument. Pass it
through to cxx_eval_constant_expression and eval_and_check_array_index
calls and return early after those if *jump_target.
(cxx_eval_increment_expression): Add jump_target argument. Pass it
through to cxx_eval_constant_expression calls and return early after
those if *jump_target.
(label_matches): Handle VAR_DECL case.
(cxx_eval_statement_list): Remove local_target variable and
!jump_target handling. Handle throws (jump_target) like returns or
breaks.
(cxx_eval_loop_expr): Remove local_target variable and !jump_target
handling. Pass it through to cxx_eval_constant_expression. Handle
throws (jump_target) like returns.
(cxx_eval_switch_expr): Pass jump_target through to
cxx_eval_constant_expression on cond, return early after it
if *jump_target.
(build_new_constexpr_heap_type): Add jump_target argument. Pass it
through to cxx_eval_constant_expression calls, return early after
those if *jump_target.
(merge_jump_target): New function.
(cxx_eval_constant_expression): Make jump_target argument no longer
defaulted, don't test jump_target for NULL. Pass jump_target
through to recursive calls, cxx_eval_call_expression,
cxx_eval_store_expression, cxx_eval_indirect_ref,
cxx_eval_unary_expression, cxx_eval_binary_expression,
cxx_eval_logical_expression, cxx_eval_array_reference,
cxx_eval_component_reference, cxx_eval_bit_field_ref,
cxx_eval_vector_conditional_expression, cxx_eval_bare_aggregate,
cxx_eval_vec_init, cxx_eval_trinary_expression, cxx_fold_indirect_ref,
build_new_constexpr_heap_type, cxx_eval_increment_expression,
cxx_eval_bit_cast and return earlyu after some of those
if *jump_target as needed.
(cxx_eval_constant_expression) <case TARGET_EXPR>: For C++26 push
also CLEANUP_EH_ONLY cleanups, with NULL_TREE marker after them.
(cxx_eval_constant_expression) <case RETURN_EXPR>: Don't
override *jump_target if throws (jump_target).
(cxx_eval_constant_expression) <case TRY_CATCH_EXPR, case TRY_BLOCK,
case MUST_NOT_THROW_EXPR, case TRY_FINALLY_EXPR, case CLEANUP_STMT>:
Handle C++26 constant expressions.
(cxx_eval_constant_expression) <case CLEANUP_POINT_EXPR>: For C++26
with throws (jump_target) evaluate the CLEANUP_EH_ONLY cleanups as
well, and if not throws (jump_target) skip those. Set *jump_target
if some of the cleanups threw.
(cxx_eval_constant_expression) <case THROW_EXPR>: Recurse on operand
for C++26.
(cxx_eval_outermost_constant_expr): Diagnose uncaught exceptions both
from main expression and cleanups, diagnose also
break/continue/returns from the main expression. Handle
CLEANUP_EH_ONLY cleanup markers. Don't diagnose mutable poison stuff
if non_constant_p. Use different diagnostics for non-deleted heap
allocations if they were allocated by __cxa_allocate_exception.
(callee_might_throw): New function.
(struct check_for_return_continue_data): Add could_throw field.
(check_for_return_continue): Handle AGGR_INIT_EXPR and CALL_EXPR and
set d->could_throw if they could throw.
(potential_constant_expression_1): For CALL_EXPR allow
cxx_dynamic_cast_fn_p calls. For C++26 set *jump_target to void_node
for calls that could throw. For C++26 if call to non-constexpr call
is seen, try to evaluate arguments first and if they could throw,
don't diagnose call to non-constexpr function nor return false.
Adjust check_for_return_continue_data initializers and
set *jump_target to void_node if data.could_throw_p. For C++26
recurse on THROW_EXPR argument. Add comment explaining TRY_BLOCK
handling with C++26 exceptions. Handle throws like returns in some
cases.
* cp-tree.h (MUST_NOT_THROW_NOEXCEPT_P, MUST_NOT_THROW_THROW_P,
MUST_NOT_THROW_CATCH_P, DECL_EXCEPTION_REFCOUNT): Define.
(DECL_LOCAL_DECL_P): Fix comment typo, VARIABLE_DECL -> VAR_DECL.
(enum cp_built_in_function): Add CP_BUILT_IN_EH_PTR_ADJUST_REF,
(handler_match_for_exception_type): Declare.
* call.cc (handler_match_for_exception_type): New function.
* except.cc (initialize_handler_parm): Set MUST_NOT_THROW_CATCH_P
on newly created MUST_NOT_THROW_EXPR.
(begin_eh_spec_block): Set MUST_NOT_THROW_NOEXCEPT_P.
(wrap_cleanups_r): Set MUST_NOT_THROW_THROW_P.
(build_throw): Add another TARGET_EXPR whose scope spans
until after the __cxa_throw call and copy pointer value from ptr
to it and use it in __cxa_throw argument.
* tree.cc (builtin_valid_in_constant_expr_p): Handle
CP_BUILT_IN_EH_PTR_ADJUST_REF.
* decl.cc (cxx_init_decl_processing): Initialize
__builtin_eh_ptr_adjust_ref FE builtin.
* pt.cc (tsubst_stmt) <case MUST_NOT_THROW_EXPR>: Copy the
MUST_NOT_THROW_NOEXCEPT_P, MUST_NOT_THROW_THROW_P and
MUST_NOT_THROW_CATCH_P flags.
* cp-gimplify.cc (cp_gimplify_expr) <case CALL_EXPR>: Error on
non-folded CP_BUILT_IN_EH_PTR_ADJUST_REF calls.
gcc/testsuite/
* g++.dg/cpp0x/constexpr-ellipsis2.C: Expect different diagnostics for
C++26.
* g++.dg/cpp0x/constexpr-throw.C: Likewise.
* g++.dg/cpp1y/constexpr-84192.C: Expect different diagnostics.
* g++.dg/cpp1y/constexpr-throw.C: Expect different diagnostics for
C++26.
* g++.dg/cpp1z/constexpr-asm-5.C: Likewise.
* g++.dg/cpp26/constexpr-eh1.C: New test.
* g++.dg/cpp26/constexpr-eh2.C: New test.
* g++.dg/cpp26/constexpr-eh3.C: New test.
* g++.dg/cpp26/constexpr-eh4.C: New test.
* g++.dg/cpp26/constexpr-eh5.C: New test.
* g++.dg/cpp26/constexpr-eh6.C: New test.
* g++.dg/cpp26/constexpr-eh7.C: New test.
* g++.dg/cpp26/constexpr-eh8.C: New test.
* g++.dg/cpp26/constexpr-eh9.C: New test.
* g++.dg/cpp26/constexpr-eh10.C: New test.
* g++.dg/cpp26/constexpr-eh11.C: New test.
* g++.dg/cpp26/constexpr-eh12.C: New test.
* g++.dg/cpp26/constexpr-eh13.C: New test.
* g++.dg/cpp26/constexpr-eh14.C: New test.
* g++.dg/cpp26/constexpr-eh15.C: New test.
* g++.dg/cpp26/feat-cxx26.C: Change formatting in __cpp_pack_indexing
and __cpp_pp_embed test. Add __cpp_constexpr_exceptions test.
* g++.dg/cpp26/static_assert1.C: Expect different diagnostics for
C++26.
* g++.dg/cpp2a/consteval34.C: Likewise.
* g++.dg/cpp2a/consteval-memfn1.C: Likewise.
* g++.dg/cpp2a/constexpr-dynamic4.C: For C++26 add std::exception and
std::bad_cast definitions and expect different diagnostics.
* g++.dg/cpp2a/constexpr-dynamic6.C: Likewise.
* g++.dg/cpp2a/constexpr-dynamic7.C: Likewise.
* g++.dg/cpp2a/constexpr-dynamic8.C: Likewise.
* g++.dg/cpp2a/constexpr-dynamic9.C: Likewise.
* g++.dg/cpp2a/constexpr-dynamic11.C: Likewise.
* g++.dg/cpp2a/constexpr-dynamic14.C: Likewise.
* g++.dg/cpp2a/constexpr-dynamic18.C: Likewise.
* g++.dg/cpp2a/constexpr-new27.C: New test.
* g++.dg/cpp2a/constexpr-typeid5.C: New test.
libstdc++-v3/
* include/bits/version.def (constexpr_exceptions): New.
* include/bits/version.h: Regenerate.
* libsupc++/exception (std::bad_exception::bad_exception): Add
_GLIBCXX26_CONSTEXPR.
(std::bad_exception::~bad_exception, std::bad_exception::what): For
C++26 add constexpr and define inline.
* libsupc++/exception.h (std::exception::exception,
std::exception::operator=): Add _GLIBCXX26_CONSTEXPR.
(std::exception::~exception, std::exception::what): For C++26 add
constexpr and define inline.
* libsupc++/exception_ptr.h (std::make_exception_ptr): Add
_GLIBCXX26_CONSTEXPR. For if consteval use just throw with
current_exception() in catch.
(std::exception_ptr::exception_ptr(void*)): For C++26 add constexpr
and define inline.
(std::exception_ptr::exception_ptr()): Add _GLIBCXX26_CONSTEXPR.
(std::exception_ptr::exception_ptr(const exception_ptr&)): Likewise.
Use __builtin_eh_ptr_adjust_ref if consteval and compiler has it
instead of _M_addref.
(std::exception_ptr::exception_ptr(nullptr_t)): Add
_GLIBCXX26_CONSTEXPR.
(std::exception_ptr::exception_ptr(exception_ptr&&)): Likewise.
(std::exception_ptr::operator=): Likewise.
(std::exception_ptr::~exception_ptr): Likewise. Use
__builtin_eh_ptr_adjust_ref if consteval and compiler has it
instead of _M_release.
(std::exception_ptr::swap): Add _GLIBCXX26_CONSTEXPR.
(std::exception_ptr::operator bool): Likewise.
(std::exception_ptr::operator==): Likewise.
* libsupc++/nested_exception.h
(std::nested_exception::nested_exception): Add _GLIBCXX26_CONSTEXPR.
(std::nested_exception::operator=): Likewise.
(std::nested_exception::~nested_exception): For C++26 add constexpr
and define inline.
(std::nested_exception::rethrow_if_nested): Add _GLIBCXX26_CONSTEXPR.
(std::nested_exception::nested_ptr): Likewise.
(std::_Nested_exception::_Nested_exception): Likewise.
(std::throw_with_nested, std::rethrow_if_nested): Likewise.
* libsupc++/new (std::bad_alloc::bad_alloc): Likewise.
(std::bad_alloc::operator=): Likewise.
(std::bad_alloc::~bad_alloc): For C++26 add constexpr and define
inline.
(std::bad_alloc::what): Likewise.
(std::bad_array_new_length::bad_array_new_length): Add
_GLIBCXX26_CONSTEXPR.
(std::bad_array_new_length::~bad_array_new_length): For C++26 add
constexpr and define inline.
(std::bad_array_new_length::what): Likewise.
* libsupc++/typeinfo (std::bad_cast::bad_cast): Add
_GLIBCXX26_CONSTEXPR.
(std::bad_cast::~bad_cast): For C++26 add constexpr and define inline.
(std::bad_cast::what): Likewise.
(std::bad_typeid::bad_typeid): Add _GLIBCXX26_CONSTEXPR.
(std::bad_typeid::~bad_typeid): For C++26 add constexpr and define
inline.
(std::bad_typeid::what): Likewise.
|