https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92496
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org, | |jason at gcc dot gnu.org --- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Even struct B { constexpr auto operator<=>(const B&) const = default; int value; }; is enough. The reason nothing is reported is that synthetize_method creates it with tf_none: else if (sfk == sfk_comparison) { /* Pass tf_none so the function is just deleted if there's a problem. */ build_comparison_op (fndecl, tf_none); need_body = false; } I've tried to fix the ICE below: --- gcc/cp/method.c.jj 2019-11-12 09:09:33.622815406 +0100 +++ gcc/cp/method.c 2019-11-13 18:41:21.645025060 +0100 @@ -1162,6 +1162,8 @@ common_comparison_type (vec<tree> &comps for (unsigned i = 0; i < comps.length(); ++i) { tree comp = comps[i]; + if (error_operand_p (comp)) + return error_mark_node; tree ctype = TREE_TYPE (comp); comp_cat_tag tag = cat_tag_for (ctype); if (tag < cc_last) @@ -1339,7 +1341,10 @@ build_comparison_op (tree fndecl, tsubst if (code == SPACESHIP_EXPR && is_auto (rettype)) { rettype = common_comparison_type (comps); - apply_deduced_return_type (fndecl, rettype); + if (rettype == error_mark_node) + DECL_DELETED_FN (fndecl) = true; + else + apply_deduced_return_type (fndecl, rettype); } for (unsigned i = 0; i < comps.length(); ++i) { but unfortunately that means no error is reported on the above testcase, maybe_explain_implicit_delete is then called only if something attempts to use the deleted function, so say: struct B { constexpr auto operator<=>(const B&) const = default; int value; }; B a, b; auto c = a <=> b; with: pr92496-3.C:6:16: error: use of deleted function ‘constexpr auto B::operator<=>(const B&) const’ 6 | auto c = a <=> b; | ^ pr92496-3.C:2:18: note: ‘constexpr auto B::operator<=>(const B&) const’ is implicitly deleted because the default definition would be ill-formed: 2 | constexpr auto operator<=>(const B&) const = default; | ^~~~~~~~ pr92496-3.C:2:18: error: ‘strong_ordering’ is not a member of ‘std’ pr92496-3.C:1:1: note: ‘std::strong_ordering’ is defined in header ‘<compare>’; did you forget to ‘#include <compare>’? +++ |+#include <compare> 1 | struct B { pr92496-3.C:2:18: note: forming type of ‘operator<=>’ 2 | constexpr auto operator<=>(const B&) const = default; | ^~~~~~~~