mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-21 18:01:15 +00:00
auto-init for uninitialized locals in traditional mode as requested by
Grievre
This commit is contained in:
parent
5157f668ad
commit
14e8bfe94b
5 changed files with 30 additions and 12 deletions
|
@ -43,6 +43,7 @@ typedef struct def_s {
|
|||
struct reloc_s *refs; // for relocations
|
||||
|
||||
unsigned initialized:1; // for uninit var detection
|
||||
unsigned set:1; // uninit var auto-inited
|
||||
unsigned constant:1; // 1 when a declaration included "= immediate"
|
||||
unsigned freed:1; // already freed from the scope
|
||||
unsigned removed:1; // already removed from the symbol table
|
||||
|
|
|
@ -46,6 +46,7 @@ typedef struct function_s {
|
|||
struct def_s *def;
|
||||
struct scope_s *scope;
|
||||
struct reloc_s *refs;
|
||||
struct expr_s *var_init;
|
||||
} function_t;
|
||||
|
||||
extern function_t *current_func;
|
||||
|
|
|
@ -291,15 +291,26 @@ type_mismatch (expr_t *e1, expr_t *e2, int op)
|
|||
static void
|
||||
check_initialized (expr_t *e)
|
||||
{
|
||||
if (options.warnings.uninited_variable) {
|
||||
if (e->type == ex_def
|
||||
&& !(e->e.def->type->type == ev_func
|
||||
&& e->e.def->global)
|
||||
&& !(e->e.def->type->type == ev_struct)
|
||||
&& !e->e.def->external
|
||||
&& !e->e.def->initialized) {
|
||||
warning (e, "%s may be used uninitialized", e->e.def->name);
|
||||
e->e.def->initialized = 1; // only warn once
|
||||
const char *name;
|
||||
|
||||
if (e->type == ex_def
|
||||
&& !(e->e.def->type->type == ev_func
|
||||
&& e->e.def->global)
|
||||
&& !(e->e.def->type->type == ev_struct)
|
||||
&& !e->e.def->external
|
||||
&& !e->e.def->initialized) {
|
||||
name = e->e.def->name;
|
||||
if (options.warnings.uninited_variable)
|
||||
warning (e, "%s may be used uninitialized", name);
|
||||
e->e.def->initialized = 1; // only warn once
|
||||
if (options.traditional && !e->e.def->set) {
|
||||
e->e.def->set = 1; // only auto-init once
|
||||
e = assign_expr (e, new_nil_expr ());
|
||||
e->file = current_func->s_file;
|
||||
e->line = current_func->def->line;
|
||||
e->next = current_func->var_init;
|
||||
current_func->var_init = e;
|
||||
notice (e, "auto-initializing %s", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -274,6 +274,11 @@ emit_function (function_t *f, expr_t *e)
|
|||
if (f->aux)
|
||||
lineno_base = f->aux->source_line;
|
||||
|
||||
while (f->var_init) {
|
||||
emit_expr (f->var_init);
|
||||
f->var_init = f->var_init->next;
|
||||
}
|
||||
|
||||
current_scope = f->scope;
|
||||
while (e) {
|
||||
//printf ("%d ", pr.source_line);
|
||||
|
|
|
@ -225,7 +225,7 @@ WriteProgdefs (const char *filename)
|
|||
RESERVED_OFS);
|
||||
|
||||
for (d = pr.scope->head; d; d = d->def_next) {
|
||||
if (!strcmp (d->name, "end_sys_globals"))
|
||||
if (d->name && !strcmp (d->name, "end_sys_globals"))
|
||||
break;
|
||||
if (!d->ofs)
|
||||
continue;
|
||||
|
@ -259,10 +259,10 @@ WriteProgdefs (const char *filename)
|
|||
// print all fields
|
||||
fprintf (f, "typedef struct\n{\n");
|
||||
for (d = pr.scope->head; d; d = d->def_next) {
|
||||
if (!strcmp (d->name, "end_sys_fields"))
|
||||
if (d->name && !strcmp (d->name, "end_sys_fields"))
|
||||
break;
|
||||
|
||||
if (!d->ofs || d->type->type != ev_field)
|
||||
if (!d->name || !d->ofs || d->type->type != ev_field)
|
||||
continue;
|
||||
|
||||
switch (d->type->aux_type->type) {
|
||||
|
|
Loading…
Reference in a new issue