https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93106
Marek Polacek <mpolacek at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |mpolacek at gcc dot gnu.org --- Comment #4 from Marek Polacek <mpolacek at gcc dot gnu.org> --- (In reply to Jason Merrill from comment #3) > Confirmed. check_return_expr can't use convert_for_initialization to test > whether to treat the returned lvalue as an rvalue. Indeed: convert_for_initialization -> perform_implicit_conversion_flags -> convert_like_real will build_temp for the rvalue version of OBJ, so it calls build_special_member_call -> build_new_method_call_1. Here we have three candidates: X::X(X&&) constexpr X::X(const X&) constexpr X::X() the last one is not viable so splice_viable kills it. And tourney selects X::X(X&&) as expected. But we pass it to build_over_call and that will not complain and just return error_mark_node for a DECL_DELETED_FN function. Then the second stage of the two-stage overload resolution succeeds. I guess we need to stop and issue an error when we found a move ctor, but it's deleted (but not if we don't find a move ctor at all). (Came here in the context of PR91212 where this convert_for_initialization selects the wrong overload.)