[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 *full_name; ///< progs name of function, with type
///< encoding
struct type_s *type; ///< type of this function
const struct type_s *type; ///< type of this function
int overloaded; ///< is this function overloaded
string_t file; ///< source file of the function
int line; ///< source line of this function
@ -68,6 +68,7 @@ typedef struct function_s {
int local_defs;
string_t s_file; ///< source file with definition
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
struct def_s *temp_defs[4]; ///< freed temp vars (by size)
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)
{
const type_t *t;
const type_t *func_type = unalias_type (f->sym->type);
const type_t *ret_type = unalias_type (func_type->t.func.type);
const type_t *ret_type = unalias_type (f->type->t.func.type);
if (!e) {
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);
if (func) {
if (unalias_type (func->type) != type) {
if (func->type != type) {
error (0, "can't overload on return types");
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->name = name;
func->full_name = full_name;
func->type = (type_t *) type; //FIXME cast
func->type = type;
func->overloaded = overload;
func->file = pr.source_file;
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) {
s = new_symbol (name);
s->sy_type = sy_func;
s->type = sym->type;
s->type = (type_t *) unalias_type (sym->type); // FIXME cast
s->params = sym->params;
s->s.func = 0; // function not yet defined
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 *fb = *(overloaded_function_t **) b;
type_t *ta = fa->type;
type_t *tb = fb->type;
const type_t *ta = fa->type;
const type_t *tb = fb->type;
int na = ta->t.func.num_params;
int nb = tb->t.func.num_params;
int ret, i;
@ -497,7 +497,13 @@ build_scope (symbol_t *fsym, symtab_t *parent)
symtab->space = defspace_new (ds_virtual);
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);
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) {
sym->s.func = new_function (sym->name, nice_name);
sym->s.func->sym = sym;
sym->s.func->type = unalias_type (sym->type);
}
if (sym->s.func->def && sym->s.func->def->external
&& storage != sc_extern) {
@ -615,7 +622,7 @@ begin_function (symbol_t *sym, const char *nicename, symtab_t *parent,
static void
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) {
error (0, "too many params");
}