[qfcc] Record alias-free type in function_t

This eases type unaliasing on functions a little.

Still more to to go, but this fixes a really hair-pulling bug: linux's
heap randomiser was making the typedef test fail randomly whenever
typedef.qfo was compiled.
This commit is contained in:
Bill Currie 2020-03-28 13:38:26 +09:00
parent 1eef2a8b5e
commit 8479cad8a8
3 changed files with 17 additions and 10 deletions

View file

@ -51,7 +51,7 @@ typedef struct overloaded_function_s {
const char *name; ///< source level name of function const char *name; ///< source level name of function
const char *full_name; ///< progs name of function, with type const char *full_name; ///< progs name of function, with type
///< encoding ///< encoding
struct type_s *type; ///< type of this function const struct type_s *type; ///< type of this function
int overloaded; ///< is this function overloaded int overloaded; ///< is this function overloaded
string_t file; ///< source file of the function string_t file; ///< source file of the function
int line; ///< source line of this function int line; ///< source line of this function
@ -68,6 +68,7 @@ typedef struct function_s {
int local_defs; int local_defs;
string_t s_file; ///< source file with definition string_t s_file; ///< source file with definition
string_t s_name; ///< name of function in output string_t s_name; ///< name of function in output
const struct type_s *type; ///< function's type without aliases
int temp_num; ///< number for next temp var int temp_num; ///< number for next temp var
struct def_s *temp_defs[4]; ///< freed temp vars (by size) struct def_s *temp_defs[4]; ///< freed temp vars (by size)
struct def_s *def; ///< output def holding function number struct def_s *def; ///< output def holding function number

View file

@ -2032,8 +2032,7 @@ expr_t *
return_expr (function_t *f, expr_t *e) return_expr (function_t *f, expr_t *e)
{ {
const type_t *t; const type_t *t;
const type_t *func_type = unalias_type (f->sym->type); const type_t *ret_type = unalias_type (f->type->t.func.type);
const type_t *ret_type = unalias_type (func_type->t.func.type);
if (!e) { if (!e) {
if (!is_void(ret_type)) { if (!is_void(ret_type)) {

View file

@ -251,7 +251,7 @@ get_function (const char *name, const type_t *type, int overload, int create)
func = Hash_Find (overloaded_functions, full_name); func = Hash_Find (overloaded_functions, full_name);
if (func) { if (func) {
if (unalias_type (func->type) != type) { if (func->type != type) {
error (0, "can't overload on return types"); error (0, "can't overload on return types");
return func; return func;
} }
@ -277,7 +277,7 @@ get_function (const char *name, const type_t *type, int overload, int create)
func = calloc (1, sizeof (overloaded_function_t)); func = calloc (1, sizeof (overloaded_function_t));
func->name = name; func->name = name;
func->full_name = full_name; func->full_name = full_name;
func->type = (type_t *) type; //FIXME cast func->type = type;
func->overloaded = overload; func->overloaded = overload;
func->file = pr.source_file; func->file = pr.source_file;
func->line = pr.source_line; func->line = pr.source_line;
@ -302,7 +302,7 @@ function_symbol (symbol_t *sym, int overload, int create)
if ((!s || s->table != current_symtab) && create) { if ((!s || s->table != current_symtab) && create) {
s = new_symbol (name); s = new_symbol (name);
s->sy_type = sy_func; s->sy_type = sy_func;
s->type = sym->type; s->type = (type_t *) unalias_type (sym->type); // FIXME cast
s->params = sym->params; s->params = sym->params;
s->s.func = 0; // function not yet defined s->s.func = 0; // function not yet defined
symtab_addsymbol (current_symtab, s); symtab_addsymbol (current_symtab, s);
@ -316,8 +316,8 @@ func_compare (const void *a, const void *b)
{ {
overloaded_function_t *fa = *(overloaded_function_t **) a; overloaded_function_t *fa = *(overloaded_function_t **) a;
overloaded_function_t *fb = *(overloaded_function_t **) b; overloaded_function_t *fb = *(overloaded_function_t **) b;
type_t *ta = fa->type; const type_t *ta = fa->type;
type_t *tb = fb->type; const type_t *tb = fb->type;
int na = ta->t.func.num_params; int na = ta->t.func.num_params;
int nb = tb->t.func.num_params; int nb = tb->t.func.num_params;
int ret, i; int ret, i;
@ -497,7 +497,13 @@ build_scope (symbol_t *fsym, symtab_t *parent)
symtab->space = defspace_new (ds_virtual); symtab->space = defspace_new (ds_virtual);
current_symtab = symtab; current_symtab = symtab;
if (fsym->type->t.func.num_params < 0) { if (!fsym->s.func) {
internal_error (0, "function %s not defined", fsym->name);
}
if (!is_func (fsym->s.func->type)) {
internal_error (0, "function type %s not a funciton", fsym->name);
}
if (fsym->s.func->type->t.func.num_params < 0) {
args = new_symbol_type (".args", &type_va_list); args = new_symbol_type (".args", &type_va_list);
initialize_def (args, 0, symtab->space, sc_param); initialize_def (args, 0, symtab->space, sc_param);
} }
@ -551,6 +557,7 @@ make_function (symbol_t *sym, const char *nice_name, defspace_t *space,
if (!sym->s.func) { if (!sym->s.func) {
sym->s.func = new_function (sym->name, nice_name); sym->s.func = new_function (sym->name, nice_name);
sym->s.func->sym = sym; sym->s.func->sym = sym;
sym->s.func->type = unalias_type (sym->type);
} }
if (sym->s.func->def && sym->s.func->def->external if (sym->s.func->def && sym->s.func->def->external
&& storage != sc_extern) { && storage != sc_extern) {
@ -615,7 +622,7 @@ begin_function (symbol_t *sym, const char *nicename, symtab_t *parent,
static void static void
build_function (symbol_t *fsym) build_function (symbol_t *fsym)
{ {
const type_t *func_type = unalias_type (fsym->type); const type_t *func_type = fsym->s.func->type;
if (func_type->t.func.num_params > MAX_PARMS) { if (func_type->t.func.num_params > MAX_PARMS) {
error (0, "too many params"); error (0, "too many params");
} }