From 799d46f83d46ff57a9ee44aa2ff0147c85a2ee12 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 17 Nov 2010 14:45:35 +0900 Subject: [PATCH] Check for incomplete types and better param/return size checking. --- tools/qfcc/source/expr.c | 8 +++++++- tools/qfcc/source/function.c | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index c79f8a99e..72969d1c3 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -1977,6 +1977,12 @@ build_function_call (expr_t *fexpr, type_t *ftype, expr_t *params) for (i = arg_count - 1, e = params; i >= 0; i--, e = e->next) { type_t *t = get_type (e); + if (!type_size (t)) + err = error (e, "type of formal parameter %d is incomplete", + i + 1); + if (type_size (t) > type_size (&type_param)) + err = error (e, "formal parameter %d is too large to be passed by" + " value", i + 1); check_initialized (e); if (ftype->parm_types[i] == &type_float && e->type == ex_integer) { convert_int (e); @@ -2005,7 +2011,7 @@ build_function_call (expr_t *fexpr, type_t *ftype, expr_t *params) && options.code.progsversion == PROG_ID_VERSION) convert_int (e); if (e->type == ex_integer && options.warnings.vararg_integer) - warning (e, "passing integer consant into ... function"); + warning (e, "passing integer constant into ... function"); } arg_types[arg_count - 1 - i] = t; } diff --git a/tools/qfcc/source/function.c b/tools/qfcc/source/function.c index 0f133ee2f..3d4a80f91 100644 --- a/tools/qfcc/source/function.c +++ b/tools/qfcc/source/function.c @@ -146,10 +146,6 @@ parse_params (type_t *type, param_t *parms) } new.num_parms = -(new.num_parms + 1); } else if (p->type) { - if (type_size (p->type) > type_size (&type_param)) { - error (0, "param too large to be passed by value"); - return type; - } new.parm_types[new.num_parms] = p->type; new.num_parms++; } @@ -350,6 +346,34 @@ find_function (expr_t *fexpr, expr_t *params) return fexpr; } +static void +check_function (def_t *func, param_t *params) +{ + param_t *p; + int i; + + if (!type_size (func->type->aux_type)) { + error (0, "return type is an incomplete type"); + func->type->aux_type = &type_void;//FIXME + } + if (type_size (func->type->aux_type) > type_size (&type_param)) { + error (0, "return value too large to be passed by value"); + func->type->aux_type = &type_void;//FIXME + } + for (p = params, i = 0; p; p = p->next, i++) { + if (!p->selector && !p->type && !p->name) + continue; // ellipsis marker + if (!p->type) + continue; // non-param selector + if (!type_size (p->type)) + error (0, "parameter %d (ā€˜%sā€™) has incomplete type", + i + 1, p->name); + if (type_size (p->type) > type_size (&type_param)) + error (0, "param %d (ā€˜%sā€™) is too large to be passed by value", + i + 1, p->name); + } +} + void build_scope (function_t *f, def_t *func, param_t *params) { @@ -359,6 +383,8 @@ build_scope (function_t *f, def_t *func, param_t *params) def_t *args = 0; int parm_ofs[MAX_PARMS]; + check_function (func, params); + f->scope = new_scope (sc_params, new_defspace (), pr.scope); if (func->type->num_parms < 0) {