diff options
author | Jason Merrill <jason@redhat.com> | 2022-11-04 15:22:45 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2022-11-07 14:54:04 -1000 |
commit | 431be04b8b6e31d950ddab340ed866d197d23d4d (patch) | |
tree | e0d29df251d9de1334b46cd96cd350e8534510e4 /gcc/cp/pt.cc | |
parent | c838119946c9f75f1e42f4320275355822cc86fc (diff) | |
download | gcc-431be04b8b6e31d950ddab340ed866d197d23d4d.zip gcc-431be04b8b6e31d950ddab340ed866d197d23d4d.tar.gz gcc-431be04b8b6e31d950ddab340ed866d197d23d4d.tar.bz2 |
c++: implement P2468R2, the equality operator you are looking for
This paper is resolving the problem of well-formed C++17 code becoming
ambiguous in C++20 due to asymmetrical operator== being compared with itself
in reverse. I had previously implemented a tiebreaker such that if the two
candidates were functions with the same parameter types, we would prefer the
non-reversed candidate. But the committee went with a different approach:
if there's an operator!= with the same parameter types as the operator==,
don't consider the reversed form of the ==.
So this patch implements that, and changes my old tiebreaker to give a
pedwarn if it is used. I also noticed that we were giving duplicate errors
for some testcases, and fixed the tourney logic to avoid that.
As a result, a lot of tests of the form
struct A { bool operator==(const A&); };
need to be fixed to add a const function-cv-qualifier, e.g.
struct A { bool operator==(const A&) const; };
The committee thought such code ought to be fixed, so breaking it was fine.
18_support/comparisons/algorithms/fallback.cc also breaks with this patch,
because of the similarly asymmetrical
bool operator==(const S&, S&) { return true; }
As a result, some of the asserts need to be reversed.
The H test in spaceship-eq15.C is specified in the standard to be
well-formed because the op!= in the inline namespace is not found by the
search, but that seems wrong to me. I've implemented that behavior, but
disabled it for now; if we decide that is the way we want to go, we can just
remove the "0 &&" in add_candidates to enable it.
Co-authored-by: Jakub Jelinek <jakub@redhat.com>
gcc/cp/ChangeLog:
* cp-tree.h (fns_correspond): Declare.
* decl.cc (fns_correspond): New.
* call.cc (add_candidates): Look for op!= matching op==.
(joust): Complain about non-standard reversed tiebreaker.
(tourney): Fix champ_compared_to_predecessor logic.
(build_new_op): Don't complain about error_mark_node not having
'bool' type.
* pt.cc (tsubst_copy_and_build): Don't try to be permissive
when seen_error().
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/spaceship-eq15.C: New test.
* g++.dg/cpp0x/defaulted3.C: Add const.
* g++.dg/cpp2a/bit-cast7.C: Add const.
* g++.dg/cpp2a/spaceship-rewrite1.C: Expect error.
* g++.dg/cpp2a/spaceship-rewrite5.C: Expect error.
* g++.old-deja/g++.jason/byval2.C: Expect error.
* g++.old-deja/g++.other/overload13.C: Add const.
libstdc++-v3/ChangeLog:
* testsuite/18_support/comparisons/algorithms/fallback.cc: Adjust
asserts.
Diffstat (limited to 'gcc/cp/pt.cc')
-rw-r--r-- | gcc/cp/pt.cc | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index c3fc56a..57917de 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -20937,8 +20937,9 @@ tsubst_copy_and_build (tree t, /* In a lambda fn, we have to be careful to not introduce new this captures. Legacy code can't be using lambdas anyway, so it's ok to be - stricter. Be strict with C++20 template-id ADL too. */ - bool strict = in_lambda || template_id_p; + stricter. Be strict with C++20 template-id ADL too. + And be strict if we're already failing anyway. */ + bool strict = in_lambda || template_id_p || seen_error(); bool diag = true; if (strict) error_at (cp_expr_loc_or_input_loc (t), |