From 8d10b0f4aab448cba66ef135218bdb9d46d3f721 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 13 Mar 2020 09:58:52 +0900 Subject: [PATCH] [qfcc] Support compound initializers for return --- tools/qfcc/source/expr.c | 27 +++++++++++++++++---------- tools/qfcc/source/qc-parse.y | 6 ++---- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 922d47921..44d62a803 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -1930,9 +1930,10 @@ expr_t * return_expr (function_t *f, expr_t *e) { type_t *t; + type_t *ret_type = f->sym->type->t.func.type; if (!e) { - if (f->sym->type->t.func.type != &type_void) { + if (ret_type != &type_void) { if (options.traditional) { if (options.warnings.traditional) warning (e, @@ -1950,25 +1951,31 @@ return_expr (function_t *f, expr_t *e) } } + if (e->type == ex_compound) { + e = expr_file_line (initialized_temp_expr (ret_type, e), e); + } + t = get_type (e); - if (e->type == ex_error) + if (e->type == ex_error) { return e; - if (f->sym->type->t.func.type == &type_void) { + } + if (ret_type == &type_void) { if (!options.traditional) return error (e, "returning a value for a void function"); if (options.warnings.traditional) warning (e, "returning a value for a void function"); } - if (e->type == ex_bool) - e = convert_from_bool (e, f->sym->type->t.func.type); - if (f->sym->type->t.func.type == &type_float && is_integer_val (e)) { + if (e->type == ex_bool) { + e = convert_from_bool (e, ret_type); + } + if (ret_type == &type_float && is_integer_val (e)) { convert_int (e); t = &type_float; } if (t == &type_void) { if (e->type == ex_nil) { - t = f->sym->type->t.func.type; + t = ret_type; convert_nil (e, t); if (e->type == ex_nil) return error (e, "invalid return type for NIL"); @@ -1980,7 +1987,7 @@ return_expr (function_t *f, expr_t *e) //FIXME does anything need to be done here? } } - if (!type_assignable (f->sym->type->t.func.type, t)) { + if (!type_assignable (ret_type, t)) { if (!options.traditional) return error (e, "type mismatch for return value of %s", f->sym->name); @@ -1988,8 +1995,8 @@ return_expr (function_t *f, expr_t *e) warning (e, "type mismatch for return value of %s", f->sym->name); } else { - if (f->sym->type->t.func.type != t) { - e = cast_expr (f->sym->type->t.func.type, e); + if (ret_type != t) { + e = cast_expr (ret_type, e); t = f->sym->type->t.func.type; } } diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index a4ce4c433..9fe7fbbd2 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -1267,10 +1267,8 @@ statement | error ';' { $$ = 0; yyerrok; } | compound_statement { $$ = $1; } | local_def { $$ = $1; } - | RETURN opt_expr ';' - { - $$ = return_expr (current_func, $2); - } + | RETURN opt_expr ';' { $$ = return_expr (current_func, $2); } + | RETURN compound_init ';' { $$ = return_expr (current_func, $2); } | BREAK ';' { $$ = 0;