https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118874
--- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> --- That check_return_expr call in /* Without a relevant location, bad conversions in check_return_expr result in unusable diagnostics, since there is not even a mention of the relevant function. Here we carry out the first part of finish_return_expr(). */ input_location = fn_start; r = check_return_expr (get_ro, &no_warning, &dangling); input_location = UNKNOWN_LOCATION; gcc_checking_assert (!dangling); actually calls want_nrvo_p and that returns false. But guess check_return_expr isn't expecting first argument like TARGET_EXPR, normal user code would return some VAR_DECL, not a TARGET_EXPR. So perhaps add before that call something like if (!aggregate_return_p (fn_return_type, current_function_decl)) { tree var = build_local_temp (fn_return_type); // Perhaps pushdecl it or else arrange it to be in BLOCK_VARS? // Emit INIT_EXPR for it from get_ro. get_ro = var; } so that you initialize the temp var instead of RESULT_DECL directly?