While looking at pack-indexing16.C I thought it would be helpful to print
the problematic type/value.
gcc/cp/ChangeLog:
* semantics.cc (finish_type_pack_element): Add more info
to diagnostics.
libstdc++-v3/ChangeLog:
* testsuite/20_util/tuple/element_access/get_neg.cc: Adjust
diagnostic.
gcc/testsuite/ChangeLog:
* g++.dg/cpp26/pack-indexing2.C: Adjust diagnostics.
* g++.dg/ext/type_pack_element2.C: Likewise.
* g++.dg/ext/type_pack_element4.C: Likewise.
The P3379R0 bump to __cpp_lib_constrained_equality relates to changes
that only affect std::expected, so there's no reason to define the
updated value in C++20.
This change restores the previous value (202403) for C++20, and only
uses the new value (202411) for C++23 and later.
Also remove the TODO comments, because I correctly predicted that the
final value would be 202411.
libstdc++-v3/ChangeLog:
* include/bits/version.def (constrained_equality): Only define
as 202411 for C++23 and later, use 202403 for C++20.
* include/bits/version.h: Regenerate.
* testsuite/20_util/expected/equality_constrained.cc: Remove
TODO comment.
In r15-8980-gf4b6acfc36fb1f I introduced a new function object for
finding the smaller of two distances. In bugzilla Hewill Kang pointed
out that we still need to explicitly convert the result back to the
right difference type, because the result might be an integer-like class
type that doesn't convert to an integral type explicitly.
Rather than doing that conversion in the __mindist function object, I
think it's simpler to remove it again and just do a comparison and
assignment. We always want the result to have a specific type, so we can
just check if the value of the other type is smaller, and then convert
that to the other type if so.
libstdc++-v3/ChangeLog:
PR libstdc++/101587
* include/bits/ranges_uninitialized.h (__detail::__mindist):
Remove.
(ranges::uninitialized_copy, ranges::uninitialized_copy_n)
(ranges::uninitialized_move, ranges::uninitialized_move_n): Use
comparison and assignment instead of __mindist.
* testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc:
Check with ranges that use integer-like class type for
difference type.
* testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc:
Likewise.
Reviewed-by: Tomasz Kaminski <tkaminsk@redhat.com>
Reviewed-by: Hewill Kang <hewillk@gmail.com>
The boolean-testable requirements don't require the type to be copyable,
so we need to convert to bool before it might need to be copied.
libstdc++-v3/ChangeLog:
PR libstdc++/119545
* include/std/tuple (operator==): Convert comparison results to
bool.
* testsuite/20_util/tuple/comparison_operators/119545.cc: New
test.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
I believe these don't get detected by DejaGnu's regexp.
Found by dg-lint.
libstdc++-v3/ChangeLog:
* testsuite/17_intro/shared_with_static_deps.cc: Fix malformed
dg-require-static-libstdcxx directive.
* testsuite/17_intro/static.cc: Likewise.
* testsuite/18_support/type_info/110572.cc: Likewise.
* testsuite/20_util/to_chars/4.cc: Likewise.
* testsuite/std/time/tzdb_list/pr118811.cc: Likewise.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Because ranges can have any signed integer-like type as difference_type,
it's not valid to use std::min(diff1, diff2). Instead of calling
std::min with an explicit template argument, this adds a new __mindist
helper that determines the common type and uses that with std::min.
libstdc++-v3/ChangeLog:
PR libstdc++/101587
* include/bits/ranges_uninitialized.h (__detail::__mindist):
New function object.
(ranges::uninitialized_copy, ranges::uninitialized_copy_n)
(ranges::uninitialized_move, ranges::uninitialized_move_n): Use
__mindist instead of std::min.
* testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc:
Check ranges with difference difference types.
* testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc:
Likewise.
Our <climits> ensures that LLONG_MIN, LLONG_MAX, and ULLONG_MAX are
defined even if the C library's <limits.h> doesn't define them. Our
<limits.h> then includes <climits>, which should mean that <limits.h>
and <climits> always define the same macros. However, we only install
our own version of <limits.h> for --enable-cheaders=c and not for the
default --enable-cheaders=c_global setting that everybody uses.
This means that if the C library's <limits.h> is not C++-aware, or if
the C library doesn't provide it and GCC's own gcc/glimits.h is used
instead, then <climits> defines the macros for long long types but
<limits.h> does not.
This causes the new 20_util/stdbit/1.cc test to fail for arm-non-eabi
because it uses gcc/glimits.h which is not C++-aware, only checking
__STDC_VERSION__ when deciding whether to declare the long long macros.
If gcc/glimits.h also checked __cplusplus it would be OK, and we would
not need our own <limits.h> to be installed.
This commit just changes the new test to use <climits> instead of
<limits.h>, but we should ensure that gcc/glimits.h is made to work
(i.e. define the long long macros) for C++, and/or install our own
<limits.h> for the --enable-cheaders=c_global configuration.
libstdc++-v3/ChangeLog:
* testsuite/20_util/stdbit/1.cc: Include <climits> instead of
<limits.h>.
A std::weak_ptr<T[]> can be converted to a compatible
std::weak_ptr<U[]>. This is implemented by having suitable converting
constructors to std::weak_ptr which dispatch to the __weak_ptr base
class (implementation detail).
In __weak_ptr<T[]>, lock() is supposed to return a __shared_ptr<T[]>,
not a __shared_ptr<element_type> (that is, __shared_ptr<T>).
Unfortunately the return type of lock() and the type of the returned
__shared_ptr were mismatching and that was causing a compile error: when
converting a __weak_ptr<T[]> to a __weak_ptr<U[]> through __weak_ptr's
converting constructor, the code calls lock(), and that simply fails to
build.
Fix it by removing the usage of element_type inside lock(), and using
_Tp instead.
Note that std::weak_ptr::lock() itself was already correct; the one in
__weak_ptr was faulty (and that is the one called by __weak_ptr's
converting constructors).
libstdc++-v3/ChangeLog:
* include/bits/shared_ptr_base.h (lock): Fixed a compile error
when calling lock() on a weak_ptr<T[]>, by removing an
erroneous usage of element_type from within lock().
* testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc:
Add more tests for array types.
* testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc:
Likewise.
* testsuite/20_util/shared_ptr/requirements/1.cc: New test.
* testsuite/20_util/weak_ptr/requirements/1.cc: New test.
The type tuple<tuple<any>> is clearly copy/move constructible, but for
reasons that are not yet completely understood checking this triggers
constraint recursion with our C++20 tuple implementation (but not the
C++17 implementation).
It turns out this recursion stems from considering the non-template
tuple(const _Elements&) constructor during the copy/move constructibility
check. Considering this constructor is ultimately redundant, since the
defaulted copy/move constructors are better matches.
GCC has a non-standard "perfect candidate" optimization[1] that causes
overload resolution to shortcut considering template candidates if we
find a (non-template) perfect candidate. So to work around this issue
(and as a general compile-time optimization) this patch turns the
problematic constructor into a template so that GCC doesn't consider it
when checking for copy/move constructibility of this tuple type.
Changing the template-ness of a constructor can affect overload
resolution (since template-ness is a tiebreaker) so there's a risk this
change could e.g. introduce overload resolution ambiguities. But the
original C++17 implementation has long defined this constructor as a
template (in order to constrain it etc), so doing the same thing in the
C++20 mode should naturally be quite safe.
The testcase still fails with Clang (in C++20 mode) since it doesn't
implement said optimization.
[1]: See r11-7287-g187d0d5871b1fa and
https://isocpp.org/files/papers/P3606R0.html
PR libstdc++/116440
libstdc++-v3/ChangeLog:
* include/std/tuple (tuple::tuple(const _Elements&...))
[C++20]: Turn into a template.
* testsuite/20_util/tuple/116440.C: New test.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
This is the first part of the P3370R1 proposal just approved by the
committee in Wrocław. This adds C++ equivalents of the functions added
to C23 by WG14 N3022.
These functions are in the global namespace, but to avoid collisions
with the same functions defined by other standard library
implementations, this change defines them in namespace __gnu_cxx and
then adds them to the global namespace.
libstdc++-v3/ChangeLog:
* include/Makefile.am: Add stdbit.h.
* include/Makefile.in: Regenerate.
* src/c++23/std.compat.cc.in: Export <stdbit.h> functions.
* include/c_compatibility/stdbit.h: New file.
* testsuite/20_util/stdbit/1.cc: New test.
* testsuite/20_util/stdbit/2_neg.cc: New test.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
LWG 4148 (approved in Wrocław, November 2024) makes it ill-formed to
dereference a std::unique_ptr if that would return a dangling reference.
That can happen with a custom pointer type and a const-qualified
element_type, such that std::add_lvalue_reference_t<element_type> is a
reference-to-const that could bind to a short-lived temporary.
In C++26 the compiler diagnoses this as an error anyway:
bits/unique_ptr.h:457:16: error: returning reference to temporary [-Wreturn-local-addr]
But that can be disabled with -Wno-return-local-addr so the
static_assert ensures it is enforced consistently.
libstdc++-v3/ChangeLog:
* include/bits/unique_ptr.h (unique_ptr::operator*): Add
static_assert to check for dangling reference, as per LWG 4148.
* testsuite/20_util/unique_ptr/lwg4148.cc: New test.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
The r15-2326-gea435261ad58ea change missed a static_assert for
is_move_constructible_v in expected<cv void, E>::value()&&. When
exceptions are enabled, the program is ill-formed if the error type is
not move constructible, because we can't construct the
std::bad_expected_access. But prior to r15-7856-gd87c0d5443ba86, using
-fno-exceptions meant that we never constructed an exception, so didn't
need to copy/move the error value.
So that we don't rely on the r15-7856-gd87c0d5443ba86 change to the
_GLIBCXX_THROW_OR_ABORT macro to consistently enforce the Mandates:
conditions whether exceptions are enabled or not, we should check the
requirement explicitly.
This adds the missing static_assert. It also adds a test that verifies
the Mandates: conditions added by LWG 3843 and 3490 are enforced even
with -fno-exceptions.
libstdc++-v3/ChangeLog:
* include/std/expected (expected<cv void,E>::value()&&):
Add missing static_assert for LWG 3940.
* testsuite/20_util/expected/lwg3843.cc: New test.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
The old COW std::string is not usable in constant expressions, so these
new tests fail with -D_GLIBCXX_USE_CXX11_ABI=0.
The parts of the tests using std::string can be conditionally skipped.
libstdc++-v3/ChangeLog:
* testsuite/20_util/specialized_algorithms/uninitialized_copy/constexpr.cc:
Do not test COW std::string in constexpr contexts.
* testsuite/20_util/specialized_algorithms/uninitialized_default_construct/constexpr.cc:
Likewise.
* testsuite/20_util/specialized_algorithms/uninitialized_fill/constexpr.cc:
Likewise.
* testsuite/20_util/specialized_algorithms/uninitialized_move/constexpr.cc:
Likewise.
* testsuite/20_util/specialized_algorithms/uninitialized_value_construct/constexpr.cc:
Likewise.
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
This commit implements P2819R2 for C++26, making std::complex
destructurable and tuple-like (see [complex.tuple]).
std::get needs to get forward declared in stl_pair.h (following the
existing precedent for the implementation of P2165R4, cf.
r14-8710-g65b4cba9d6a9ff), and implemented in <complex>.
Also, std::get(complex<T>) needs to return *references* to the real and
imaginary parts of a std::complex object, honoring the value category
and constness of the argument. In principle a straightforward task, it
gets a bit convoluted by the fact that:
1) std::complex does not have existing getters that one can use for this
(real() and imag() return values, not references);
2) there are specializations for language/extended floating-point types,
which requires some duplication -- need to amend the primary and all
the specializations;
3) these specializations use a `__complex__ T`, but the primary template
uses two non-static data members, making generic code harder to write.
The implementation choice used here is to add the overloads of std::get
for complex as declared in [complex.tuple]. In turn they dispatch to a
newly added getter that extracts references to the real/imaginary parts
of a complex<T>. This getter is private API, and the implementation
depends on whether it's the primary (bind the data member) or a
specialization (use the GCC language extensions for __complex__).
To avoid duplication and minimize template instantiations, the getter
uses C++23's deducing this (this avoids const overloads). The value
category is dealt with by the std::get overloads.
Add a test that covers the aspects of the tuple protocol, as well as the
tuple-like interface. While at it, add a test for the existing
tuple-like feature-testing macro.
PR libstdc++/113310
libstdc++-v3/ChangeLog:
* include/bits/stl_pair.h (get): Forward-declare std::get for
std::complex.
* include/bits/version.def (tuple_like): Bump the value of
the feature-testing macro in C++26.
* include/bits/version.h: Regenerate.
* include/std/complex: Implement the tuple protocol for
std::complex.
(tuple_size): Specialize for std::complex.
(tuple_element): Ditto.
(__is_tuple_like_v): Ditto.
(complex): Add a private getter to obtain references to the real
and the imaginary part, on the primary class template and on its
specializations.
(get): Add overloads of std::get for std::complex.
* testsuite/20_util/tuple/tuple_like_ftm.cc: New test.
* testsuite/26_numerics/complex/tuple_like.cc: New test.
This commit adds support for C++26's constexpr specialized memory
algorithms, introduced by P2283R2, P3508R0, P3369R0.
The uninitialized_default, value, copy, move and fill algorithms are
affected, in all of their variants (iterator-based, range-based and _n
versions.)
The changes are mostly mechanical -- add `constexpr` to a number of
signatures when compiling in C++26 and above modes. The internal helper
guard class for range algorithms instead can be marked unconditionally.
uninitialized_default_construct is implemented in terms of the
_Construct_novalue helper, which requires support for C++26's constexpr
placement new from the compiler (P2747R2, which GCC implements). We can
simply mark it as constexpr in C++26 language modes, even if the
compiler does not support P2747R2 (e.g. Clang 17/18), because C++23's
P2448R2 makes it OK to mark functions as constexpr even if they never
qualify, and other compilers implement this.
The only "real" change to the implementation of the algorithms is that
during constant evaluation I need to dispatch to a constexpr-friendly
version of them.
For each algorithm family I've added only one test to cover it and its
variants; the idea is to avoid too much repetition and simplify future
maintenance.
libstdc++-v3/ChangeLog:
* include/bits/ranges_uninitialized.h: Mark the specialized
memory algorithms as constexpr in C++26. Also mark the members
of the _DestroyGuard helper class.
* include/bits/stl_uninitialized.h: Ditto.
* include/bits/stl_construct.h: (_Construct_novalue) Mark it
as constexpr in C++26.
* include/bits/version.def (raw_memory_algorithms): Bump the
feature-testing macro for C++26.
* include/bits/version.h: Regenerate.
* testsuite/20_util/headers/memory/synopsis.cc: Add constexpr to
the uninitialized_* algorithms (when in C++26) in the test.
* testsuite/20_util/specialized_algorithms/feature_test_macro.cc:
New test.
* testsuite/20_util/specialized_algorithms/uninitialized_copy/constexpr.cc:
New test.
* testsuite/20_util/specialized_algorithms/uninitialized_default_construct/constexpr.cc:
New test.
* testsuite/20_util/specialized_algorithms/uninitialized_fill/constexpr.cc:
New test.
* testsuite/20_util/specialized_algorithms/uninitialized_move/constexpr.cc:
New test.
* testsuite/20_util/specialized_algorithms/uninitialized_value_construct/constexpr.cc:
New test.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Although this should never make a difference for sensible code, we
should really make the expression in the noexcept-specifier match the
expression in the function body.
libstdc++-v3/ChangeLog:
* include/bits/ranges_cmp.h (not_equal_to): Make order of
expressions in noexcept-specifier match the body.
* testsuite/20_util/function_objects/range.cmp/not_equal_to.cc:
Check noexcept.
This actually implements P3247R2 by deprecating the is_trivial type
trait.
libstdc++-v3/ChangeLog:
* include/std/type_traits: Deprecate is_trivial and
is_trivial_v.
* include/experimental/type_traits: Suppress the deprecation
warning.
* testsuite/20_util/is_trivial/requirements/explicit_instantiation.cc:
Amend the test to suppress the deprecation warning.
* testsuite/20_util/is_trivial/requirements/typedefs.cc:
Likewise.
* testsuite/20_util/is_trivial/value.cc: Likewise.
* testsuite/20_util/variable_templates_for_traits.cc: Likewise.
* testsuite/experimental/type_traits/value.cc: Likewise.
* testsuite/18_support/max_align_t/requirements/2.cc: Update the
test with P3247R2's new wording.
Signed-off-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
In preparation for the deprecation of is_trivial (P3247R2).
Unfortunately I am unable to fully understand what aspect of triviality
seems to matter for these algorithms, so I just ported is_trivial to its
direct equivalent (trivially copyable + trivially default
constructible.)
libstdc++-v3/ChangeLog:
* include/pstl/algorithm_impl.h (__remove_elements): Port away
from is_trivial.
(__pattern_inplace_merge): Likewise.
* include/pstl/glue_memory_impl.h (uninitialized_copy): Likewise.
(uninitialized_copy_n): Likewise.
(uninitialized_move): Likewise.
(uninitialized_move_n): Likewise.
(uninitialized_default_construct): Likewise.
(uninitialized_default_construct_n): Likewise.
(uninitialized_value_construct): Likewise.
(uninitialized_value_construct_n): Likewise.
* testsuite/20_util/specialized_algorithms/pstl/uninitialized_construct.cc:
Likewise.
* testsuite/20_util/specialized_algorithms/pstl/uninitialized_copy_move.cc:
Likewise.
* testsuite/20_util/specialized_algorithms/pstl/uninitialized_fill_destroy.cc:
Likewise.
* testsuite/25_algorithms/pstl/alg_modifying_operations/partition.cc:
Likewise.
Signed-off-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
This was removed by P2868R3, voted into the C++26 draft at the November
2023 meeting in Kona. We've had a deprecated warning in place for three
years.
libstdc++-v3/ChangeLog:
* include/bits/allocator.h (allocator::is_always_equal): Do not
define for C++26.
(allocator<void>::is_always_equal): Likewise.
* testsuite/20_util/allocator/requirements/typedefs.cc: Check
that is_always_equal is not present in C++26.
* testsuite/20_util/allocator/void.cc: Do not require
is_always_equal for C++26.
* testsuite/23_containers/vector/bool/cons/constexpr.cc: Add
missing override of base's is_always_equal.
* testsuite/23_containers/vector/cons/constexpr.cc: Likewise.
The converting constructors had the same bug as the converting
assignments, so need the same fix as r15-5833-gc2c7d71eeeab7c.
libstdc++-v3/ChangeLog:
PR libstdc++/117889
PR libstdc++/117858
* include/std/optional (optional(const optional<U>&)): Fix copy
and paste error in constraints.
(optional(optional<U>&&)): Likewise.
* testsuite/20_util/optional/assignment/117858.cc: Move to ...
* testsuite/20_util/optional/cons/117858.cc: New test.
The copy & paste bug affected two assignment operators, so ensure the
new test covers both.
libstdc++-v3/ChangeLog:
PR libstdc++/117858
* testsuite/20_util/optional/assignment/117858.cc: Also test
assignment from rvalue optional.
It looks like I copied these constraints from operator=(U&&) and didn't
correct them to account for the parameter being optional<U> not U.
libstdc++-v3/ChangeLog:
PR libstdc++/117858
* include/std/optional (operator=(const optional<U>&)): Fix copy
and paste error in constraints.
(operator=(optional<U>&&)): Likewise.
* testsuite/20_util/optional/assignment/117858.cc: New test.
Another C++26 paper just approved in Wrocław. The std::monostate class
is defined in <variant> since C++17, but for C++26 it should also be
available in <utility>.
libstdc++-v3/ChangeLog:
* include/Makefile.am: Add bits/monostate.h.
* include/Makefile.in: Regenerate.
* include/std/utility: Include <bits/monostate.h>.
* include/std/variant (monostate, hash<monostate>): Move
definitions to ...
* include/bits/monostate.h: New file.
* testsuite/20_util/headers/utility/synopsis.cc: Add monostate
and hash<monostate> declarations.
* testsuite/20_util/monostate/requirements.cc: New test.
This is deprecated in the C++20 standard and will be removed at some
point.
libstdc++-v3/ChangeLog:
* include/bits/stl_relops.h (rel_ops): Add deprecated attribute.
* testsuite/20_util/headers/utility/using_namespace_std_rel_ops.cc:
Add dg-warning for -Wdeprecated warnings.
* testsuite/20_util/rel_ops.cc: Likewise.
* testsuite/util/testsuite_containers.h: Disable -Wdeprecated
warnings when using rel_ops.
This patch implements C++26 Pack Indexing, as described in
<https://wg21.link/P2662R3>.
The issue discussing how to mangle pack indexes has not been resolved
yet <https://github.com/itanium-cxx-abi/cxx-abi/issues/175> and I've
made no attempt to address it so far.
Unlike v1, which used augmented TYPE/EXPR_PACK_EXPANSION codes, this
version introduces two new codes: PACK_INDEX_EXPR and PACK_INDEX_TYPE.
Both carry two operands: the pack expansion and the index. They are
handled in tsubst_pack_index: substitute the index and the pack and
then extract the element from the vector (if possible).
To handle pack indexing in a decltype or with decltype(auto), there is
also the new PACK_INDEX_PARENTHESIZED_P flag.
With this feature, it's valid to write something like
using U = tmpl<Ts...[Is]...>;
where we first expand the template argument into
Ts...[Is#0], Ts...[Is#1], ...
and then substitute each individual pack index.
PR c++/113798
gcc/cp/ChangeLog:
* constexpr.cc (potential_constant_expression_1) <case PACK_INDEX_EXPR>:
New case.
* cp-objcp-common.cc (cp_common_init_ts): Mark PACK_INDEX_TYPE and
PACK_INDEX_EXPR.
* cp-tree.def (PACK_INDEX_TYPE): New.
(PACK_INDEX_EXPR): New.
* cp-tree.h (WILDCARD_TYPE_P): Also check PACK_INDEX_TYPE.
(PACK_INDEX_CHECK): Define.
(PACK_INDEX_P): Define.
(PACK_INDEX_PACK): Define.
(PACK_INDEX_INDEX): Define.
(PACK_INDEX_PARENTHESIZED_P): Define.
(make_pack_index): Declare.
(pack_index_element): Declare.
* cxx-pretty-print.cc (cxx_pretty_printer::expression) <case
PACK_INDEX_EXPR>: New case.
(cxx_pretty_printer::type_id) <case PACK_INDEX_TYPE>: New case.
* error.cc (dump_type) <case PACK_INDEX_TYPE>: New case.
(dump_type_prefix): Handle PACK_INDEX_TYPE.
(dump_type_suffix): Likewise.
(dump_expr) <case PACK_INDEX_EXPR>: New case.
* mangle.cc (write_type) <case PACK_INDEX_TYPE>: New case.
* module.cc (trees_out::type_node) <case PACK_INDEX_TYPE>: New case.
(trees_in::tree_node) <case PACK_INDEX_TYPE>: New case.
* parser.cc (cp_parser_next_tokens_are_pack_index_p): New.
(cp_parser_pack_index): New.
(cp_parser_primary_expression): Handle a C++26 pack-index-expression.
(cp_parser_unqualified_id): Handle a C++26 pack-index-specifier.
(cp_parser_nested_name_specifier_opt): See if a pack-index-specifier
follows.
(cp_parser_qualifying_entity): Handle a C++26 pack-index-specifier.
(cp_parser_decltype_expr): Set id_expression_or_member_access_p for
pack indexing.
(cp_parser_mem_initializer_id): Handle a C++26 pack-index-specifier.
(cp_parser_simple_type_specifier): Likewise.
(cp_parser_base_specifier): Likewise.
* pt.cc (iterative_hash_template_arg) <case PACK_INDEX_TYPE,
PACK_INDEX_EXPR>: New case.
(find_parameter_packs_r) <case PACK_INDEX_TYPE, PACK_INDEX_EXPR>: New
case.
(make_pack_index): New.
(tsubst_pack_index): New.
(tsubst): Avoid tsubst on PACK_INDEX_TYPE.
<case TYPENAME_TYPE>: Add a call to error.
<case PACK_INDEX_TYPE>: New case.
(tsubst_expr) <case PACK_INDEX_EXPR>: New case.
(dependent_type_p_r): Return true for PACK_INDEX_TYPE.
(type_dependent_expression_p): Recurse on PACK_INDEX_PACK for
PACK_INDEX_EXPR.
* ptree.cc (cxx_print_type) <case PACK_INDEX_TYPE>: New case.
* semantics.cc (finish_parenthesized_expr): Set
PACK_INDEX_PARENTHESIZED_P for PACK_INDEX_EXPR.
(finish_type_pack_element): Adjust error messages.
(pack_index_element): New.
* tree.cc (cp_tree_equal) <case PACK_INDEX_EXPR>: New case.
(cp_walk_subtrees) <case PACK_INDEX_TYPE, PACK_INDEX_EXPR>: New case.
* typeck.cc (structural_comptypes) <case PACK_INDEX_TYPE>: New case.
libstdc++-v3/ChangeLog:
* testsuite/20_util/tuple/element_access/get_neg.cc: Adjust
dg-prune-output.
gcc/testsuite/ChangeLog:
* g++.dg/cpp26/pack-indexing1.C: New test.
* g++.dg/cpp26/pack-indexing2.C: New test.
* g++.dg/cpp26/pack-indexing3.C: New test.
* g++.dg/cpp26/pack-indexing4.C: New test.
* g++.dg/cpp26/pack-indexing5.C: New test.
* g++.dg/cpp26/pack-indexing6.C: New test.
* g++.dg/cpp26/pack-indexing7.C: New test.
* g++.dg/cpp26/pack-indexing8.C: New test.
* g++.dg/cpp26/pack-indexing9.C: New test.
* g++.dg/cpp26/pack-indexing10.C: New test.
* g++.dg/cpp26/pack-indexing11.C: New test.
* g++.dg/modules/pack-index-1_a.C: New test.
* g++.dg/modules/pack-index-1_b.C: New test.
This attempts to simplify and clean up our std::hash code. The primary
benefit is improved diagnostics for users when they do something wrong
involving std::hash or unordered containers. An additional benefit is
that for the unstable ABI (--enable-symvers=gnu-versioned-namespace) we
can reduce the memory footprint of several std::hash specializations.
In the current design, __hash_enum is a base class of the std::hash
primary template, but the partial specialization of __hash_enum for
non-enum types is disabled. This means that if a user forgets to
specialize std::hash for their class type (or forgets to use a custom
hash function for unordered containers) they get error messages about
std::__hash_enum not being constructible. This is confusing when there
is no enum type involved: why should users care about __hash_enum not
being constructible if they're not trying to hash enums?
This change makes the std::hash primary template only derive from
__hash_enum when the template argument type is an enum. Otherwise, it
derives directly from a new class template, __hash_not_enabled. This new
class template defines the deleted members that cause a given std::hash
specialization to be a disabled specialization (as per P0513R0). Now
when users try to use a disabled specialization, they get more
descriptive errors that mention __hash_not_enabled instead of
__hash_enum.
Additionally, adjust __hash_base to remove the deprecated result_type
and argument_type typedefs for C++20 and later.
In the current code we use a __poison_hash base class in the std::hash
specializations for std::unique_ptr, std::optional, and std::variant.
The primary template of __poison_hash has deleted special members, which
is used to conditionally disable the derived std::hash specialization.
This can also result in confusing diagnostics, because seeing "poison"
in an enabled specialization is misleading. Only some uses of
__poison_hash actually "poison" anything, i.e. cause a specialization to
be disabled. In other cases it's just an empty base class that does
nothing.
This change removes __poison_hash and changes the std::hash
specializations that were using it to conditionally derive from
__hash_not_enabled instead. When the std::hash specialization is
enabled, there is no more __poison_hash base class. However, to preserve
the ABI properties of those std::hash specializations, we need to
replace __poison_hash with some other empty base class. This is needed
because in the current code std::hash<std::variant<int, const int>> has
two __poison_hash<int> base classes, which must have unique addresses,
so sizeof(std::hash<std::variant<int, const int>>) == 2. To preserve
this unfortunate property, a new __hash_empty_base class is used as a
base class to re-introduce du0plicate base classes that increase the
class size. For the unstable ABI we don't use __hash_empty_base so the
std::hash<std::variant<T...>> specializations are always size 1, and
the class hierarchy is much simpler so will compile faster.
Additionally, remove the result_type and argument_type typedefs from all
disabled specializations of std::hash for std::unique_ptr,
std::optional, and std::variant. Those typedefs are useless for disabled
specializations, and although the standard doesn't say they must *not*
be present for disabled specializations, it certainly only requires them
for enabled specializations. Finally, for C++20 the typedefs are also
removed from enabled specializations of std::hash for std::unique_ptr,
std::optional, and std::variant.
libstdc++-v3/ChangeLog:
* doc/xml/manual/evolution.xml: Document removal of nested types
from std::hash specializations.
* doc/html/manual/api.html: Regenerate.
* include/bits/functional_hash.h (__hash_base): Remove
deprecated nested types for C++20.
(__hash_empty_base): Define new class template.
(__is_hash_enabled_for): Define new variable template.
(__poison_hash): Remove.
(__hash_not_enabled): Define new class template.
(__hash_enum): Remove partial specialization for non-enums.
(hash): Derive from __hash_not_enabled for non-enums, instead of
__hash_enum.
* include/bits/unique_ptr.h (__uniq_ptr_hash): Derive from
__hash_base. Conditionally derive from __hash_empty_base.
(__uniq_ptr_hash<>): Remove disabled specialization.
(hash): Do not derive from __hash_base unconditionally.
Conditionally derive from either __uniq_ptr_hash or
__hash_not_enabled.
* include/std/optional (__optional_hash_call_base): Remove.
(__optional_hash): Define new class template.
(hash): Derive from either
(hash): Conditionally derive from either __optional_hash or
__hash_not_enabled. Remove nested typedefs.
* include/std/variant (_Base_dedup): Replace __poison_hash with
__hash_empty_base.
(__variant_hash_call_base_impl): Remove.
(__variant_hash): Define new class template.
(hash): Conditionally derive from either __variant_hash or
__hash_not_enabled. Remove nested typedefs.
* testsuite/20_util/optional/hash.cc: Check whether nested types
are present.
* testsuite/20_util/variant/hash.cc: Likewise.
* testsuite/20_util/optional/hash_abi.cc: New test.
* testsuite/20_util/unique_ptr/hash/abi.cc: New test.
* testsuite/20_util/unique_ptr/hash/types.cc: New test.
* testsuite/20_util/variant/hash_abi.cc: New test.
This removes all the __copy_move class template specializations that
decide how to optimize std::copy and std::copy_n. We can inline those
optimizations into the algorithms, using if-constexpr (and macros for
C++98 compatibility) and remove the code dispatching to the various
class template specializations.
Doing this means we implement the optimization directly for std::copy_n
instead of deferring to std::copy, That avoids the unwanted consequence
of advancing the iterator in copy_n only to take the difference later to
get back to the length that we already had in copy_n originally (as
described in PR 115444).
With the new flattened implementations, we can also lower contiguous
iterators to pointers in std::copy/std::copy_n/std::copy_backwards, so
that they benefit from the same memmove optimizations as pointers.
There's a subtlety though: contiguous iterators can potentially throw
exceptions to exit the algorithm early. So we can only transform the
loop to memmove if dereferencing the iterator is noexcept. We don't
check that incrementing the iterator is noexcept because we advance the
contiguous iterators before using memmove, so that if incrementing would
throw, that happens first. I am writing a proposal (P3349R0) which would
make this unnecessary, so I hope we can drop the nothrow requirements
later.
This change also solves PR 114817 by checking is_trivially_assignable
before optimizing copy/copy_n etc. to memmove. It's not enough to check
that the types are trivially copyable (a precondition for using memmove
at all), we also need to check that the specific assignment that would
be performed by the algorithm is also trivial. Replacing a non-trivial
assignment with memmove would be observable, so not allowed.
libstdc++-v3/ChangeLog:
PR libstdc++/115444
PR libstdc++/114817
* include/bits/stl_algo.h (__copy_n): Remove generic overload
and overload for random access iterators.
(copy_n): Inline generic version of __copy_n here. Do not defer
to std::copy for random access iterators.
* include/bits/stl_algobase.h (__copy_move): Remove.
(__nothrow_contiguous_iterator, __memcpyable_iterators): New
concepts.
(__assign_one, _GLIBCXX_TO_ADDR, _GLIBCXX_ADVANCE): New helpers.
(__copy_move_a2): Inline __copy_move logic and conditional
memmove optimization into the most generic overload.
(__copy_n_a): Likewise.
(__copy_move_backward): Remove.
(__copy_move_backward_a2): Inline __copy_move_backward logic and
memmove optimization into the most generic overload.
* testsuite/20_util/specialized_algorithms/uninitialized_copy/114817.cc:
New test.
* testsuite/20_util/specialized_algorithms/uninitialized_copy_n/114817.cc:
New test.
* testsuite/25_algorithms/copy/114817.cc: New test.
* testsuite/25_algorithms/copy/115444.cc: New test.
* testsuite/25_algorithms/copy_n/114817.cc: New test.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
This refactors the std::uninitialized_copy, std::uninitialized_fill and
std::uninitialized_fill_n algorithms to directly perform memcpy/memset
optimizations instead of dispatching to std::copy/std::fill/std::fill_n.
The reasons for this are:
- Use 'if constexpr' to simplify and optimize compilation throughput, so
dispatching to specialized class templates is only needed for C++98
mode.
- Use memcpy instead of memmove, because the conditions on
non-overlapping ranges are stronger for std::uninitialized_copy than
for std::copy. Using memcpy might be a minor optimization.
- No special case for creating a range of one element, which std::copy
needs to deal with (see PR libstdc++/108846). The uninitialized algos
create new objects, which reuses storage and is allowed to clobber
tail padding.
- Relax the conditions for using memcpy/memset, because the C++20 rules
on implicit-lifetime types mean that we can rely on memcpy to begin
lifetimes of trivially copyable types. We don't need to require
trivially default constructible, so don't need to limit the
optimization to trivial types. See PR 68350 for more details.
- Remove the dependency on std::copy and std::fill. This should mean
that stl_uninitialized.h no longer needs to include all of
stl_algobase.h. This isn't quite true yet, because we still use
std::fill in __uninitialized_default and still use std::fill_n in
__uninitialized_default_n. That will be fixed later.
Several tests need changes to the diagnostics matched by dg-error
because we no longer use the __constructible() function that had a
static assert in. Now we just get straightforward errors for attempting
to use a deleted constructor.
Two tests needed more signficant changes to the actual expected results
of executing the tests, because they were checking for old behaviour
which was incorrect according to the standard.
20_util/specialized_algorithms/uninitialized_copy/64476.cc was expecting
std::copy to be used for a call to std::uninitialized_copy involving two
trivially copyable types. That was incorrect behaviour, because a
non-trivial constructor should have been used, but using std::copy used
trivial default initialization followed by assignment.
20_util/specialized_algorithms/uninitialized_fill_n/sizes.cc was testing
the behaviour with a non-integral Size passed to uninitialized_fill_n,
but I wrote the test looking at the requirements of uninitialized_copy_n
which are not the same as uninitialized_fill_n. The former uses --n and
tests n > 0, but the latter just tests n-- (which will never be false
for a floating-point value with a fractional part).
libstdc++-v3/ChangeLog:
PR libstdc++/68350
PR libstdc++/93059
* include/bits/stl_uninitialized.h (__check_constructible)
(_GLIBCXX_USE_ASSIGN_FOR_INIT): Remove.
[C++98] (__unwrappable_niter): New trait.
(__uninitialized_copy<true>): Replace use of std::copy.
(uninitialized_copy): Fix Doxygen comments. Open-code memcpy
optimization for C++11 and later.
(__uninitialized_fill<true>): Replace use of std::fill.
(uninitialized_fill): Fix Doxygen comments. Open-code memset
optimization for C++11 and later.
(__uninitialized_fill_n<true>): Replace use of std::fill_n.
(uninitialized_fill_n): Fix Doxygen comments. Open-code memset
optimization for C++11 and later.
* testsuite/20_util/specialized_algorithms/uninitialized_copy/64476.cc:
Adjust expected behaviour to match what the standard specifies.
* testsuite/20_util/specialized_algorithms/uninitialized_fill_n/sizes.cc:
Likewise.
* testsuite/20_util/specialized_algorithms/uninitialized_copy/1.cc:
Adjust dg-error directives.
* testsuite/20_util/specialized_algorithms/uninitialized_copy/89164.cc:
Likewise.
* testsuite/20_util/specialized_algorithms/uninitialized_copy_n/89164.cc:
Likewise.
* testsuite/20_util/specialized_algorithms/uninitialized_fill/89164.cc:
Likewise.
* testsuite/20_util/specialized_algorithms/uninitialized_fill_n/89164.cc:
Likewise.
* testsuite/23_containers/vector/cons/89164.cc: Likewise.
* testsuite/23_containers/vector/cons/89164_c++17.cc: Likewise.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
This proposal of mine has been approved by LEWG and forwarded to LWG. I
expect it to be voted into the draft without significant changes.
libstdc++-v3/ChangeLog:
* include/bits/version.def (constrained_equality): Bump value.
* include/bits/version.h: Regenerate.
* include/std/expected (operator==): Add constraints and
noexcept specifiers.
* testsuite/20_util/optional/relops/constrained.cc: Adjust
check for feature test macro.
* testsuite/20_util/pair/comparison_operators/constrained.cc:
Likewise.
* testsuite/20_util/tuple/comparison_operators/constrained.cc:
Likewise.
* testsuite/20_util/variant/relops/constrained.cc: Likewise.
* testsuite/20_util/expected/equality_constrained.cc: New test.
libstdc++-v3/ChangeLog:
* testsuite/20_util/duration/io.cc [!__cpp_lib_char8_t]: Define
char8_t as a typedef for unsigned char.
* testsuite/std/format/parse_ctx_neg.cc: Skip for -fno-char8_t.
This change also requires implementing the proposed resolution of LWG
3216 so that std::make_shared and std::allocate_shared still work, and
the proposed resolution of LWG 3891 so that std::expected still works.
libstdc++-v3/ChangeLog:
* include/bits/shared_ptr_base.h: Remove cv-qualifiers from
type managed by _Sp_counted_ptr_inplace, as per LWG 3210.
* include/bits/stl_construct.h: Do not cast away cv-qualifiers
when passing pointer to placement new.
* include/std/expected: Use remove_cv_t for union member, as per
LWG 3891.
* testsuite/20_util/allocator/void.cc: Do not test construction
via const pointer.
The issue was approved at the recent St. Louis meeting, requiring
support for bounded arrays, but only without arguments to initialize the
array elements.
libstdc++-v3/ChangeLog:
* include/bits/stl_construct.h (construct_at): Support array
types (LWG 3436).
* testsuite/20_util/specialized_algorithms/construct_at/array.cc:
New test.
* testsuite/20_util/specialized_algorithms/construct_at/array_neg.cc:
New test.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/initlist-opt1.C: Adjust for different diagnostics
from std::construct_at by adding -fconcepts-diagnostics-depth=2.
Implement Peter Dimov's suggestion for resolving LWG 4118, which is to
use +d.count() so that character types are promoted to an integer type
before formatting them. This didn't have unanimous consensus in the
committee as Howard Hinnant proposed that we should format the rep
consistently with std::format("{}", d.count()) instead. That ends up
being more complicated, because it makes std::formattable a precondition
of operator<< which was not previously the case, and it means that
ios_base::fmtflags from the stream would be ignored because std::format
doesn't use them.
libstdc++-v3/ChangeLog:
PR libstdc++/116755
* include/bits/chrono_io.h (operator<<): Use +d.count() for
duration inserter.
(__formatter_chrono::_M_format): Likewise for %Q format.
* testsuite/20_util/duration/io.cc: Test durations with
character types as reps.
Added by P2985R0 for C++26. This simply exposes the compiler
builtin, and adds the feature-testing macro.
libstdc++-v3/ChangeLog:
* include/bits/version.def: Added the feature-testing macro.
* include/bits/version.h: Regenerated.
* include/std/type_traits: Add support for
std::is_virtual_base_of and std::is_virtual_base_of_v,
implemented in terms of the compiler builtin.
* testsuite/20_util/is_virtual_base_of/value.cc: New test.
Signed-off-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Some of these are due to no longer using #pragma GCC system_header in
libstdc++ headers, some have been failing for longer and weren't
noticed.
libstdc++-v3/ChangeLog:
* include/parallel/algobase.h (search): Use sequential algorithm
for constant evaluation.
* include/parallel/algorithmfwd.h (search): Add
_GLIBCXX20_CONSTEXPR.
* include/parallel/multiway_merge.h: Remove stray semi-colon.
* include/parallel/multiseq_selection.h: Add diagnostic pragmas
for -Wlong-long warning.
* include/parallel/quicksort.h: Likewise.
* include/parallel/random_number.h: Likewise.
* include/parallel/settings.h: Likewise.
* include/parallel/workstealing.h: Replace ++ and -- on volatile
variables.
* testsuite/17_intro/names.cc: Skip names defined by
<tr1/random>.
* testsuite/20_util/pair/dangling_ref.cc: Skip test if Parallel
Mode is enabled.
* testsuite/20_util/tuple/dangling_ref.cc: Likewise.
This fixes two FAILs due to -Wpointer-arith warnings when testing with
c++11 or c++14 dialects.
libstdc++-v3/ChangeLog:
* testsuite/20_util/bind/dangling_ref.cc: Add an additional
dg-warning for -Wreturn-local-addr warning.
* testsuite/30_threads/packaged_task/cons/dangling_ref.cc:
Likewise.
When formatting chrono::duration<signed-integer-type, P>::min() we were
causing undefined behaviour by trying to form the negative of the most
negative value. If we convert negative durations with integer rep to the
corresponding unsigned integer rep then we can safely represent all
values.
libstdc++-v3/ChangeLog:
PR libstdc++/116755
* include/bits/chrono_io.h (formatter<duration<R,P>>::format):
Cast negative integral durations to unsigned rep.
* testsuite/20_util/duration/io.cc: Test the most negative
integer durations.
PR 116529 shows that std::unique_ptr<X&, D> is currently unusable
because the constructor taking std::auto_ptr (which is a non-standard
extension since C++17) tries to form the invalid type X&* during
overload resolution. We can use the `pointer` type in the constructor
constraints, instead of trying to form an invalid type. The
std::auto_ptr constructor can never actually match for the case where
element_type is a reference, so we just need it to produce a
substitution failure instead of being ill-formed.
LWG 4144 might make std::unique_ptr<X&, D> ill-formed, which would
invalidate this new test. We would have to remove this test in that
case. Using `pointer` in the constructor from std::auto_ptr would not be
needed to support the std::unique_ptr<X&, D> case, but would not cause
any harm either.
libstdc++-v3/ChangeLog:
PR libstdc++/116529
* include/bits/unique_ptr.h (unique_ptr(auto_ptr<U>&&)):
Use pointer instead of T*.
* testsuite/20_util/unique_ptr/creation/116529.cc: New test.
We don't need to use std::aligned_storage in std::any. We just need a
POD type of the right size. The void* union member already ensures the
alignment will be correct. Avoiding std::aligned_storage means we don't
need to suppress a -Wdeprecated-declarations warning.
libstdc++-v3/ChangeLog:
* include/experimental/any (experimental::any::_Storage): Use
array of unsigned char instead of deprecated
std::aligned_storage.
* include/std/any (any::_Storage): Likewise.
* testsuite/20_util/any/layout.cc: New test.
This avoids constraint recursion in operator<=> for std::optional.
The resolution was approved in Kona 2022.
libstdc++-v3/ChangeLog:
* include/std/optional (__is_derived_from_optional): New
concept.
(operator<=>): Use __is_derived_from_optional.
* testsuite/20_util/optional/relops/lwg3746.cc: New test.
Using std::is_constructible in the constraints introduces a spurious
dependency on the type being destructible, which should not be required
for constructing with an allocator. The test case shows a case where the
type has a private destructor, which can be destroyed by the allocator,
but std::is_destructible and std::is_constructible are false.
Similarly, using is_nothrow_constructible in the noexcept-specifiers
for the construct members of allocator_traits and std::allocator,
__gnu_cxx::__new_allocator, and __gnu_cxx::__malloc_allocator gives the
wrong answer if the type isn't destructible.
We need a new type trait to define those correctly, so that we only
check if the placement new-expression is nothrow after using
is_constructible to check that it would be well-formed.
Instead of just fixing the overly restrictive constraint to check for
placement new, rewrite allocator_traits in terms of 'if constexpr' using
variable templates and the detection idiom.
Although we can use 'if constexpr' and variable templates in C++11 with
appropriate uses of diagnostic pragmas, we can't have constexpr
functions with multiple return statements. This means that in C++11 mode
the _S_nothrow_construct and _S_nothrow_destroy helpers used for
noexcept-specifiers still need to be overlaods using enable_if. Nearly
everything else can be simplified to reduce overload resolution and
enable_if checks.
libstdc++-v3/ChangeLog:
PR libstdc++/108619
* include/bits/alloc_traits.h (__allocator_traits_base): Add
variable templates for detecting which allocator operations are
supported.
(allocator_traits): Use 'if constexpr' instead of dispatching to
overloads constrained with enable_if.
(allocator_traits<allocator<T>>::construct): Use Construct if
construct_at is not supported. Use
__is_nothrow_new_constructible for noexcept-specifier.
(allocator_traits<allocator<void>>::construct): Use
__is_nothrow_new_constructible for noexcept-specifier.
* include/bits/new_allocator.h (construct): Likewise.
* include/ext/malloc_allocator.h (construct): Likewise.
* include/std/type_traits (__is_nothrow_new_constructible): New
variable template.
* testsuite/20_util/allocator/89510.cc: Adjust expected results.
* testsuite/ext/malloc_allocator/89510.cc: Likewise.
* testsuite/ext/new_allocator/89510.cc: Likewise.
* testsuite/20_util/allocator_traits/members/108619.cc: New test.
The standard says this constructor should be private. LWG 4141 proposes
to remove it entirely. We still need it, but it doesn't need to be
public.
For std::bitset the default constructor is already private (and never
even defined) but there's a non-standard constructor that's public, but
doesn't need to be.
libstdc++-v3/ChangeLog:
PR libstdc++/115098
* include/bits/stl_bvector.h (_Bit_reference): Make default
constructor private. Declare vector and bit iterators as
friends.
* include/std/bitset (bitset::reference): Make constructor and
data members private.
* testsuite/20_util/bitset/115098.cc: New test.
* testsuite/23_containers/vector/bool/115098.cc: New test.
libstdc++-v3/ChangeLog:
PR libstdc++/116381
* include/std/variant (variant): Fix conditions for
static_assert to match the spec.
* testsuite/20_util/variant/types_neg.cc: New test.
Inspired by https://github.com/llvm/llvm-project/issues/101614 this
inverts the relationship between forward_like and __like_t so that
forward_like is defined in terms of __like_t and with a concrete return
type. __like_t in turn is defined via partial specializations that
pattern match on the const- and reference-ness of T.
This turns out to be more SFINAE friendly and significantly cheaper
to compile than the previous implementation.
libstdc++-v3/ChangeLog:
* include/bits/move.h (__like_impl): New metafunction.
(__like_t): Redefine in terms of __like_impl.
(forward_like): Redefine in terms of __like_t.
* testsuite/20_util/forward_like/2_neg.cc: Don't expect
error outside the immediate context anymore.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>