A call as the immediate operand of decltype is handled differently; we don't create an object of the return type as we do normally. But in the case of a rewritten operator, we're adding another call as a wrapper, so the inner call doesn't get the special handling.
Tested x86_64-pc-linux-gnu, applying to trunk. * call.c (build_new_op_1): Clear tf_decltype on inner call. --- gcc/cp/call.c | 6 +++++- gcc/testsuite/g++.dg/cpp2a/spaceship-decltype1.C | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/spaceship-decltype1.C diff --git a/gcc/cp/call.c b/gcc/cp/call.c index ce942977f45..48d49b7ec87 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6242,6 +6242,10 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, result = error_mark_node; else { + tsubst_flags_t ocomplain = complain; + if (cand->rewritten ()) + /* We'll wrap this call in another one. */ + ocomplain &= ~tf_decltype; if (cand->reversed ()) { /* We swapped these in add_candidate, swap them back now. */ @@ -6251,7 +6255,7 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, "current function recursively with reversed " "arguments"); } - result = build_over_call (cand, LOOKUP_NORMAL, complain); + result = build_over_call (cand, LOOKUP_NORMAL, ocomplain); } if (trivial_fn_p (cand->fn)) diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-decltype1.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-decltype1.C new file mode 100644 index 00000000000..bc673b2e020 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-decltype1.C @@ -0,0 +1,11 @@ +// PR c++/92560 +// { dg-do compile { target c++2a } } + +#include <compare> + +struct X +{ + friend std::strong_ordering operator<=>(X, X); +} x; + +using T = decltype(x < x); base-commit: b746406f8489fd246aabe01bdf0fc2f319be5b05 -- 2.18.1