Skip to content

Commit

Permalink
c++: ambiguous member lookup for rewritten cands [PR113529]
Browse files Browse the repository at this point in the history
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
OK for trunk/13?

-- >8 --

Here we handle the operator expression u < v inconsistently: in a SFINAE
context (such as a requires-expression) we accept the it, and in a
non-SFINAE context we reject it with

  error: request for member 'operator<=>' is ambiguous

as per [class.member.lookup]/6.  This inconsistency is ultimately
because we neglect to propagate error_mark_node after recursing in
add_operator_candidates, fixed like so.

	PR c++/113529

gcc/cp/ChangeLog:

	* call.cc (add_operator_candidates): Propagate error_mark_node
	result after recursing to find rewritten candidates.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp2a/spaceship-sfinae3.C: New test.
  • Loading branch information
Patrick Palka authored and ouuleilei-bot committed Jan 22, 2024
1 parent c2d62cd commit 022e685
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
11 changes: 8 additions & 3 deletions gcc/cp/call.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6896,9 +6896,14 @@ add_operator_candidates (z_candidate **candidates,
{
flags |= LOOKUP_REWRITTEN;
if (rewrite_code != code)
/* Add rewritten candidates in same order. */
add_operator_candidates (candidates, rewrite_code, ERROR_MARK,
arglist, lookups, flags, complain);
{
/* Add rewritten candidates in same order. */
tree r = add_operator_candidates (candidates, rewrite_code,
ERROR_MARK, arglist, lookups,
flags, complain);
if (r == error_mark_node)
return error_mark_node;
}

z_candidate *save_cand = *candidates;

Expand Down
22 changes: 22 additions & 0 deletions gcc/testsuite/g++.dg/cpp2a/spaceship-sfinae3.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// PR c++/113529
// { dg-do compile { target c++20 } }

#include <compare>

struct A {
auto operator<=>(const A&) const = default;
bool operator<(const A&) const;
};
struct B {
auto operator<=>(const B&) const = default;
};
struct C : A, B { };


template<class T>
void f(T u, T v) {
static_assert(!requires { u < v; });
u < v; // { dg-error "request for member 'operator<=>' is ambiguous" }
}

template void f(C, C);

0 comments on commit 022e685

Please sign in to comment.