aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.cc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2022-11-04 15:22:45 -0400
committerJason Merrill <jason@redhat.com>2022-11-07 14:54:04 -1000
commit431be04b8b6e31d950ddab340ed866d197d23d4d (patch)
treee0d29df251d9de1334b46cd96cd350e8534510e4 /gcc/cp/pt.cc
parentc838119946c9f75f1e42f4320275355822cc86fc (diff)
downloadgcc-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.cc5
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),