glibc mallinfo is now deprecated resulting in make check-performance
failure. When glibc => 2.33 prefer mallinfo2.
libstdc++-v3/ChangeLog:
* testsuite/util/testsuite_performance.h (__gnu_test::MallocInfo): New.
(__gnu_test::malloc_info): New, replace mallinfo on current platform
supporting it and use mallinfo2 when glibc >= 2.33.
The check_trait_type function is used for a number of different type
traits that have different requirements on their arguments. For example,
__is_constructible allows arrays of unknown bound even if the array
element is an incomplete type, but __is_aggregate does not, it always
requires the array element type to be complete. Other traits have
different requirements again, e.g. __is_empty allows incomplete unions,
and arrays (of known or unknown bound) of incomplete types.
This alters the check_trait_type function to take an additional KIND
parameter which indicates which set of type trait requirements to check.
As noted in a comment, the requirements for __is_aggregate deviate from
the ones for std::is_aggregate in the standard. It's not necessary for
the elements of an array to be complete types, because arrays are always
aggregates.
The type_has_virtual_destructor change is needed to avoid an ICE.
Previously it could never be called for incomplete union types as they
were (incorrectly) rejected by check_trait_type.
This change causes some additional diagnostics in some libstdc++ tests,
where the front end was not previously complaining about invalid types
that the library assertions diagnosed. We should consider removing the
library assertions from traits where the front end implements the
correct checks now.
PR c++/106838
gcc/cp/ChangeLog:
* class.cc (type_has_virtual_destructor): Return false for
union types.
* semantics.cc (check_trait_type): Add KIND parameter to support
different sets of requirements.
(finish_trait_expr): Pass KIND argument for relevant traits.
gcc/ChangeLog:
* doc/extend.texi (Type Traits): Fix requirements. Document
__is_aggregate and __is_final.
gcc/testsuite/ChangeLog:
* g++.dg/ext/array4.C: Fix invalid use of __is_constructible.
* g++.dg/ext/unary_trait_incomplete.C: Fix tests for traits with
different requirements.
libstdc++-v3/ChangeLog:
* testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc:
Prune additional errors from front-end.
* testsuite/20_util/is_move_constructible/incomplete_neg.cc:
Likewise.
* testsuite/20_util/is_nothrow_swappable/incomplete_neg.cc:
Likewise.
* testsuite/20_util/is_nothrow_swappable_with/incomplete_neg.cc:
Likewise.
* testsuite/20_util/is_swappable_with/incomplete_neg.cc:
Likewise.
This change implements P0528 which requires that padding bits not
participate in atomic compare exchange operations. All arguments to the
generic template are 'sanitized' by the __builtin_clear_padding intrinsic
before they are used in comparisons. This requires that any stores
also sanitize the incoming value.
Co-authored-by: Jakub Jelinek <jakub@redhat.com>
Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Thomas Rodgers <trodgers@redhat.com>
libstdc++-v3/ChangeLog:
* include/bits/atomic_base.h (__atomic_impl::__maybe_has_padding):
New function.
(__atomic_impl::clear_padding): Likewise.
(__atomic_impl::__compare_exchange): Likewise.
(__atomic_impl::compare_exchange_weak): Delegate to
__compare_exchange.
(__atomic_impl::compare_exchange_strong): Likewise.
* include/std/atomic (atomic<T>::atomic(T)): Clear padding when
possible in a constexpr function.
(atomic::store): Clear padding.
(atomic::exchange): Likewise.
(atomic::compare_exchange_weak): Use __compare_exchange.
(atomic::compare_exchange_strong): Likewise.
* testsuite/29_atomics/atomic/compare_exchange_padding.cc: New
test.
* testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc:
New test.
The new proposed resolution for LWG 3629 says that std::error_code and
std::error_condition should only use ADL to find their customization
points. This means we need to use a poison pill to prevent lookup from
finding overloads in the enclosing namespaces.
We can also remove the forward declarations of std::make_error_code and
std::make_error_condition, because they aren't needed now. ADL can find
them anyway (when std is an associated namespace), and unqualified name
lookup will not (and should not) find them.
libstdc++-v3/ChangeLog:
* include/std/system_error (__adl_only::make_error_code): Add
deleted function.
(__adl_only::make_error_condition): Likewise.
(error_code::error_code(ErrorCodeEnum)): Add using-declaration
for deleted function.
(error_condition::error_condition(ErrorConditionEnum)):
Likewise.
* testsuite/19_diagnostics/error_code/cons/lwg3629.cc: New test.
* testsuite/19_diagnostics/error_condition/cons/lwg3629.cc: New test.
This file is missing the GCC Runtime Library Exception text in the
licence header. That is unintentional, and it should have been present.
libstdc++-v3/ChangeLog:
* include/std/barrier: Add missing runtime exception.
Instead of defining is_reference in terms of is_[lr]value_reference,
just define it directly.
libstdc++-v3/ChangeLog:
* include/std/type_traits (is_reference): Make the primary
template derive from false_type. Define two partial
specializations that derive from true_type.
Instead of defining these in terms of a helper class template
and the relatively expensive __remove_cv_t, just declare four
explicit specializations of the main template, one for each choice
of cv-quals.
libstdc++-v3/ChangeLog:
* include/std/type_traits (__is_void_helper): Remove.
(is_void): Make the primary template derive from false_type,
and define four explicit specializations that derive from
true_type.
(__is_null_pointer_helper, is_null_pointer): Likewise.
This change speeds up the simple benchmark below by about 40%.
struct A { virtual ~A() {} };
struct B: A { } b;
A* ap = &b;
void *sink;
int main()
{
for (long i = 0; i < 4000000000L; ++i)
sink = dynamic_cast<B*>(ap);
}
libstdc++-v3/ChangeLog:
* libsupc++/dyncast.cc (__dynamic_cast): Avoid virtual function
call in simple success case.
Now that these internal type traits are (again) class templates, it's
better to derive from the trait's ::type instead of from the trait
itself, for sake of a shallower inheritance chain.
libstdc++-v3/ChangeLog:
* include/std/tuple (tuple::_UseOtherCtor): Use ::type when
deriving from __and_, __or_ or __not_.
* include/std/type_traits (negation): Likewise.
(is_unsigned): Likewise.
(__is_implicitly_default_constructible): Likewise.
(is_trivially_destructible): Likewise.
(__is_nt_invocable_impl): Likewise.
This defines the is_xxx_constructible_v and is_xxx_assignable_v variable
templates by using the built-ins directly. The actual logic for each one
is the same as the corresponding class template, but way using the
variable template doesn't need to instantiate the class template.
This means that the variable templates won't use the static assertions
checking for complete types, cv void or unbounded arrays, but that's OK
because the built-ins check those anyway. We could probably remove the
static assertions from the class templates, and maybe from all type
traits that use a built-in.
libstdc++-v3/ChangeLog:
* include/std/type_traits (is_constructible_v)
(is_default_constructible_v, is_copy_constructible_v)
(is_move_constructible_v): Define using __is_constructible.
(is_assignable_v, is_copy_assignable_v, is_move_assignable_v):
Define using __is_assignable.
(is_trivially_constructible_v)
(is_trivially_default_constructible_v)
(is_trivially_copy_constructible_v)
(is_trivially_move_constructible_v): Define using
__is_trivially_constructible.
(is_trivially_assignable_v, is_trivially_copy_assignable_v)
(is_trivially_move_assignable_v): Define using
__is_trivially_assignable.
(is_nothrow_constructible_v)
(is_nothrow_default_constructible_v)
(is_nothrow_copy_constructible_v)
(is_nothrow_move_constructible_v): Define using
__is_nothrow_constructible.
(is_nothrow_assignable_v, is_nothrow_copy_assignable_v)
(is_nothrow_move_assignable_v): Define using
__is_nothrow_assignable.
r13-2230-g390f94eee1ae69 redefined the internal logical operator traits
__and_, __or_ and __not_ as alias templates that directly resolve to
true_type or false_type. But it turns out using an alias template here
causes the traits to be less lazy than before because we now compute the
logical result immediately upon _specialization_ of the trait, and not
later upon _completion_ of the specialization.
So for example, in
using type = __and_<A, __not_<B>>;
we now compute the conjunction and thus instantiate A even though we're
in a context that doesn't require completion of the __and_. What's
worse is that we also compute the inner negation and thus instantiate B
(for the same reason), independent of the __and_ and the value of A!
Thus the traits are now less lazy and composable than before.
Fortunately, the fix is cheap and straightforward: redefine these traits
as class templates instead of as alias templates so that computation of
the logical result is triggered by completion, not by specialization.
libstdc++-v3/ChangeLog:
* include/std/type_traits (__or_, __and_, __not_): Redefine as a
class template instead of as an alias template.
* testsuite/20_util/logical_traits/requirements/short_circuit.cc:
Add more tests for conjunction and disjunction. Add corresponding
tests for __and_ and __or_.
We only use the __is_referenceable helper in three places now:
add_pointer, add_lvalue_reference, and add_rvalue_reference. But lots of
other traits depend on add_[lr]value_reference, and decay depends on
add_pointer, so removing the instantiation of __is_referenceable helps
compile all those other traits slightly faster.
We can just use void_t<T&> to check for a referenceable type in the
add_[lr]value_reference traits.
Then we can specialize add_pointer for reference types, so that we don't
need to use remove_reference, and then use void_t<T*> for all
non-reference types to detect when we can form a pointer to the type.
libstdc++-v3/ChangeLog:
* include/std/type_traits (__is_referenceable): Remove.
(__add_lvalue_reference_helper, __add_rvalue_reference_helper):
Use __void_t instead of __is_referenceable.
(__add_pointer_helper): Likewise.
(add_pointer): Add partial specializations for reference types.
We can replace some class template helpers with alias templates, which
are cheaper to instantiate.
For example, replace the __is_copy_constructible_impl class template
with an alias template that uses just evaluates the __is_constructible
built-in, using add_lvalue_reference<const T> to get the argument type
in a way that works for non-referenceable types. For a given
specialization of is_copy_constructible this results in the same number
of class templates being instantiated (for the common case of non-void,
non-function types), but the add_lvalue_reference instantiations are not
specific to the is_copy_constructible specialization and so can be
reused by other traits. Previously __is_copy_constructible_impl was a
distinct class template and its specializations were never used for
anything except is_copy_constructible.
With the new definitions of these traits that don't depend on helper
classes, it becomes more practical to optimize the
is_xxx_constructible_v variable templates to avoid instantiations.
Previously doing so would have meant two entirely separate
implementation strategies for these traits.
libstdc++-v3/ChangeLog:
* include/std/type_traits (__is_constructible_impl): Replace
class template with alias template.
(is_default_constructible, is_nothrow_constructible)
(is_nothrow_constructible): Simplify base-specifier.
(__is_copy_constructible_impl, __is_move_constructible_impl)
(__is_nothrow_copy_constructible_impl)
(__is_nothrow_move_constructible_impl): Remove class templates.
(is_copy_constructible, is_move_constructible)
(is_nothrow_constructible, is_nothrow_default_constructible)
(is_nothrow_copy_constructible, is_nothrow_move_constructible):
Adjust base-specifiers to use __is_constructible_impl.
(__is_copy_assignable_impl, __is_move_assignable_impl)
(__is_nt_copy_assignable_impl, __is_nt_move_assignable_impl):
Remove class templates.
(__is_assignable_impl): New alias template.
(is_assignable, is_copy_assignable, is_move_assignable):
Adjust base-specifiers to use new alias template.
(is_nothrow_copy_assignable, is_nothrow_move_assignable):
Adjust base-specifiers to use existing alias template.
(__is_trivially_constructible_impl): New alias template.
(is_trivially_constructible, is_trivially_default_constructible)
(is_trivially_copy_constructible)
(is_trivially_move_constructible): Adjust base-specifiers to use
new alias template.
(__is_trivially_assignable_impl): New alias template.
(is_trivially_assignable, is_trivially_copy_assignable)
(is_trivially_move_assignable): Adjust base-specifier to use
new alias template.
(__add_lval_ref_t, __add_rval_ref_t): New alias templates.
(add_lvalue_reference, add_rvalue_reference): Use new alias
templates.
Define partial specializations of std::decay and its __decay_selector
helper so that remove_reference, is_array and is_function are not
instantiated for every type, and remove_extent is not instantiated for
arrays.
libstdc++-v3/ChangeLog:
* include/std/type_traits (__decay_selector): Add partial
specializations for array types. Only check for function types
when not dealing with an array.
(decay): Add partial specializations for reference types.
This avoids having to instantiate a class template when we can detect
the true cases easily with a partial specialization.
libstdc++-v3/ChangeLog:
* include/std/type_traits (is_lvalue_reference_v)
(is_rvalue_reference_v, is_reference_v, is_const_v)
(is_volatile_v): Define using partial specializations instead
of instantiating class templates.
This avoids having to instantiate a class template that just uses the
same built-in anyway.
None of the corresponding class templates have any type-completeness
static assertions, so we're not losing any diagnostics by using the
built-ins directly.
libstdc++-v3/ChangeLog:
* include/std/type_traits (is_enum_v, is_class_v, is_union_v)
(is_empty_v, is_polymoprhic_v, is_abstract_v, is_final_v)
(is_base_of_v, is_aggregate_v): Use built-in directly instead of
instantiating class template.
PR c++/99968 is fixed since GCC 12.1 so we can remove the workaround.
libstdc++-v3/ChangeLog:
* include/std/type_traits (is_scoped_enum): Remove workaround.
Improve compile times by avoiding unnecessary class template
instantiations.
__is_array_known_bounds and __is_array_unknown_bounds can be defined
without instantiating extent, by providing partial specializations for
the true cases.
std::extent can avoid recursing down through a multidimensional array,
so it stops after providing the result. Previously extent<T[n][m], 0>
would instantiate extent<T[n], -1u> and extent<T, -2u> as well.
std::is_array_v can use partial specializations to avoid instantiating
std::is_array, and similarly for std::rank_v and std::extent_v.
std::is_bounded_array_v and std::is_unbounded_array_v can also use
partial specializations, and then the class templates can be defined in
terms of the variable templates. This makes sense for these traits,
because they are new in C++20 and so the variable templates are always
available, which isn't true in general for C++11 and C++14 traits.
libstdc++-v3/ChangeLog:
* include/std/type_traits (__is_array_known_bounds): Add partial
specialization instead of using std::extent.
(__is_array_unknown_bounds): Likewise.
(extent): Add partial specializations to stop recursion after
the result is found.
(is_array_v): Add partial specializations instead of
instantiating the class template.
(rank_v, extent_v): Likewise.
(is_bounded_array_v, is_unbounded_array_v): Likewise.
(is_bounded_array, is_unbounded_array): Define in terms of the
variable templates.
libstdc++-v3/ChangeLog:
* include/bits/ranges_base.h (__advance_fn::operator()): Add
parentheses in assert condition to avoid -Wparentheses warning.
* include/std/ranges: (take_view::take_view): Uglify 'base'.
(take_while_view::take_while_view): Likewise.
(elements_view::elements_view): Likewise.
(views::_Zip::operator()): Adjust position of [[nodiscard]] for
compatibility with -fconcepts-ts.
(zip_transform_view::_Sentinel): Uglify 'OtherConst'.
(views::_ZipTransform::operator()): Adjust position of
[[nodiscard]] for compatibilty with -fconcepts-ts.
This isn't required by the standard, but there's an LWG issue suggesting
to add it.
Also use __invoke_result instead of result_of, to match the spec in
recent standards.
libstdc++-v3/ChangeLog:
* include/bits/refwrap.h (reference_wrapper::operator()): Add
noexcept-specifier and use __invoke_result instead of result_of.
* testsuite/20_util/reference_wrapper/invoke-noexcept.cc: New test.
libstdc++-v3/ChangeLog:
* include/std/ranges (zip_view::_Iterator::operator<): Remove
as per LWG 3692.
(zip_view::_Iterator::operator>): Likewise.
(zip_view::_Iterator::operator<=): Likewise.
(zip_view::_Iterator::operator>=): Likewise.
(zip_view::_Iterator::operator<=>): Remove three_way_comparable
constraint as per LWG 3692.
(zip_transform_view::_Iterator): Ditto as per LWG 3702.
The internal type-level logical operator traits __and_ and __or_ seem to
have high overhead for a couple of reasons:
1. They are drop-in replacements for std::con/disjunction, which
are rigidly specified to form a type that derives from the first
type argument that caused the overall computation to short-circuit.
In practice this inheritance property seems to be rarely needed;
usually all we care about is the value of the overall result.
2. Their recursive implementations instantiate O(N) class templates
and form an inheritance chain of depth O(N).
This patch gets rid of this inheritance property of __and_ and __or_
(which seems to be unneeded in the library except indirectly by
std::con/disjunction) which allows us to redefine them non-recursively
as alias templates that yield either false_type or true_type via
enable_if_t and partial ordering of a pair of function templates
(alternatively we could use an equivalent partially specialized class
template, but using function templates appears to be slightly more
efficient).
As for std::con/disjunction, it seems we need to keep implementing them
via a recursive class template for sake of the inheritance property.
But instead of using inheritance recursion, use a recursive member
typedef that gets immediately flattened, so that specializations thereof
now have O(1) instead of O(N) inheritance depth.
In passing, redefine __not_ as an alias template for consistency with
__and_ and __or_, and to remove a layer of indirection.
Together these changes have a substantial effect on compile time and
memory usage for code that heavily uses these internal type traits.
For the following example (which tests constructibility between two
compatible 257-element tuple types):
#include <tuple>
#define M(x) x, x
using ty1 = std::tuple<M(M(M(M(M(M(M(M(int)))))))), int>;
using ty2 = std::tuple<M(M(M(M(M(M(M(M(int)))))))), long>;
static_assert(std::is_constructible_v<ty2, ty1>);
memory usage improves ~27% from 440MB to 320MB and compile time improves
~20% from ~2s to ~1.6s (with -std=c++23).
libstdc++-v3/ChangeLog:
* include/std/type_traits (enable_if, __enable_if_t): Define them
earlier.
(__detail::__first_t): Define.
(__detail::__or_fn, __detail::__and_fn): Declare.
(__or_, __and_): Redefine as alias templates in terms of __or_fn
and __and_fn.
(__not_): Redefine as an alias template.
(__detail::__disjunction_impl, __detail::__conjunction_impl):
Define.
(conjuction, disjunction): Redefine in terms of __disjunction_impl
and __conjunction_impl.
This removes the redundant operator=(E) from std::error_code and
std::error_condition. Without that overload, assignment from a custom
type will use the templated constructor to create a temporary and then
use the trivial copy assignment operator. With the overloaded
assignment, we have to check the constraints twice as often, because
that overload and its constraints are checked for simple copy
assignments (including the one in the overloaded assignment operator
itself!)
Also add tests that ADL is used as per LWG 3629.
libstdc++-v3/ChangeLog:
* include/std/system_error (error_code::_Check): New alias
template for constructor SFINAE constraint.
(error_code::error_code(ErrorCodeEnum)): Use it.
(error_code::operator=(ErrorCodeEnum)): Remove.
(error_condition::_Check): New alias template for constraint.
(error_condition::error_condition(ErrorConditionEnum)): Use it.
(error_condition::operator=(ErrorConditionEnum)): Remove.
* testsuite/19_diagnostics/error_code/cons/1.cc: Check
constructor taking user-defined error enum.
* testsuite/19_diagnostics/error_condition/cons/1.cc: Likewise.
Ideally this wouldn't be needed, because eventually these pointers all
get passed to either the basic_string_view(const CharT*) constructor, or
to basic_string_view::find(const CharT*), both of which already have the
attribute. But for that to work requires optimization, so that the null
value gets propagated through the call chain.
Adding it explicitly to each member that requires a non-null pointer
makes the diagnostics more reliable even without optimization. It's
better to give a diagnostic earlier anyway, at the actual problematic
call in the user's code.
libstdc++-v3/ChangeLog:
* include/bits/basic_string.h (starts_with, ends_with, contains):
Add nonnull attribute.
* include/bits/cow_string.h (starts_with, ends_with, contains):
Likewise.
* include/std/string_view (starts_with, ends_with, contains):
Likewise.
* testsuite/21_strings/basic_string/operations/contains/nonnull.cc
* testsuite/21_strings/basic_string/operations/ends_with/nonnull.cc
* testsuite/21_strings/basic_string/operations/starts_with/nonnull.cc
* testsuite/21_strings/basic_string_view/operations/contains/nonnull.cc
* testsuite/21_strings/basic_string_view/operations/ends_with/nonnull.cc
* testsuite/21_strings/basic_string_view/operations/starts_with/nonnull.cc