public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/98842] New: optional's spaceship operations generates wrong code when operator== is not present
@ 2021-01-26 18:09 nunoplopes at sapo dot pt
2021-01-26 18:56 ` [Bug libstdc++/98842] " gcc@nicholas-schwab.de
` (7 more replies)
0 siblings, 8 replies; 9+ messages in thread
From: nunoplopes at sapo dot pt @ 2021-01-26 18:09 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98842
Bug ID: 98842
Summary: optional's spaceship operations generates wrong code
when operator== is not present
Product: gcc
Version: 11.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: nunoplopes at sapo dot pt
Target Milestone: ---
struct expr {
std::strong_ordering operator<=>(const expr &rhs) const;
//bool operator==(const expr &rhs) const;
};
int f() {
return std::is_eq(std::optional<expr>() <=> std::optional<expr>());
//return std::optional<expr>() == std::optional<expr>();
}
Function f() is compiled to 0 like that. But if you uncomment the
expr::operator== line, it returns 1.
https://gcc.godbolt.org/z/fv85eP
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug libstdc++/98842] optional's spaceship operations generates wrong code when operator== is not present
2021-01-26 18:09 [Bug libstdc++/98842] New: optional's spaceship operations generates wrong code when operator== is not present nunoplopes at sapo dot pt
@ 2021-01-26 18:56 ` gcc@nicholas-schwab.de
2021-01-26 21:45 ` gcc@nicholas-schwab.de
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: gcc@nicholas-schwab.de @ 2021-01-26 18:56 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98842
gcc@nicholas-schwab.de changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |gcc@nicholas-schwab.de
--- Comment #1 from gcc@nicholas-schwab.de ---
Three problem lies in the concept three_way_comparable_with. It uses
__detail::__weakly_eq_cmp_with that requires u == t. Due to paper P1185
operator== will not lookup operator<=>. Therefore having only operator<=>
defined does not suffice to fulfill __detail::__weakly_eq_cmp. Hence the first
of these two templates is SFINAE'D out and the second is taken.
template<typename _Tp, three_way_comparable_with<_Tp> _Up>
constexpr compare_three_way_result_t<_Tp, _Up>
operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y)
template<typename _Tp, typename _Up>
constexpr compare_three_way_result_t<_Tp, _Up>
operator<=>(const optional<_Tp>& __x, const _Up& __v)
The second will however compare false whenever the left hand side is empty.
The standard requires that three_way_comparable_with also requires
weakly_equality_comparable. Hence the implementation of this concept is
correct. However this might be a defect in the standard.
Note that the standard also wants three_way_comparable_with<_Tp> for the second
template (http://eel.is/c++draft/optional#comp.with.t-25). So the second
template above is non-confirming. But it seems to me that a comparison between
two optionals then is always ambiguous, so this should be a defect.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug libstdc++/98842] optional's spaceship operations generates wrong code when operator== is not present
2021-01-26 18:09 [Bug libstdc++/98842] New: optional's spaceship operations generates wrong code when operator== is not present nunoplopes at sapo dot pt
2021-01-26 18:56 ` [Bug libstdc++/98842] " gcc@nicholas-schwab.de
@ 2021-01-26 21:45 ` gcc@nicholas-schwab.de
2021-01-26 22:55 ` redi at gcc dot gnu.org
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: gcc@nicholas-schwab.de @ 2021-01-26 21:45 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98842
--- Comment #2 from gcc@nicholas-schwab.de ---
Created attachment 50063
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50063&action=edit
Patch operator<=>
The operator<=>(optional<_Tp>, _Up) is currently underconstrained. cf
http://eel.is/c++draft/optional.comp.with.t#25 . This patch fixes this by
adding the constraint three_way_comparable_with<_Tp> for _Up. Then in the
program that started this bug report
std::optional<expr>{} <=> std::optional<expr>{}
will not compile if operator==(expr, expr) is not declared.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug libstdc++/98842] optional's spaceship operations generates wrong code when operator== is not present
2021-01-26 18:09 [Bug libstdc++/98842] New: optional's spaceship operations generates wrong code when operator== is not present nunoplopes at sapo dot pt
2021-01-26 18:56 ` [Bug libstdc++/98842] " gcc@nicholas-schwab.de
2021-01-26 21:45 ` gcc@nicholas-schwab.de
@ 2021-01-26 22:55 ` redi at gcc dot gnu.org
2021-06-07 14:47 ` cvs-commit at gcc dot gnu.org
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2021-01-26 22:55 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98842
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Ever confirmed|0 |1
Last reconfirmed| |2021-01-26
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug libstdc++/98842] optional's spaceship operations generates wrong code when operator== is not present
2021-01-26 18:09 [Bug libstdc++/98842] New: optional's spaceship operations generates wrong code when operator== is not present nunoplopes at sapo dot pt
` (2 preceding siblings ...)
2021-01-26 22:55 ` redi at gcc dot gnu.org
@ 2021-06-07 14:47 ` cvs-commit at gcc dot gnu.org
2021-06-11 22:25 ` cvs-commit at gcc dot gnu.org
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2021-06-07 14:47 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98842
--- Comment #3 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:
https://gcc.gnu.org/g:adec14811714e22a6c1f7f0199adc05370f0d8b0
commit r12-1260-gadec14811714e22a6c1f7f0199adc05370f0d8b0
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Mon Jun 7 13:02:15 2021 +0100
libstdc++: Constrain three-way comparison for std::optional [PR 98842]
The operator<=>(const optional<T>&, const U&) operator is supposed to be
constrained with three_way_comparable_with<U, T> so that it can only be
used when T and U are weakly-equality-comparable and also three-way
comparable.
Adding that constrain completely breaks std::optional comparisons,
because it causes constraint recursion. To avoid that, an additional
check that U is not a specialization of std::optional is needed. That
appears to be a defect in the standard and should be reported to LWG.
Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:
PR libstdc++/98842
* include/std/optional (operator<=>(const optional<T>& const U&)):
Add missing constraint and add workaround for template
recursion.
* testsuite/20_util/optional/relops/three_way.cc: Check that
type without equality comparison cannot be compared when wrapped
in std::optional.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug libstdc++/98842] optional's spaceship operations generates wrong code when operator== is not present
2021-01-26 18:09 [Bug libstdc++/98842] New: optional's spaceship operations generates wrong code when operator== is not present nunoplopes at sapo dot pt
` (3 preceding siblings ...)
2021-06-07 14:47 ` cvs-commit at gcc dot gnu.org
@ 2021-06-11 22:25 ` cvs-commit at gcc dot gnu.org
2021-07-22 15:34 ` cvs-commit at gcc dot gnu.org
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2021-06-11 22:25 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98842
--- Comment #4 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-11 branch has been updated by Jonathan Wakely
<redi@gcc.gnu.org>:
https://gcc.gnu.org/g:4f11586945fffd0ff808c16f2f341f9e85d83749
commit r11-8559-g4f11586945fffd0ff808c16f2f341f9e85d83749
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Mon Jun 7 13:02:15 2021 +0100
libstdc++: Constrain three-way comparison for std::optional [PR 98842]
The operator<=>(const optional<T>&, const U&) operator is supposed to be
constrained with three_way_comparable_with<U, T> so that it can only be
used when T and U are weakly-equality-comparable and also three-way
comparable.
Adding that constrain completely breaks std::optional comparisons,
because it causes constraint recursion. To avoid that, an additional
check that U is not a specialization of std::optional is needed. That
appears to be a defect in the standard and should be reported to LWG.
Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:
PR libstdc++/98842
* include/std/optional (operator<=>(const optional<T>& const U&)):
Add missing constraint and add workaround for template
recursion.
* testsuite/20_util/optional/relops/three_way.cc: Check that
type without equality comparison cannot be compared when wrapped
in std::optional.
(cherry picked from commit adec14811714e22a6c1f7f0199adc05370f0d8b0)
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug libstdc++/98842] optional's spaceship operations generates wrong code when operator== is not present
2021-01-26 18:09 [Bug libstdc++/98842] New: optional's spaceship operations generates wrong code when operator== is not present nunoplopes at sapo dot pt
` (4 preceding siblings ...)
2021-06-11 22:25 ` cvs-commit at gcc dot gnu.org
@ 2021-07-22 15:34 ` cvs-commit at gcc dot gnu.org
2021-07-22 15:36 ` redi at gcc dot gnu.org
2024-03-28 11:24 ` redi at gcc dot gnu.org
7 siblings, 0 replies; 9+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2021-07-22 15:34 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98842
--- Comment #5 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-10 branch has been updated by Jonathan Wakely
<redi@gcc.gnu.org>:
https://gcc.gnu.org/g:3a415b6a93765f29bffd0582a001bf03c4b93f3c
commit r10-9996-g3a415b6a93765f29bffd0582a001bf03c4b93f3c
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Mon Jun 7 13:02:15 2021 +0100
libstdc++: Constrain three-way comparison for std::optional [PR 98842]
The operator<=>(const optional<T>&, const U&) operator is supposed to be
constrained with three_way_comparable_with<U, T> so that it can only be
used when T and U are weakly-equality-comparable and also three-way
comparable.
Adding that constrain completely breaks std::optional comparisons,
because it causes constraint recursion. To avoid that, an additional
check that U is not a specialization of std::optional is needed. That
appears to be a defect in the standard and should be reported to LWG.
Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:
PR libstdc++/98842
* include/std/optional (operator<=>(const optional<T>& const U&)):
Add missing constraint and add workaround for template
recursion.
* testsuite/20_util/optional/relops/three_way.cc: Check that
type without equality comparison cannot be compared when wrapped
in std::optional.
(cherry picked from commit adec14811714e22a6c1f7f0199adc05370f0d8b0)
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug libstdc++/98842] optional's spaceship operations generates wrong code when operator== is not present
2021-01-26 18:09 [Bug libstdc++/98842] New: optional's spaceship operations generates wrong code when operator== is not present nunoplopes at sapo dot pt
` (5 preceding siblings ...)
2021-07-22 15:34 ` cvs-commit at gcc dot gnu.org
@ 2021-07-22 15:36 ` redi at gcc dot gnu.org
2024-03-28 11:24 ` redi at gcc dot gnu.org
7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2021-07-22 15:36 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98842
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |RESOLVED
Resolution|--- |FIXED
Target Milestone|--- |10.4
--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Fixed for 10.4 and 11.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug libstdc++/98842] optional's spaceship operations generates wrong code when operator== is not present
2021-01-26 18:09 [Bug libstdc++/98842] New: optional's spaceship operations generates wrong code when operator== is not present nunoplopes at sapo dot pt
` (6 preceding siblings ...)
2021-07-22 15:36 ` redi at gcc dot gnu.org
@ 2024-03-28 11:24 ` redi at gcc dot gnu.org
7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2024-03-28 11:24 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98842
--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to GCC Commits from comment #3)
> Adding that constrain completely breaks std::optional comparisons,
> because it causes constraint recursion. To avoid that, an additional
> check that U is not a specialization of std::optional is needed. That
> appears to be a defect in the standard and should be reported to LWG.
For the record, that is https://cplusplus.github.io/LWG/issue3566
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2024-03-28 11:24 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-26 18:09 [Bug libstdc++/98842] New: optional's spaceship operations generates wrong code when operator== is not present nunoplopes at sapo dot pt
2021-01-26 18:56 ` [Bug libstdc++/98842] " gcc@nicholas-schwab.de
2021-01-26 21:45 ` gcc@nicholas-schwab.de
2021-01-26 22:55 ` redi at gcc dot gnu.org
2021-06-07 14:47 ` cvs-commit at gcc dot gnu.org
2021-06-11 22:25 ` cvs-commit at gcc dot gnu.org
2021-07-22 15:34 ` cvs-commit at gcc dot gnu.org
2021-07-22 15:36 ` redi at gcc dot gnu.org
2024-03-28 11:24 ` redi at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).