function return checking

This commit is contained in:
Bill Currie 2001-07-23 02:27:46 +00:00
parent 50fadb6866
commit b8874cab1c
3 changed files with 32 additions and 2 deletions

View file

@ -68,6 +68,7 @@ void print_expr (expr_t *e);
expr_t *binary_expr (int op, expr_t *e1, expr_t *e2); expr_t *binary_expr (int op, expr_t *e1, expr_t *e2);
expr_t *unary_expr (int op, expr_t *e); expr_t *unary_expr (int op, expr_t *e);
expr_t *function_expr (expr_t *e1, expr_t *e2); expr_t *function_expr (expr_t *e1, expr_t *e2);
expr_t *return_expr (function_t *f, expr_t *e);
def_t *emit_statement (int line, opcode_t *op, def_t *var_a, def_t *var_b, def_t *var_c); def_t *emit_statement (int line, opcode_t *op, def_t *var_a, def_t *var_b, def_t *var_c);
void emit_expr (expr_t *e); void emit_expr (expr_t *e);

View file

@ -917,6 +917,35 @@ function_expr (expr_t *e1, expr_t *e2)
return e; return e;
} }
expr_t *
return_expr (function_t *f, expr_t *e)
{
if (!e) {
if (f->def->type->aux_type != &type_void)
return error (e, "return from non-void function without a value");
} else {
type_t *t;
if (f->def->type->aux_type == &type_void)
return error (e, "returning a value for a void function");
if (e->type == ex_expr) {
t = e->e.expr.type;
} else if (e->type == ex_def) {
t = e->e.def->type;
} else {
if (f->def->type->aux_type == &type_float
&& e->type == ex_integer) {
e->type = ex_float;
e->e.float_val = e->e.integer_val;
}
t = types[get_type (e)];
}
if (f->def->type->aux_type != t)
return error (e, "type mismatch for return value of %s",
e->e.def->name);
}
return new_unary_expr ('r', e);
}
def_t * def_t *
emit_statement (int sline, opcode_t *op, def_t *var_a, def_t *var_b, def_t *var_c) emit_statement (int sline, opcode_t *op, def_t *var_a, def_t *var_b, def_t *var_c)
{ {

View file

@ -317,11 +317,11 @@ statement
| statement_block { $$ = $1; } | statement_block { $$ = $1; }
| RETURN expr ';' | RETURN expr ';'
{ {
$$ = new_unary_expr ('r', $2); $$ = return_expr (current_func, $2);
} }
| RETURN ';' | RETURN ';'
{ {
$$ = new_unary_expr ('r', 0); $$ = return_expr (current_func, 0);
} }
| WHILE '(' expr ')' statement | WHILE '(' expr ')' statement
{ {