Age | Commit message (Collapse) | Author | Files | Lines |
|
I noticed a -Wmaybe-uninitialized warning for this function, which turns
out to be correct. If the caller passes a valid std::ios_base::seekdir
value then there's no problem, but if they pass std::seekdir(999) then
we don't initialize the __base variable before adding it to __off.
Rather than initialize it to an arbitrary value, we should return an
error.
Also add [[unlikely]] attributes to the paths that return an error.
libstdc++-v3/ChangeLog:
* include/std/spanstream (basic_spanbuf::seekoff): Return an
error for invalid seekdir values.
|
|
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.
|
|
libstdc++-v3/ChangeLog:
* include/bits/regex.tcc: Fix -Wsign-compare warning.
|
|
libstdc++-v3/ChangeLog:
* include/pstl/parallel_backend_tbb.h (__merge_func): Fix order
of mem-initializers.
|
|
libstdc++-v3/ChangeLog:
* include/bits/hashtable_policy.h (_Local_iterator_base): Fix
-Wsign-compare warnings.
|
|
Because of PR c++/85944 we have several bugs where _GLIBCXX_DEBUG causes
errors for constexpr code. Although Bug 117966 could be fixed by
avoiding redundant debug checks in std::span, and Bug 106212 could be
fixed by avoiding redundant debug checks in std::array, there are many
more cases where similar __glibcxx_requires_valid_range checks fail to
compile and removing the checks everywhere isn't desirable.
This just disables the __gnu_debug::__check_singular(T*) check during
constant evaluation. Attempting to dereference a null pointer will
certainly fail during constant evaluation (if it doesn't fail then it's
a compiler bug and not the library's problem). Disabling this check
during constant evaluation shouldn't do any harm.
libstdc++-v3/ChangeLog:
PR libstdc++/109517
PR libstdc++/109976
* include/debug/helper_functions.h (__valid_range_aux): Treat
all input iterator ranges as valid during constant evaluation.
|
|
As PR c++/106212 shows, the Debug Mode checks cause a compilation error
for equality comparisons involving std::array prvalues in constant
expressions. Those Debug Mode checks are redundant when
comparing two std::array objects, because we already know we have a
valid range. We can also avoid the unnecessary step of using
std::__niter_base to do __normal_iterator unwrapping, which isn't needed
because our std::array iterators are just pointers. Using
std::__equal_aux1 instead of std::equal avoids the redundant checks in
std::equal and std::__equal_aux.
libstdc++-v3/ChangeLog:
PR libstdc++/106212
* include/std/array (operator==): Use std::__equal_aux1 instead
of std::equal.
* testsuite/23_containers/array/comparison_operators/106212.cc:
New test.
|
|
As PR c++/117966 shows, the Debug Mode checks cause a compilation error
for a global constexpr std::span. Those debug checks are redundant when
constructing from an array or a range, because we already know we have a
valid range and we know its size. Instead of delegating to the
std::span(contiguous_iterator, contiguous_iterator) constructor, just
initialize the data members directly.
libstdc++-v3/ChangeLog:
PR libstdc++/117966
* include/std/span (span(T (&)[N])): Do not delegate to
constructor that performs redundant checks.
(span(array<T, N>&), span(const array<T, N>&)): Likewise.
(span(Range&&), span(const span<T, N>&)): Likewise.
* testsuite/23_containers/span/117966.cc: New test.
|
|
This was approved in Wrocław as LWG 3900, so that passing an incorrect
argument intended as an allocator will be ill-formed, instead of
silently ignored.
This also renames the template parameters and function parameters for
the allocators, to align with the names in the standard. I found it too
confusing to have a parameter _Alloc which doesn't correspond to Alloc
in the standard. Rename _Alloc to _Allocator (which the standard calls
Allocator) and rename _Na to _Alloc (which the standard calls Alloc).
libstdc++-v3/ChangeLog:
* include/std/generator (_Promise_alloc): Rename template
parameter. Use __alloc_rebind to rebind allocator.
(_Promise_alloc::operator new): Replace constraints with a
static_assert in the body. Rename allocator parameter.
(_Promise_alloc<void>::_M_allocate): Rename allocator parameter.
Use __alloc_rebind to rebind allocator.
(_Promise_alloc<void>::operator new): Rename allocator
parameter.
* testsuite/24_iterators/range_generators/alloc.cc: New test.
* testsuite/24_iterators/range_generators/lwg3900.cc: New test.
Reviewed-by: Arsen Arsenović <arsen@aarsen.me>
|
|
This was just approved in Wrocław.
libstdc++-v3/ChangeLog:
* include/std/ostream (println): Pass stream's locale to
std::format, as per LWG 4088.
* testsuite/27_io/basic_ostream/print/1.cc: Check std::println
with custom locale. Remove unused brit_punc class.
|
|
Check the __glibcxx_polymorphic_allocator macro instead of just checking
whether __cplusplus > 201703L.
libstdc++-v3/ChangeLog:
* include/bits/memory_resource.h (polymoprhic_allocator): Use
feature test macro for P0339R6 features.
|
|
This reverts r15-6060-ge4a0157c2397c9 so that __is_bitwise_relocatable
depends only on is_trivial. To avoid the deprecation warnings for C++26,
use the __is_trivial built-in directly instead of std::is_trivial.
We need to be sure that the type is trivially copyable, not just
trivially constructible and trivially assignable. Otherwise we get
-Wclass-memaccess diagnostics for e.g. std::vector<std::pair<A*, B*>>.
We could add is_trivially_copyable to the conditions, but this isn't
really an appropriate change for stage 3 anyway (it affects all modes
from C++11 upwards). Just revert to using is_trivial, and we can revisit
the condition for GCC 16.
libstdc++-v3/ChangeLog:
* include/bits/stl_uninitialized.h (__is_bitwise_relocatable):
Revert to depending on is_trivial.
|
|
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).
The rangified uninitialized_* specialized memory algorithms have code
paths where they call the non-uninitialized versions, because the latter
are usually optimized. The detection in these code paths uses is_trivial;
port it away from it towards more specific checks.
The detection for the copy/move algorithms was suspicious: it checked
that the output type was trivial, and that assignment from the input
range reference type was nothrow. If so, the algorithm would copy/move
assign (by calling the ranges::copy/move algorithms) instead of
constructing elements. I think this is off because:
1) the constructor that would be called by the algorithm (which may be
neither a copy or a move constructor) wasn't checked. If that
constructor isn't trivial the caller might detect that we're not
calling it, and that goes against the algorithms' specifications.
2) a nothrow assignment is necessary but not sufficient, as again we
need to check for triviality, or the caller can detect we're calling
an assignment operator we were never meant to be calling from these
algorithms.
Therefore I've amended the respective detections.
libstdc++-v3/ChangeLog:
* include/bits/ranges_uninitialized.h: port some if
constexpr away from is_trivial, and towards more specific
detections instead.
Signed-off-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
|
|
In preparation for the deprecation of is_trivial (P3247R2).
"bitwise relocation" (or "trivial relocation" à la P1144/P2786)
doesn't need the full-fledged notion of triviality, just checking for a
trivial move constructor and a trivial destructor is sufficient.
libstdc++-v3/ChangeLog:
* include/bits/stl_uninitialized.h: Amended the
__is_bitwise_relocatable type trait.
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>
|
|
In preparation for the deprecation of is_trivial (P3247R2), stop using
it from std::string_view. Also, add the same detection to std::string
(described in [strings.general]/2).
libstdc++-v3/ChangeLog:
* include/bits/basic_string.h: Add a static_assert on the
char-like type.
* include/std/string_view: Port away from is_trivial.
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.
|
|
Using a stateful allocator with std::vector would fail in Debug Mode,
because the allocator-extended move constructor tries to swap all the
attached safe iterators, but that uses a non-inline function which isn't
constexpr. We don't actually need to swap any iterators in constant
expressions, because we never attach them to the container in the first
place.
This bug went unnoticed because the tests for constexpr std::vector were
using a stateful allocator with a std::allocator base class, but were
failing to override the inherited is_always_equal trait from
std::allocator. That meant that the allocators took the always-equal
code paths, and didn't try to use the buggy constructor. In C++26 the
std::allocator::is_always_equal trait goes away, and so the tests
changed behaviour, revealing the bug.
libstdc++-v3/ChangeLog:
PR libstdc++/117962
* include/debug/safe_container.h: Make allocator-extended move
constructor a no-op during constant evaluation.
|
|
libstdc++-v3/ChangeLog:
* include/std/format: Fix typo in Doxygen comment.
|
|
The standard says that Compare, Pred and Hash objects should be swapped
as described in [swappable.requirements] which means calling swap
unqualified with std::swap visible to name lookup.
libstdc++-v3/ChangeLog:
PR libstdc++/117921
* include/bits/hashtable_policy.h (_Hash_code_base::_M_swap):
Use ADL swap for Hash members.
(_Hashtable_base::_M_swap): Use ADL swap for _Equal members.
* include/bits/stl_tree.h (_Rb_tree::swap): Use ADL swap for
_Compare members.
* testsuite/23_containers/set/modifiers/swap/adl.cc: New test.
* testsuite/23_containers/unordered_set/modifiers/swap-2.cc: New
test.
|
|
The standard says that std::exclusive_scan can be used to work in
place, i.e. where the output range is the same as the input range. This
means that the first sum cannot be written to the output until after
reading the first input value, otherwise we'll already have overwritten
the first input value.
While writing a new testcase I also realised that the serial version of
std::exclusive_scan uses copy construction for the accumulator variable,
but the standard only requires Cpp17MoveConstructible. We also require
move assignable, which is missing from the standard's requirements, but
we should at least use move construction not copy construction.
A similar problem exists for some other new C++17 numeric algos, but
I'll fix the others in a subsequent commit.
libstdc++-v3/ChangeLog:
PR libstdc++/108236
* include/pstl/glue_numeric_impl.h (exclusive_scan): Pass __init
as rvalue.
* include/pstl/numeric_impl.h (__brick_transform_scan): Do not
write through __result until after reading through __first. Move
__init into return value.
(__pattern_transform_scan): Pass __init as rvalue.
* include/std/numeric (exclusive_scan): Move construct instead
of copy constructing.
* testsuite/26_numerics/exclusive_scan/2.cc: New test.
* testsuite/26_numerics/pstl/numeric_ops/108236.cc: New test.
|
|
Use diagnostic pragmas to allow using `if constexpr` in C++11 mode, so
that we don't need to use tag dispatching.
These helpers could be removed entirely by just using `if constexpr`
directly in the container member functions, but that's a slightly larger
change that can happen later.
It also looks like we could remove the __alloc_on_copy(const Alloc&)
overload, which is unused.
libstdc++-v3/ChangeLog:
* include/bits/alloc_traits.h (__do_alloc_on_copy): Remove.
(__do_alloc_on_move __do_alloc_on_swap): Remove.
(__alloc_on_copy, __alloc_on_move, __alloc_on_swap): Use if
constexpr.
|
|
This takes a very similar approach to the changes for std::list.
libstdc++-v3/ChangeLog:
PR libstdc++/57272
* include/bits/forward_list.h (_GLIBCXX_USE_ALLOC_PTR_FOR_LIST):
Define.
(_Fwd_list_node_base::_M_base_ptr): New member functions.
(_Fwd_list_node::_M_node_ptr): New member function.
(_Fwd_list_iterator, _Fwd_list_const_iterator): Make internal
member functions and data member private. Declare forward_list
and _Fwd_list_base as friends.
(__fwdlist::_Node_base, __fwdlist::_Node, __fwdlist::_Iterator):
New class templates.
(__fwdlist::_Node_traits): New class template.
(_Fwd_list_base): Use _Node_traits to get types. Use _Base_ptr
instad of _Fwd_list_node_base*. Use _M_base_ptr() instead of
taking address of head node.
(forward_list): Likewise.
(_Fwd_list_base::_M_get_node): Do not define for versioned
namespace.
(_Fwd_list_base::_M_put_node): Only convert pointer if needed.
(_Fwd_list_base::_M_create_node): Use __allocate_guarded_obj.
(_Fwd_list_base::_M_destroy_node): New member function.
* include/bits/forward_list.tcc (_Fwd_list_base::_M_insert_after)
(forward_list::_M_splice_after, forward_list::insert_after): Use
const_iterator::_M_const_cast() instead of casting pointers.
(_Fwd_list_base::_M_erase_after): Use _M_destroy_node.
(forward_list::remove, forward_list::remove_if): Only do
downcasts when accessing the value.
(forward_list::sort): Likewise.
* testsuite/23_containers/forward_list/capacity/1.cc: Check
max_size for new node type.
* testsuite/23_containers/forward_list/capacity/node_sizes.cc:
New test.
* testsuite/23_containers/forward_list/requirements/explicit_instantiation/alloc_ptr.cc:
New test.
* testsuite/23_containers/forward_list/requirements/explicit_instantiation/alloc_ptr_ignored.cc:
New test.
|
|
Currently std::list uses raw pointers to connect its nodes, which is
non-conforming. We should use the allocator's pointer type everywhere
that a "pointer" is needed.
Because the existing types like _List_node<T> are part of the ABI now,
we can't change them. To support nodes that are connected by fancy
pointers we need a parallel hierarchy of node types. This change
introduces new class templates parameterized on the allocator's
void_pointer type, __list::_Node_base and __list::_Node_header, and new
class templates parameterized on the allocator's pointer type,
__list::Node, __list::_Iterator. The iterator class template is used for
both iterator and const_iterator. Whether std::list<T, A> should use the
old _List_node<T> or new _list::_Node<A::pointer> type family internally
is controlled by a new __list::_Node_traits traits template.
Because std::pointer_traits and std::__to_address are not defined for
C++98, there is no way to support fancy pointers in C++98. For C++98 the
_Node_traits traits always choose the old _List_node family.
In case anybody is currently using std::list with an allocator that has
a fancy pointer, this change would be an ABI break, because their
std::list instantiations would start to (correctly) use the fancy
pointer type. If the fancy pointer just contains a single pointer and so
has the same size, layout, and object represenation as a raw pointer,
the code might still work (despite being an ODR violation). But if their
fancy pointer has a different representation, they would need to
recompile all their code using that allocator with std::list. Because
std::list will never use fancy pointers in C++98 mode, recompiling
everything to use fancy pointers isn't even possible if mixing C++98 and
C++11 code that uses std::list. To alleviate this problem, compiling
with -D_GLIBCXX_USE_ALLOC_PTR_FOR_LIST=0 will force std::list to have
the old, non-conforming behaviour and use raw pointers internally. For
testing purposes, compiling with -D_GLIBCXX_USE_ALLOC_PTR_FOR_LIST=9001
will force std::list to always use the new node types. This macro is
currently undocumented, which needs to be fixed.
The original _List_node<T> type is trivially constructible and trivially
destructible, but the new __list::_Node<Ptr> type might not be,
depending on the fancy pointer data members in _Node_base. This means
that std::list needs to explicitly construct and destroy the node
object, not just the value that it contains. This commit adds a new
__allocated_obj helper which wraps an __allocated_ptr and additionally
constructs and destroys an object in the allocated storage.
Pretty printers for std::list need to be updated to handle the new node
types. Potentially we just can't pretty print them, because we don't
know how to follow the fancy pointers to traverse the list.
libstdc++-v3/ChangeLog:
PR libstdc++/57272
PR libstdc++/110952
* include/bits/allocated_ptr.h (__allocated_ptr::get): Add
const.
(__allocated_ptr::operator bool, __allocated_ptr::release): New
member functions.
(__allocate_guarded): Add inline.
(__allocated_obj): New class template.
(__allocate_guarded_obj): New function template.
* include/bits/list.tcc (_List_base::_M_clear()): Replace uses
of raw pointers. Use _M_destroy_node.
(list::emplace, list::insert): Likewise.
(list::sort): Adjust check for 0 or 1 wsize. Use template
argument list for _Scratch_list.
* include/bits/stl_list.h (_GLIBCXX_USE_ALLOC_PTR_FOR_LIST):
Define.
(_List_node_base::_Base_ptr): New typedef.
(_List_node_base::_M_base): New member functions.
(_List_node_header::_M_base): Make public and add
using-declaration for base class overload.
(__list::_Node_traits, __list::_Node_base)
(__list::_Node_header, __list::_Node, __list::_Iterator): New
class templates.
(_Scratch_list): Turn class into class template. Use _Base_ptr
typedef instead of _List_node_base*.
(_List_node::_Node_ptr): New typedef.
(_List_node::_M_node_ptr): New member function.
(_List_base, _List_impl): Use _Node_traits to get node types.
(_List_base::_M_put_node): Convert to fancy pointer if needed.
(_List_base::_M_destroy_node): New member function.
(_List_base(_List_base&&, _Node_alloc_type&&)): Use if constexpr
to make function a no-op for fancy pointers.
(_List_base::_S_distance, _List_base::_M_distance)
(_List_base::_M_node_count): Likewise.
(list): Use _Node_traits to get iterator, node and pointer
types.
(list::_M_create_node): Use _Node_ptr typedef instead of _Node*.
Use __allocate_guarded_obj instead of _M_get_node.
(list::end, list::cend, list::empty): Use node header's
_M_base() function instead of taking its address.
(list::swap): Use _Node_traits to get node base type.
(list::_M_create_node, list::_M_insert): Use _Node_ptr instead
of _Node*.
(list::_M_erase): Likewise. Use _M_destroy_node.
(__distance): Overload for __list::_Iterator.
(_Node_base::swap, _Node_base::_M_transfer): Define non-inline
member functions of class templates.
(_Node_header::_M_reverse): Likewise.
* testsuite/23_containers/list/capacity/29134.cc: Check max_size
for allocator of new node type.
* testsuite/23_containers/list/capacity/node_sizes.cc: New test.
* testsuite/23_containers/list/requirements/explicit_instantiation/alloc_ptr.cc:
New test.
* testsuite/23_containers/list/requirements/explicit_instantiation/alloc_ptr_ignored.cc:
New test.
|
|
We can just use the injected-class-name instead of defining a new name.
That seems simpler.
libstdc++-v3/ChangeLog:
* include/bits/stl_list.h (_List_iterator): Remove _Self typedef
and just use injected-class-name instead.
(_List_const_iterator): Likewise.
|
|
Remove some preprocessor conditionals by moving the _M_size member for
the cxx11 ABI into a new base class, which is empty for the gcc4-compat
ABI.
Move some unused members that are only retained for ABI compatibility to
the end of _List_base and add an explanatory comment. Stop using
list::_M_node_count and list::_D_distance and then move them to the end
of std::list with a comment too.
libstdc++-v3/ChangeLog:
* include/bits/stl_list.h (_List_size): New struct.
(_List_node_header): Replace _M_size member with _List_size base
class.
(_List_node_header(_List_node_header&&)): Replace explicit uses
of _M_size with initializing the base.
(_List_node_header::_M_init): Likewise.
(_List_base::_S_distance, _List_base::_M_distance)
(_List_base::_M_node_count): Move to end of class body and add
comment.
(list::_S_distance, list::_M_node_count): Likewise.
(list::size): Inline _M_node_count effects to here.
(list::splice(iterator, list&, iterator, iterator)): Use #if and
call std::distance instead of _S_distance.
|
|
LWG 3778 was approved in November 2022. We already implement all the
changes except for one, which this commit does.
The new test verifies all the changes from LWG 3778, not just the one
implemented here.
libstdc++-v3/ChangeLog:
* include/bits/stl_bvector.h (vector(const allocator_type&)):
Add noexcept, as per LWG 3778.
* testsuite/23_containers/vector/bool/cons/lwg3778.cc: New test.
|
|
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.
|
|
This is another place where we can use 'if constexpr' to replace
dispatching to a specialized class template, improving compile times and
avoiding a function call.
libstdc++-v3/ChangeLog:
* include/bits/stl_construct.h (_Destroy(FwdIter, FwdIter)): Use
'if constexpr' instead of dispatching to a member function of a
class template.
(_Destroy_n(FwdIter, Size)): Likewise.
(_Destroy_aux, _Destroy_n_aux): Only define for C++98.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
|
|
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.
|
|
While we are already in stage3, I wonder if implementing this small paper
wouldn't be useful even for GCC 15, so that we have in the GCC world one
extra year of deprecation of variadic ellipsis without preceding comma.
The paper just deprecates something, I'd hope most of the C++ code in the
wild when it uses variadic functions at all uses the comma before the
ellipsis.
2024-11-30 Jakub Jelinek <jakub@redhat.com>
gcc/c-family/
* c.opt (Wdeprecated-variadic-comma-omission): New option.
* c.opt.urls: Regenerate.
* c-opts.cc (c_common_post_options): Default to
-Wdeprecated-variadic-comma-omission for C++26 or -Wpedantic.
gcc/cp/
* parser.cc: Implement C++26 P3176R1 - The Oxford variadic comma.
(cp_parser_parameter_declaration_clause): Emit
-Wdeprecated-variadic-comma-omission warnings.
gcc/
* doc/invoke.texi (-Wdeprecated-variadic-comma-omission): Document.
gcc/testsuite/
* g++.dg/cpp26/variadic-comma1.C: New test.
* g++.dg/cpp26/variadic-comma2.C: New test.
* g++.dg/cpp26/variadic-comma3.C: New test.
* g++.dg/cpp26/variadic-comma4.C: New test.
* g++.dg/cpp26/variadic-comma5.C: New test.
* g++.dg/cpp1z/fold10.C: Expect a warning for C++26.
* g++.dg/ext/attrib33.C: Likewise.
* g++.dg/cpp1y/lambda-generic-variadic19.C: Likewise.
* g++.dg/cpp2a/lambda-generic10.C: Likewise.
* g++.dg/cpp0x/lambda/lambda-const3.C: Likewise.
* g++.dg/cpp0x/variadic164.C: Likewise.
* g++.dg/cpp0x/variadic17.C: Likewise.
* g++.dg/cpp0x/udlit-args-neg.C: Likewise.
* g++.dg/cpp0x/variadic28.C: Likewise.
* g++.dg/cpp0x/gen-attrs-33.C: Likewise.
* g++.dg/cpp23/explicit-obj-diagnostics3.C: Likewise.
* g++.old-deja/g++.law/operators15.C: Likewise.
* g++.old-deja/g++.mike/p811.C: Likewise.
* g++.old-deja/g++.mike/p12306.C (printf): Add , before ... .
* g++.dg/analyzer/fd-bind-pr107783.C (bind): Likewise.
* g++.dg/cpp0x/vt-65790.C (printf): Likewise.
libstdc++-v3/
* include/std/functional (_Bind_check_arity): Add , before ... .
* include/bits/refwrap.h (_Mem_fn_traits, _Weak_result_type_impl):
Likewise.
* include/tr1/type_traits (is_function): Likewise.
|
|
This benefits from the optimizations in std::_Destroy which avoid doing
any work when using std::allocator.
libstdc++-v3/ChangeLog:
* include/std/stacktrace (basic_stacktrace::_M_impl::_M_resize):
Use std::_Destroy to destroy removed elements.
|
|
libstdc++-v3/ChangeLog:
PR libstdc++/117822
* include/std/stacktrace (stacktrace(stacktrace&&, const A&)):
Fix typo in qualified-id for is_always_equal trait.
* testsuite/19_diagnostics/stacktrace/stacktrace.cc: Test
allocator-extended constructors and allocator propagation.
|
|
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.
|
|
We have a number of comments which are duplicated for C++98 and C++11
overloads, where the signatures are slightly different. Instead of
duplicating the comments that are 90% identical, just use a single
comment that can apply to both. In some cases this means saying "an
iterator" instead of "A const iterator" but that's fine, a
std::list::const_iterator is still an iterator (and a non-const iterator
is a valid argument to those functions because they'll implicitly
convert to const_iterator).
In two cases the @return description just needs to say that it returns
void for C++98 and an iterator otherwise.
libstdc++-v3/ChangeLog:
* include/bits/stl_list.h: Reduce duplication in doxygen
comments.
|
|
Add __builtin_unreachable conditionls to declare value ranges of
basic_string::length(). FIx max_size() to return actual max size
using logic similar to std::vector. Aviod use of size() in empty()
to save some compile time overhead.
As disucced, max_size() change is technically ABI breaking, but
hopefully this does not really matter in practice.
Change of length() breaks empty-loop testcase where we now optimize the
loop only after inlining, so template is updated to check cddce3 instead
of cddce2. This is PR117764.
With these chages we now optimize out unused strings as tested in
string-1.C
libstdc++-v3/ChangeLog:
* include/bits/basic_string.h (basic_string::size(),
basic_string::length(), basic_string::capacity()): Add
__builtin_unreachable to declare value ranges.
(basic_string::empty()): Implement directly
(basic_string::max_size()): Account correctly the terminating 0
and limits implied by ptrdiff_t.
gcc/testsuite/ChangeLog:
* g++.dg/tree-ssa/empty-loop.C: xfail optimization at cddce2 and check
it happens at cddce3.
* g++.dg/tree-ssa/string-1.C: New test.
|
|
libstdc++-v3/ChangeLog:
* include/bits/c++config (__glibcxx_assert): Remove useless
__builtin_expect from constexpr-only assertion. Improve
comments.
|
|
This helps the compiler to split the cold path into a separate clone, so
that the hot path is a smaller function that uses less icache, and the
cold path is only fetched into the icache if actually executed.
libstdc++-v3/ChangeLog:
PR libstdc++/117650
* include/bits/c++config (__glibcxx_assert_fail): Add cold
attribute.
* include/debug/formatter.h (_Error_formatter::_M_error):
Likewise.
|
|
This declares the range adaptor pipe operators a friend of the
_RangeAdaptorClosure base class so that the std module doesn't need to
export them for ADL to find them.
Note that we deliberately don't define these pipe operators as hidden
friends, see r14-3293-g4a6f3676e7dd9e.
libstdc++-v3/ChangeLog:
* include/std/ranges (views::__adaptor::_RangeAdaptorClosure):
Befriend both operator| overloads.
* src/c++23/std.cc.in: Don't export views::__adaptor::operator|.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
|
|
While working on fancy pointer support for the linked lists I noticed
they didn't have any debug assertions. This adds the obvious non-empty
assertions to front() and back().
libstdc++-v3/ChangeLog:
* include/bits/forward_list.h (forward_list::front): Add
non-empty assertions.
* include/bits/stl_list.h (list::front, list::back): Add
non-empty assertions.
|
|
Use diagnostic pragmas to allow using `if constexpr` in C++11 mode, so
that we don't need to use tag dispatching.
The unused member functions are preserved for the purposes of explicit
instantiations. The _M_assign function template can be removed, because
member function templates aren't instantiated by explicit instantiations
anyway.
libstdc++-v3/ChangeLog:
* include/bits/forward_list.h (operator=(forward_list&&)): Use
if constexpr instead of dispatching to _M_move_assign.
(assign(InputIterator, InputIterator)): Use if constexpr instead
of dispatching to _M_assign.
(assign(size_type, const T&)): Use if constexpr instead of
dispatching to _M_assign_n.
(_M_move_assign, _M_assign_n): Do not define for versioned
namespace.
(_M_assign): Remove.
|
|
Use diagnostic pragmas to allow using `if constexpr` in C++11 mode, so
that we don't need to use tag dispatching.
The _M_move_assign overloads that were previously used for tag
dispatching are no longer used, but are retained here (at least for the
default config) so that an explicit instantiation will still define
those members. This ensures that old code which expects an explicit
instantiation in some other translation unit will still link. I'm not
sure if that's really needed, we should probably have a policy about
whether we support explicit instantiations where the declaration and
definition use different versions of the headers.
libstdc++-v3/ChangeLog:
* include/bits/stl_list.h (operator=(list&&)): Use if constexpr
instead of dispatching to _M_move_assign.
(_M_move_assign): Do not define for versioned namespace.
|
|
Looking into reason why we still do throw_bad_alloc in clang binary I noticed
that quite few calls come from deque::_M_reallocate_map. This patch adds
unreachable to limit the size of realloc_map. _M_reallocate_map is called only
if new size is smaller then max_size. map is an array holding pointers to
entries of fixed size.
Since rellocation is done by doubling the map size, I think the maximal size of
map allocated is max_size / deque_buf_size rounded up times two. This should
be also safe for overflows since we have extra bit.
map size is always at least 8. Theoretically this computation may be wrong for
very large T, but in that case callers should never reallocate.
On the testcase I get:
jh@shroud:~> ~/trunk-install-new4/bin/g++ -O2 dq.C -c ; size -A dq.o | grep text
.text 284 0
.text._ZNSt5dequeIiSaIiEE17_M_reallocate_mapEmb 485 0
.text.unlikely 10 0
jh@shroud:~> ~/trunk-install-new5/bin/g++ -O2 dq.C -c ; size -A dq.o | grep text
.text 284 0
.text._ZNSt5dequeIiSaIiEE17_M_reallocate_mapEmb 465 0
.text.unlikely 10 0
so this saves about 20 bytes of rellocate_map, which I think is worthwhile.
Curiously enough gcc14 does:
jh@shroud:~> g++ -O2 dq.C -c ; size -A dq.o | grep text
.text 604 0
.text.unlikely 10 0
which is 145 bytes smaller. Obvoius difference is that _M_reallocate_map gets inlined.
Compiling gcc14 preprocessed file with trunk gives:
jh@shroud:~> g++ -O2 dq.C -S ; size -A dq.o | grep text
.text 762 0
.text.unlikely 10 0
So inlining is due to changes at libstdc++ side, but code size growth is due to
something else.
For clang this reduced number of thris_bad_new_array_length from 121 to 61.
libstdc++-v3/ChangeLog:
* include/bits/deque.tcc (std::deque::_M_reallocate_map): Add
__builtin_unreachable check to declare that maps are not very large.
* include/bits/stl_deque.h (std::deque::size): Add __builtin_unreachable
to check for maximal size of map.
gcc/testsuite/ChangeLog:
* g++.dg/tree-ssa/deque-1.C: New test.
* g++.dg/tree-ssa/deque-2.C: New test.
|
|
As an extension, this adds conditional noexcept to std::begin, std::end,
and std::ssize.
libstdc++-v3/ChangeLog:
* include/bits/range_access.h (begin, end, ssize): Add
conditional noexcept.
* testsuite/18_support/initializer_list/range_access.cc: Check
results and noexcept-specifier for std::begin and std::end.
* testsuite/24_iterators/headers/iterator/range_access_c++11.cc:
Check for conditional noexcept on std::begin and std::end.
* testsuite/24_iterators/headers/iterator/range_access_c++14.cc:
Likewise.
* testsuite/24_iterators/headers/iterator/range_access_c++17.cc:
Likewise.
* testsuite/24_iterators/range_access/range_access.cc: Check
conditional noexcept is correct.
* testsuite/24_iterators/range_access/range_access_cpp17.cc:
Check std::size, std::empty and std::data.
* testsuite/24_iterators/range_access/range_access_cpp20.cc:
Check conditional noexcept on std::ssize.
|
|
Use Markdown backticks to format comments, instead of Doxygen @c and @a
commands.
libstdc++-v3/ChangeLog:
* include/bits/forward_list.h: Use Markdown in Doxygen comments.
|
|
François noticed that the "wrong" type is used in the return type for a
std::set member function template.
The iterator for our std::set is the same type as const_iterator,
so this doesn't actually matter. But it's clearer if the return type
matches the type used in the function body.
libstdc++-v3/ChangeLog:
* include/bits/stl_set.h (set::find): Use const_iterator in
return type, not iterator.
|
|
The __is_key_type specialization that matches a pair<key_type, T>
argument is intended for std::unordered_map, not for
std::unordered_set<std::pair<K,T>>.
This uses a pair<const Args&...> as the template argument for
__is_key_type, so that it won't match a set's key_type.
libstdc++-v3/ChangeLog:
PR libstdc++/117686
* include/bits/hashtable.h (_Hashtable::_M_emplace_uniq):
Adjust usage of __is_key_type to avoid false positive.
* testsuite/23_containers/unordered_set/insert/117686.cc:
New test.
|
|
François pointed out that static_cast<__node_ptr>(&_M_before_begin) is
invalid, because _M_before_begin is only a node-base not a node.
Refactor the new merge overloads to only cast when we know we have a
valid node.
He also pointed out some optimizations to allow reusing hash codes that
might be cached in the node. The _M_src_hash_code function already has
the right logic to decide when a cached hash code can be reused by a
different _Hashtable object.
libstdc++-v3/ChangeLog:
* include/bits/hashtable.h (_Hashtable::_M_src_hash_code):
Improve comments.
(_Hashtable::_M_merge_unique(_Hashtable&)): Use pointer_traits
to get before-begin pointer. Only use static_cast on valid
nodes, not the before-begin pointer. Reuse a hash code cached in
the node when possible.
(_Hashtable::_M_merge_multi(_Hashtable&)): Likewise.
Reviewed-by: François Dumont <fdumont@gcc.gnu.org>
|