Commit graph

35 commits

Author SHA1 Message Date
Jakub Jelinek
0c86a66748 libstdc++: _Bfloat16 for <compare>
Jon pointed out that we have TODO: _Bfloat16 in <compare>.
Right now _S_fp_fmt() returns _Binary16 for _Float16, __fp16 as well
as __bf16 and it actually works because we don't have a special handling
of _Binary16.  So, either we could just document that, but I'm a little bit
afraid if HPPA or MIPS don't start supporting _Float16 and/or __bf16.
If they do, we have the
 #if defined __hppa__ || (defined __mips__ && !defined __mips_nan2008)
                  // IEEE 754-1985 allowed the meaning of the quiet/signaling
                  // bit to be reversed. Flip that to give desired ordering.
                  if (__builtin_isnan(__x) && __builtin_isnan(__y))
                    {
                      using _Int = decltype(__ix);

                      constexpr int __nantype = __fmt == _Binary32  ?  22
                                              : __fmt == _Binary64  ?  51
                                              : __fmt == _Binary128 ? 111
                                              : -1;
                      constexpr _Int __bit = _Int(1) << __nantype;
                      __ix ^= __bit;
                      __iy ^= __bit;
                    }
 #endif
code, the only one where we actually care whether something is
_Binary{32,64,128} (elsewhere we just care about the x86 and m68k 80bits
or double double or just floating point type's sizeof) and we'd need
to handle there _Binary16 and/or _Bfloat16.

So this patch uses different enum for it even when it isn't needed right
now, after all _Binary16 isn't needed either and we could just use
_Binary32...

2022-11-02  Jakub Jelinek  <jakub@redhat.com>

	* libsupc++/compare (_Strong_order::_Fp_fmt): Add _Bfloat16.
	(_Strong_order::_Bfloat16): New static data member.
	(_Strong_order::_S_fp_fmt): Return _Bfloat16 for std::bfloat16_t.
2022-11-02 13:35:53 +01:00
Jonathan Wakely
488d268728 libstdc++: Do not use #include inside push visibility scope [PR99871]
libstdc++-v3/ChangeLog:

	PR libstdc++/99871
	* include/bits/specfun.h: Use visibility attribute on namespace,
	instead of pragma push/pop.
	* libsupc++/compare: Likewise.
	* libsupc++/exception: Likewise.
	* libsupc++/exception.h: Likewise.
	* libsupc++/exception_ptr.h: Likewise.
	* libsupc++/initializer_list: Likewise.
	* libsupc++/nested_exception.h: Likewise.
2022-05-06 14:43:39 +01:00
Jonathan Wakely
8bbeffc102 libstdc++: Workaround for missing 'using enum' in Clang 12
Once we no longer care about older compilers without this feature, we
can drop these static data members, so the names don't have to be
visible at class scope.

libstdc++-v3/ChangeLog:

	* libsupc++/compare (_Strong_order) [!__cpp_using_enum]: Add
	static data members for _Fp_fmt enumerators.
2022-03-29 10:06:33 +01:00
Jonathan Wakely
73f3b8a53e libstdc++: Fix std::strong_order to handle NaN on VAX
I mistakenly believed that VAX floats do not support NaN, but with GCC
__builtin_isnan(__builtin_nan("")) is true. That means my previous
change to <compare> is wrong, because it fails to handle NaN.

When std::numeric_limits<floating-point-type>::is_iec559 is false, as on
VAX, the standard only requires an ordering that is consistent with the
ordering observed by comparison operators. With this change the ordering
is -NaN < numbers < +NaN, and there is no support for different NaN bit
patterns (as I'm not even sure if GCC supports any for VAX).

libstdc++-v3/ChangeLog:

	* libsupc++/compare (_Strong_order::_S_fp_cmp) [__vax__]:
	Handle NaN.
2022-03-10 14:25:46 +00:00
Jonathan Wakely
cfaa2fac42 libstdc++: Support VAX floats in std::strong_order
The VAX float and double format does not support NaN, so the
std::partial_ordering returned by <=> will never be 'unordered'. We can
just use the partial_ordering value as the strong_ordering.

libstdc++-v3/ChangeLog:

	* libsupc++/compare (_Strong_ordering::_S_fp_cmp) [__vax__]: Use
	<=> comparison.
2022-03-10 11:49:00 +00:00
Jonathan Wakely
289f65d643 libstdc++: Fix -Wunused-local-typedefs warning in <compare>
libstdc++-v3/ChangeLog:

	* libsupc++/compare (strong_order::_S_fp_cmp): Move typedef
	inside #if condition.
2022-03-04 10:43:29 +00:00
Jonathan Wakely
9805965e35 libstdc++: Implement std::strong_order for floating-point types [PR96526]
This removes a FIXME in <compare>, defining the total order for
floating-point types. I originally opened PR96526 to request a new
compiler built-in to implement this, but now that we have std::bit_cast
it can be done entirely in the library.

The implementation is based on the glibc definitions of totalorder,
totalorderf, totalorderl etc.

I think this works for all the types that satisfy std::floating_point
today, and should also work for the types expected to be added by P1467
except for std::bfloat16_t. It also supports some additional types that
don't currently satisfy std::floating_point, such as __float80, but we
probably do want that to satisfy the concept for non-strict modes.

libstdc++-v3/ChangeLog:

	PR libstdc++/96526
	* libsupc++/compare (strong_order): Add missing support for
	floating-point types.
	* testsuite/18_support/comparisons/algorithms/strong_order_floats.cc:
	New test.
2022-03-03 22:24:45 +00:00
Jakub Jelinek
7adcbafe45 Update copyright years. 2022-01-03 10:42:10 +01:00
Jonathan Wakely
74d14778e7 libstdc++: Define std::__is_constant_evaluated() for internal use
This adds std::__is_constant_evaluated() as a C++11 wrapper for
__builtin_is_constant_evaluated, but just returning false if the
built-in isn't supported by the compiler. This allows us to use it
throughout the library without checking __has_builtin every time.

Some uses in std::vector and std::string can only be constexpr when the
std::is_constant_evaluated() function actually works, so we might as
well guard them with a relevant macro and call that function directly,
rather than the built-in or std::__is_constant_evaluated().

The remaining checks of the __cpp_lib_is_constant_evaluated macro could
now be replaced by checking __cplusplus >= 202002 instead, but there's
no practical difference. We still need some kind of preprocessor check
there anyway.

libstdc++-v3/ChangeLog:

	* doc/doxygen/user.cfg.in (PREDEFINED): Change macro name.
	* include/bits/allocator.h (allocate, deallocate): Use
	std::__is_constant_evaluated() unconditionally, instead of
	checking whether std::is_constant_evaluated() (or the built-in)
	can be used.
	* include/bits/basic_string.h: Check new macro. call
	std::is_constant_evaluated() directly in C++20-only code that is
	guarded by a suitable macro.
	* include/bits/basic_string.tcc: Likewise.
	* include/bits/c++config (__is_constant_evaluated): Define.
	(_GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED): Replace with ...
	(_GLIBCXX_HAVE_IS_CONSTANT_EVALUATED): New macro.
	* include/bits/char_traits.h (char_traits): Replace conditional
	calls to std::is_constant_evaluated with unconditional calls to
	std::__is_constant_evaluated.
	* include/bits/cow_string.h: Use new macro.
	* include/bits/ranges_algobase.h (__copy_or_move): Replace
	conditional calls to std::is_constant_evaluated with unconditional
	calls to std::__is_constant_evaluated.
	(__copy_or_move_backward, __fill_n_fn): Likewise.
	* include/bits/ranges_cmp.h (ranges::less): Likewise.
	* include/bits/stl_algobase.h (lexicographical_compare_three_way):
	Likewise.
	* include/bits/stl_bvector.h: Call std::is_constant_evaluated
	directly in C++20-only code that is guarded by a suitable macro.
	* include/bits/stl_construct.h (_Construct, _Destroy, _Destroy_n):
	Replace is_constant_evaluated with __is_constant_evaluated.
	* include/bits/stl_function.h (greater, less, greater_equal)
	(less_equal): Replace __builtin_is_constant_evaluated and
	__builtin_constant_p with __is_constant_evaluated.
	* include/bits/stl_vector.h: Call std::is_constant_evaluated()
	in C++20-only code.
	* include/debug/helper_functions.h (__check_singular): Use
	__is_constant_evaluated instead of built-in, or remove check
	entirely.
	* include/std/array (operator<=>): Use __is_constant_evaluated
	unconditionally.
	* include/std/bit (__bit_ceil): Likewise.
	* include/std/type_traits (is_constant_evaluated): Define using
	'if consteval' if possible.
	* include/std/version: Use new macro.
	* libsupc++/compare: Use __is_constant_evaluated instead of
	__builtin_is_constant_evaluated.
	* testsuite/23_containers/array/tuple_interface/get_neg.cc:
	Adjust dg-error lines.
2021-12-01 15:00:33 +00:00
Jonathan Wakely
c2a984a357 libstdc++: Also move the [[nodiscard]] attributes in <compare>
Signed-off-by: Jonathan Wakely <jwakely@redhat.com>

libstdc++-v3/ChangeLog:

	* libsupc++/compare (compare_three_way, strong_order)
	(weak_order, partial_order, compare_strong_order_fallback)
	(compare_weak_order_fallback, compare_partial_order_fallback):
	Move nodiscard attributes to correct location.
2021-08-06 13:43:26 +01:00
Jonathan Wakely
8dec72aeb5 libstdc++: Add [[nodiscard]] to <compare>
This adds the [[nodiscard]] attribute to all conversion operators,
comparison operators, call operators and non-member functions in
<compare>. Nothing in this header except constructors has side effects.

Signed-off-by: Jonathan Wakely <jwakely@redhat.com>

libstdc++-v3/ChangeLog:

	* libsupc++/compare (partial_ordering, weak_ordering)
	(strong_ordering, is_eq, is_neq, is_lt, is_lteq, is_gt, is_gteq)
	(compare_three_way, strong_order, weak_order, partial_order)
	(compare_strong_order_fallback, compare_weak_order_fallback)
	(compare_partial_order_fallback, __detail::__synth3way): Add
	nodiscard attribute.
	* testsuite/18_support/comparisons/categories/zero_neg.cc: Add
	-Wno-unused-result to options.
2021-08-05 15:16:58 +01:00
Jonathan Wakely
b76a529c09 libstdc++: Implement LWG 3465 for std::compare_partial_order_fallback [PR101056]
libstdc++-v3/ChangeLog:

	PR libstdc++/101056
	* libsupc++/compare (compare_partial_order_fallback): Add
	constraint using reversed parameter order, as per LWG 3465.
	* testsuite/18_support/comparisons/algorithms/fallback.cc:
	Adjust expected result.
2021-06-14 14:04:45 +01:00
Jonathan Wakely
e2c79b968f libstdc++: Change [cmp.alg] assertions to constraints
This moves the same_as<decay_t<_Tp>, decay_t<_Up>> checks from the
[cmp.alg] function bodies into their constraints.

Also add a test for the compare_xxx_order_fallback algorithms.

libstdc++-v3/ChangeLog:

	* libsupc++/compare (__decayed_same_as): New helper concept.
	(strong_order, weak_order, partial_order): Constrain with new
	concept instead of using static_assert.
	(compare_strong_order_fallback, compare_weak_order_fallback)
	(compare_partial_order_fallback): Likewise. Do not deduce return
	types. Remove redundant if-constexpr checks.
	* testsuite/18_support/comparisons/algorithms/fallback.cc: New test.
2021-06-14 14:04:45 +01:00
Jonathan Wakely
dddd011113 libstdc++: Implement LWG 3530 for concept-constrained comparisons
The proposed resolution for this library issue simplifies the
constraints for compare_three_way, ranges::equal_to, ranges::less etc.
so that they do not work with types which are convertible to pointers
but which fail to meet the usual syntactic requirements for the
comparisons.

This affects the example in PR libstdc++/93628 but doesn't fix the
problem described in that report.

libstdc++-v3/ChangeLog:

	* include/bits/ranges_cmp.h (__eq_builtin_ptr_cmp): Remove.
	(ranges::equal_to, ranges::not_equal_to): Do not constrain
	with __eq_builtin_ptr_cmp.
	(ranges::less, ranges::greater, ranges::less_equal)
	(ranges::greater_equal): Do not constrain with
	__less_builtin_ptr_cmp.
	* libsupc++/compare (compare_three_way): Do not constrain with
	__3way_builtin_ptr_cmp.
	* testsuite/18_support/comparisons/object/builtin-ptr-three-way.cc: Moved to...
	* testsuite/18_support/comparisons/object/lwg3530.cc: ...here.
	* testsuite/20_util/function_objects/range.cmp/lwg3530.cc: New test.
2021-03-10 15:27:06 +00:00
Jakub Jelinek
99dee82307 Update copyright years. 2021-01-04 10:26:59 +01:00
Jonathan Wakely
73a0a21d22 libstdc++: Update __cpp_lib_three_way_comparison macro
With P1614R2 fully implemented (except for the <chrono> types which we
don't support at all) we can define the feature test macro to the new
value.

	* include/std/version (__cpp_lib_three_way_comparison): Update value.
	* libsupc++/compare (__cpp_lib_three_way_comparison): Likewise.
2020-04-20 17:50:10 +01:00
Jonathan Wakely
e1e9e8d7aa libstdc++: Fix constraints on std::compare_three_way
My "simplification" of std::compare_three_way's constraints in commit
f214ffb336 was incorrect, because
std::three_way_comparable_with imposes additional restrictions beyond
the <=> expression being valid.

	* libsupc++/compare (compare_three_way): Fix constraint so that
	BUILTIN-PTR-THREE-WAY does not require three_way_comparable_with.
	* testsuite/18_support/comparisons/object/builtin-ptr-three-way.cc:
	New test.
2020-04-14 21:59:15 +01:00
Jonathan Wakely
597601aa7a libstdc++: Make comparison category comparisons noexcept (PR 94565)
PR libstdc++/94565
	* libsupc++/compare (__unspec): Add noexcept-specifier to constructor.
	* testsuite/18_support/comparisons/categories/94565.cc: New test.
2020-04-14 11:42:04 +01:00
Jonathan Wakely
3fd1c229ad libstdc++: Implement LWG 3324 for [cmp.alg] function objects (LWG 3324)
LWG 3324 changed the [cmp.alg] types to use std::compare_three_way
instead of the <=> operator, but we were still using the old
specification. In order to make the existing tests pass the N::X type
needs to be equality comparable, so that three_way_comparable is
satisfied and compare_three_way can be used.

As part of this change I noticed that the compare_three_way call
operator was unconditionally noexcept, which is incorrect.

	* libsupc++/compare (compare_three_way): Fix noexcept-specifier.
	(strong_order, weak_order, partial_order): Replace uses of <=> with
	compare_three_way function object (LWG 3324).
	* testsuite/18_support/comparisons/algorithms/partial_order.cc: Add
	equality operator so that X satisfies three_way_comparable.
	* testsuite/18_support/comparisons/algorithms/strong_order.cc:
	Likewise.
	* testsuite/18_support/comparisons/algorithms/weak_order.cc: Likewise.
2020-04-09 22:24:57 +01:00
Jonathan Wakely
256f67aa07 libstdc++: Simplify std::three_way_comparable_with (LWG 3360)
This also removes a useless condition that was supposed to be removed by
the P1959R0 changes, but left in when that was implemented.

	* libsupc++/compare (three_way_comparable): Remove always-false check
	that should have been removed with weak_equality (P1959R0).
	(three_way_comparable_with): Likewise. Reorder requirements (LWG 3360).
2020-02-19 21:49:24 +00:00
Jonathan Wakely
0294dc5f4e libstdc++: Simplify std::totally_ordered (LWG 3331)
* include/std/concepts (__detail::__partially_ordered_with): Move here
	from <compare>.
	(totally_ordered, totally_ordered_with): Use __partially_ordered_with
	to simplify definition (LWG 3331).
	* libsupc++/compare (__detail::__partially_ordered_with): Move to
	<concepts>.
2020-02-19 21:40:03 +00:00
Jonathan Wakely
c5e1c1d3ab libstdc++: P1964R2 Wording for boolean-testable
This removes the complicated std::boolean concept, as agreed in Prague.

	* include/bits/ranges_algo.h (__find_fn, __find_first_of_fn)
	(__adjacent_find_fn): Cast result of predicate to bool.
	* include/std/concepts (__boolean): Remove.
	(__detail::__boolean_testable_impl, __detail::__boolean_testable): Add
	new helper concepts.
	(__detail::__weakly_eq_cmp_with, totally_ordered, totally_ordered_with)
	(predicate): Use __boolean_testable instead of boolean.
	* libsupc++/compare (__detail::__partially_ordered, _Synth3way):
	Likewise.
2020-02-17 18:22:05 +00:00
Jonathan Wakely
0d57370c9c libstdc++: Optimize C++20 comparison category types
This reduces the size and alignment of all three comparison category
types to a single byte. The partial_ordering::_M_is_ordered flag is
replaced by the value 0x02 in the _M_value member.

This also optimizes conversion and comparison operators to avoid
conditional branches where possible, by comparing _M_value to constants
or using bitwise operations to correctly handle the unordered state.

	* libsupc++/compare (__cmp_cat::type): Define typedef for underlying
	type of enumerations and comparison category types.
	(__cmp_cat::_Ord, __cmp_cat::_Ncmp): Add underlying type.
	(__cmp_cat::_Ncmp::unordered): Change value to 2.
	(partial_ordering::_M_value, weak_ordering::_M_value)
	(strong_ordering::_M_value): Change type to __cmp_cat::type.
	(partial_ordering::_M_is_ordered): Remove data member.
	(partial_ordering): Use second bit of _M_value for unordered. Adjust
	comparison operators.
	(weak_ordering::operator partial_ordering): Simplify to remove
	branches.
	(operator<=>(unspecified, weak_ordering)): Likewise.
	(strong_ordering::operator partial_ordering): Likewise.
	(strong_ordering::operator weak_ordering): Likewise.
	(operator<=>(unspecified, strong_ordering)): Likewise.
	* testsuite/18_support/comparisons/categories/partialord.cc: New test.
	* testsuite/18_support/comparisons/categories/strongord.cc: New test.
	* testsuite/18_support/comparisons/categories/weakord.cc: New test.
2020-02-07 14:09:03 +00:00
Jonathan Wakely
f214ffb336 libstdc++: Simplify constraints on std::compare_three_way
The __3way_builtin_ptr_cmp concept can use three_way_comparable_with to
check whether <=> is valid. Doing that makes it obvious that the
disjunction on compare_three_way::operator() is redundant, because
the second constraint subsumes the first.

The workaround for PR c++/91073 can also be removed as that bug is fixed
now.

	* libsupc++/compare (__detail::__3way_builtin_ptr_cmp): Use
	three_way_comparable_with.
	(__detail::__3way_cmp_with): Remove workaround for fixed bug.
	(compare_three_way::operator()): Remove redundant constraint from
	requires-clause.
	(__detail::_Synth3way::operator()): Use three_way_comparable_with
	instead of workaround.
	* testsuite/18_support/comparisons/object/93479.cc: Prune extra
	output due to simplified constraints on compare_three_way::operator().
2020-01-29 13:56:49 +00:00
Jonathan Wakely
83b0201035 libstdc++: Make std::compare_three_way check if <=> is valid (PR 93479)
Currently types that cannot be compared using <=> but which are
convertible to pointers will be compared by converting to pointers
first. They should not be comparable.

	PR libstdc++/93479
	* libsupc++/compare (__3way_builtin_ptr_cmp): Require <=> to be valid.
	* testsuite/18_support/comparisons/object/93479.cc: New test.
2020-01-29 13:36:15 +00:00
Jonathan Wakely
482eeff5f1 libstdc++: Simplify construction of comparison category types
The _Eq and _Ord enumerations can be combined into one, reducing the
number of constructors needed for the comparison category types. The
redundant equal enumerator can be removed and equivalent used in its
place. The _Less and _Greater enumerators can be renamed because 'less'
and 'greater' are already reserved names anyway.

	* libsupc++/compare (__cmp_cat::_Eq): Remove enumeration type.
	(__cmp_cat::_Ord::equivalent): Add enumerator.
	(__cmp_cat::_Ord::_Less, __cmp_cat::_Ord::_Greater): Rename to less
	and greater.
	(partial_ordering, weak_ordering, strong_ordering): Remove
	constructors taking __cmp_cat::_Eq parameters. Use renamed
	enumerators.
2020-01-24 17:17:16 +00:00
Jonathan Wakely
f31a99f7c1 libstdc++: Define __cpp_lib_three_way_comparison conditionally
The contents of the <compare> header are not complete unless concepts
are supported, so the feature test macro should depend on the macro for
concepts.

As a result, the std::lexicographical_compare_three_way function will
not be defined unless concepts are supported, so there is no need to
check __cpp_lib_concepts before using concepts in those functions.

	* include/bits/stl_algobase.h (__is_byte_iter, __min_cmp)
	(lexicographical_compare_three_way): Do not depend on
	__cpp_lib_concepts.
	* include/std/version (__cpp_lib_three_way_comparison): Only define
	when __cpp_lib_concepts is defined.
	* libsupc++/compare (__cpp_lib_three_way_comparison): Likewise.

From-SVN: r279896
2020-01-06 12:06:41 +00:00
Jakub Jelinek
8d9254fc8a Update copyright years.
From-SVN: r279813
2020-01-01 12:51:42 +01:00
Jonathan Wakely
d1505d0146 libstdc++: Simplify std::common_comparison_category
* libsupc++/compare (common_comparison_category): Define without using
	concepts and optimise for compilation time.
	(__detail::__cmp_cat_ids): Remove.
	(__detail::__common_cmp_cat): Replace class template and
	specializations with constexpr function.

From-SVN: r279307
2019-12-12 14:35:55 +00:00
Jonathan Wakely
7f397e4519 libstdc++: Implement spaceship for std::pair (P1614R2)
This defines operator<=> as a non-member function template and does not
alter operator==. This contradicts the changes made by P1614R2, which
specify both as hidden friends, but that specification of operator<=> is
broken and the subject of a soon-to-be-published LWG issue.

	* include/bits/stl_pair.h [__cpp_lib_three_way_comparison]
	(operator<=>): Define for C++20.
	* libsupc++/compare (__cmp2way_res_t): Rename to __cmp3way_res_t,
	move into __detail namespace. Do not turn argument types into lvalues.
	(__cmp3way_helper): Rename to __cmp3way_res_impl, move into __detail
	namespace. Constrain with concepts instead of using void_t.
	(compare_three_way_result): Adjust name of base class.
	(compare_three_way_result_t): Use __cmp3way_res_impl directly.
	(__detail::__3way_cmp_with): Add workaround for PR 91073.
	(compare_three_way): Use workaround.
	(__detail::__synth3way, __detail::__synth3way_t): Define new helpers
	implementing synth-three-way and synth-three-way-result semantics.
	* testsuite/20_util/pair/comparison_operators/constexpr_c++20.cc: New
	test.

From-SVN: r278951
2019-12-03 23:57:46 +00:00
Jonathan Wakely
0ff15d21c8 libsupc++: Implement comparison algorithms for C++20
This is incomplete because std::strong_order doesn't support
floating-point types.

The partial_order and weak_order tests use VERIFY instead of
static_assert because of PR 92431.

	* libsupc++/compare (strong_order, weak_order, partial_order)
	(compare_strong_order_fallback, compare_weak_order_fallback)
	(compare_partial_order_fallback): Define customization point objects
	for C++20.
	* testsuite/18_support/comparisons/algorithms/partial_order.cc: New
	test.
	* testsuite/18_support/comparisons/algorithms/strong_order.cc: New
	test.
	* testsuite/18_support/comparisons/algorithms/weak_order.cc: New test.

From-SVN: r278149
2019-11-13 16:26:18 +00:00
Jonathan Wakely
2966952166 libstdc++: define std::common_comparison_category for C++20
* libsupc++/compare (common_comparison_category)
	(common_comparison_category_t): Define for C++20.
	* testsuite/18_support/comparisons/common/1.cc: New test.

From-SVN: r277943
2019-11-08 00:37:08 +00:00
Jason Merrill
4629ea5560 Implement D1959R0, remove weak_equality and strong_equality.
Shortly after I finished implementing the previous semantics, the
committee decided to remove the *_equality comparison categories, because
they were largely obsoleted by the earlier change that separated operator==
from its original dependency on operator<=>.

gcc/cp/
	* method.c (enum comp_cat_tag, comp_cat_info): Remove *_equality.
	(genericize_spaceship, common_comparison_type): Likewise.
	* typeck.c (cp_build_binary_op): Move SPACESHIP_EXPR to be with the
	relational operators, exclude other types no longer supported.
libstdc++-v3/
	* libsupc++/compare: Remove strong_equality and weak_equality.

From-SVN: r277925
2019-11-07 12:06:09 -05:00
Jonathan Wakely
0c92c8627c libstdc++: Add compare_three_way and install <compare> header
* include/Makefile.in: Regenerate.
	* libsupc++/Makefile.in: Regenerate.
	* libsupc++/compare (__3way_builtin_ptr_cmp): Define helper.
	(compare_three_way): Add missing implementation.

From-SVN: r277889
2019-11-06 17:53:38 +00:00
Jason Merrill
b7689b962d Implement C++20 operator<=>.
There are three major pieces to this support: scalar operator<=>,
synthesis of comparison operators, and rewritten/reversed overload
resolution (e.g. a < b becomes 0 > b <=> a).

Unlike other defaulted functions, where we use synthesized_method_walk to
semi-simulate what the definition of the function will be like, this patch
determines the characteristics of a comparison operator by trying to define
it.

My handling of non-dependent rewritten operators in templates can still use
some work: build_min_non_dep_op_overload can't understand the rewrites and
crashes, so I'm avoiding it for now by clearing *overload.  This means we'll
do name lookup again at instantiation time, which can incorrectly mean a
different result.  I'll poke at this more in stage 3.

I'm leaving out a fourth section ("strong structural equality") even though
I've implemented it, because it seems likely to change radically tomorrow.

Thanks to Tim van Deurzen and Jakub for implementing lexing of the <=>
operator, and Jonathan for the initial <compare> header.

gcc/cp/
	* cp-tree.h (struct lang_decl_fn): Add maybe_deleted bitfield.
	(DECL_MAYBE_DELETED): New.
	(enum special_function_kind): Add sfk_comparison.
	(LOOKUP_REWRITTEN, LOOKUP_REVERSED): New.
	* call.c (struct z_candidate): Add rewritten and reversed methods.
	(add_builtin_candidate): Handle SPACESHIP_EXPR.
	(add_builtin_candidates): Likewise.
	(add_candidates): Don't add a reversed candidate if the parms are
	the same.
	(add_operator_candidates): Split out from build_new_op_1.  Handle
	rewritten and reversed candidates.
	(add_candidate): Swap conversions of reversed candidate.
	(build_new_op_1): Swap them back.  Build a second operation for
	rewritten candidates.
	(extract_call_expr): Handle rewritten calls.
	(same_fn_or_template): New.
	(joust): Handle rewritten and reversed candidates.
	* class.c (add_implicitly_declared_members): Add implicit op==.
	(classtype_has_op, classtype_has_defaulted_op): New.
	* constexpr.c (cxx_eval_binary_expression): Handle SPACESHIP_EXPR.
	(cxx_eval_constant_expression, potential_constant_expression_1):
	Likewise.
	* cp-gimplify.c (genericize_spaceship): New.
	(cp_genericize_r): Use it.
	* cp-objcp-common.c (cp_common_init_ts): Handle SPACESHIP_EXPR.
	* decl.c (finish_function): Handle deleted function.
	* decl2.c (grokfield): SET_DECL_FRIEND_CONTEXT on defaulted friend.
	(mark_used): Check DECL_MAYBE_DELETED.  Remove assumption that
	defaulted functions are non-static members.
	* error.c (dump_expr): Handle SPACESHIP_EXPR.
	* method.c (type_has_trivial_fn): False for sfk_comparison.
	(enum comp_cat_tag, struct comp_cat_info_t): New types.
	(comp_cat_cache): New array variable.
	(lookup_comparison_result, lookup_comparison_category)
	(is_cat, cat_tag_for, spaceship_comp_cat)
	(spaceship_type, genericize_spaceship)
	(common_comparison_type, early_check_defaulted_comparison)
	(comp_info, build_comparison_op): New.
	(synthesize_method): Handle sfk_comparison.  Handle deleted.
	(get_defaulted_eh_spec, maybe_explain_implicit_delete)
	(explain_implicit_non_constexpr, implicitly_declare_fn)
	(defaulted_late_check, defaultable_fn_check): Handle sfk_comparison.
	* name-lookup.c (get_std_name_hint): Add comparison categories.
	* tree.c (special_function_p): Add sfk_comparison.
	* typeck.c (cp_build_binary_op): Handle SPACESHIP_EXPR.

2019-11-05  Tim van Deurzen  <tim@kompiler.org>

	Add new tree code for the spaceship operator.
gcc/cp/
	* cp-tree.def: Add new tree code.
	* operators.def: New binary operator.
	* parser.c: Add new token and tree code.
libcpp/
	* cpplib.h: Add spaceship operator for C++.
	* lex.c: Implement conditional lexing of spaceship operator for C++20.

2019-11-05  Jonathan Wakely  <jwakely@redhat.com>

libstdc++-v3/
	* libsupc++/compare: New header.
	* libsupc++/Makefile.am (std_HEADERS): Add compare.
	* include/std/version: Define __cpp_lib_three_way_comparison.
	* include/std/functional: #include <compare>.

From-SVN: r277865
2019-11-05 18:56:18 -05:00