diff --git a/src/cc/backend/codegen.c b/src/cc/backend/codegen.c index 98fe38652..bb8e7b85b 100644 --- a/src/cc/backend/codegen.c +++ b/src/cc/backend/codegen.c @@ -340,7 +340,7 @@ static void gen_return(Stmt *stmt) { if (is_prim_type(val->type)) { int flag = is_unsigned(val->type) ? IRF_UNSIGNED : 0; new_ir_result(fnbe->result_dst, vreg, flag); - } else { + } else if (val->type->kind != TY_VOID) { VReg *retval = fnbe->retval; if (retval != NULL) { gen_memcpy(val->type, retval, vreg); diff --git a/src/cc/frontend/parser.c b/src/cc/frontend/parser.c index 05b48775e..16d629120 100644 --- a/src/cc/frontend/parser.c +++ b/src/cc/frontend/parser.c @@ -443,10 +443,16 @@ static Stmt *parse_return(const Token *tok) { if (rettype->kind != TY_VOID) parse_error(PE_NOFATAL, tok, "`return' required a value"); } else { - if (rettype->kind == TY_VOID) - parse_error(PE_NOFATAL, val->token, "void function `return' a value"); - else + if (rettype->kind == TY_VOID) { + if (val->type->kind == TY_VOID) { + // Allow `return void_fnc();`. + parse_error(PE_WARNING, val->token, "`return' with void value"); + } else { + parse_error(PE_NOFATAL, val->token, "void function `return' a value"); + } + } else { val = make_cast(rettype, val->token, val, false); + } } return new_stmt_return(tok, val);