diff --git a/tools/qfcc/source/expr_call.c b/tools/qfcc/source/expr_call.c index 50f631661..855a9c96e 100644 --- a/tools/qfcc/source/expr_call.c +++ b/tools/qfcc/source/expr_call.c @@ -170,7 +170,7 @@ check_arg_types (const expr_t **arguments, const type_t **arg_types, err = param_mismatch (e, i + 1, fexpr->symbol->name, t, param_type); } - } else { + } else if (!is_reference (param_type)) { if (!type_assignable (param_type, t)) { err = param_mismatch (e, i + 1, fexpr->symbol->name, param_type, t); @@ -236,7 +236,14 @@ build_call_scope (symbol_t *fsym, const expr_t **arguments) } auto psym = new_symbol (p->name); psym->sy_type = sy_expr; - psym->expr = arguments[i]; + auto arg_type = get_type (arguments[i]); + if (is_reference (p->type) && !is_reference (arg_type)) { + psym->expr = address_expr (arguments[i], nullptr); + } else if (!is_reference (p->type) && is_reference (arg_type)) { + psym->expr = pointer_deref (arguments[i]); + } else { + psym->expr = arguments[i]; + } symtab_addsymbol (params, psym); } } diff --git a/tools/qfcc/source/function.c b/tools/qfcc/source/function.c index 8c839a4ed..4e5a361e8 100644 --- a/tools/qfcc/source/function.c +++ b/tools/qfcc/source/function.c @@ -604,19 +604,19 @@ check_type (const type_t *type, callparm_t param, unsigned *cost, bool promote) if (!type) { return false; } - if (type == param.type) { + if (type_same (type, param.type)) { return true; } if (is_reference (type)) { // pass by references is a free conversion, but no promotion - return dereference_type (type) == param.type; + return type_same (dereference_type (type), param.type); } if (is_reference (param.type)) { // dereferencing a reference is free so long as there's no // promotion, otherwise there's the promotion cost param.type = dereference_type (param.type); } - if (type == param.type) { + if (type_same (type, param.type)) { return true; } int ret = obj_types_assignable (type, param.type);