Fix uninitialised locals detection (for both -WF302 and -Olo).

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5693 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2020-05-14 13:43:32 +00:00
parent 89f1fa4011
commit 402fd12785
3 changed files with 18 additions and 11 deletions

View file

@ -1307,7 +1307,7 @@ void PR_RunGC (progfuncs_t *progfuncs)
gc->tempstrings = (void*)((char*)gc->amem+prinst.addressableused); gc->tempstrings = (void*)((char*)gc->amem+prinst.addressableused);
memcpy(gc->tempstrings, prinst.tempstrings, sizeof(*gc->tempstrings)*gc->maxtemps); memcpy(gc->tempstrings, prinst.tempstrings, sizeof(*gc->tempstrings)*gc->maxtemps);
COM_AddWork(WG_LOADER, PR_QCGC_Thread, gc, NULL, 0, 0); COM_InsertWork(WG_LOADER, PR_QCGC_Thread, gc, NULL, 0, 0);
#ifdef GCTIMINGS #ifdef GCTIMINGS
endtime = Sys_DoubleTime(); endtime = Sys_DoubleTime();

View file

@ -439,6 +439,7 @@ typedef struct QCC_def_s
pbool nofold:1; pbool nofold:1;
pbool initialized:1; //true when a declaration included "= immediate". pbool initialized:1; //true when a declaration included "= immediate".
pbool isextern:1; //fteqw-specific lump entry pbool isextern:1; //fteqw-specific lump entry
pbool isparameter:1; //its an engine parameter (thus preinitialised).
int fromstatement; //statement that it is valid from. int fromstatement; //statement that it is valid from.
temp_t *temp; temp_t *temp;
@ -1013,6 +1014,7 @@ void QCC_PR_NewLine (pbool incomment);
#define GDF_BASICTYPE 128 //don't care about #merge types not being known correctly. #define GDF_BASICTYPE 128 //don't care about #merge types not being known correctly.
#define GDF_SCANLOCAL 256 //don't use the locals hash table #define GDF_SCANLOCAL 256 //don't use the locals hash table
#define GDF_POSTINIT 512 //field must be initialised at the end of the compile (allows arrays to be extended later) #define GDF_POSTINIT 512 //field must be initialised at the end of the compile (allows arrays to be extended later)
#define GDF_PARAMETER 1024
QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, const char *name, struct QCC_function_s *scope, pbool allocate, int arraysize, unsigned int flags); QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, const char *name, struct QCC_function_s *scope, pbool allocate, int arraysize, unsigned int flags);
QCC_sref_t QCC_PR_GetSRef (QCC_type_t *type, const char *name, struct QCC_function_s *scope, pbool allocate, int arraysize, unsigned int flags); QCC_sref_t QCC_PR_GetSRef (QCC_type_t *type, const char *name, struct QCC_function_s *scope, pbool allocate, int arraysize, unsigned int flags);
void QCC_FreeTemp(QCC_sref_t t); void QCC_FreeTemp(QCC_sref_t t);

View file

@ -233,6 +233,7 @@ QCC_statement_t *QCC_Generate_OP_IF(QCC_sref_t e, pbool preserve);
QCC_statement_t *QCC_Generate_OP_GOTO(void); QCC_statement_t *QCC_Generate_OP_GOTO(void);
QCC_sref_t QCC_PR_GenerateLogicalNot(QCC_sref_t e, const char *errormessage); QCC_sref_t QCC_PR_GenerateLogicalNot(QCC_sref_t e, const char *errormessage);
static QCC_function_t *QCC_PR_GenerateQCFunction (QCC_def_t *def, QCC_type_t *type, unsigned int *pif_flags); static QCC_function_t *QCC_PR_GenerateQCFunction (QCC_def_t *def, QCC_type_t *type, unsigned int *pif_flags);
static void QCC_StoreToSRef(QCC_sref_t dest, QCC_sref_t source, QCC_type_t *type, pbool preservesource, pbool preservedest);
//NOTE: prints may use from the func argument's symbol, which can be awkward if its a temp. //NOTE: prints may use from the func argument's symbol, which can be awkward if its a temp.
QCC_sref_t QCC_PR_GenerateFunctionCallSref (QCC_sref_t newself, QCC_sref_t func, QCC_sref_t *arglist, int argcount); QCC_sref_t QCC_PR_GenerateFunctionCallSref (QCC_sref_t newself, QCC_sref_t func, QCC_sref_t *arglist, int argcount);
@ -5818,10 +5819,14 @@ QCC_sref_t QCC_PR_GenerateFunctionCallRef (QCC_sref_t newself, QCC_sref_t func,
if (args[i].ref.sym != d.sym || args[i].ref.ofs != d.ofs) if (args[i].ref.sym != d.sym || args[i].ref.ofs != d.ofs)
{ {
QCC_ForceUnFreeDef(d.sym); QCC_ForceUnFreeDef(d.sym);
#if 0
QCC_StoreToSRef(d, args[i].ref, d.cast, false, false);
#else
if (args[i].ref.cast->size == 3) if (args[i].ref.cast->size == 3)
QCC_FreeTemp(QCC_PR_StatementFlags (&pr_opcodes[OP_STORE_V], args[i].ref, d, NULL, 0)); QCC_FreeTemp(QCC_PR_StatementFlags (&pr_opcodes[OP_STORE_V], args[i].ref, d, NULL, 0));
else else
QCC_FreeTemp(QCC_PR_StatementFlags (&pr_opcodes[OP_STORE_F], args[i].ref, d, NULL, 0)); QCC_FreeTemp(QCC_PR_StatementFlags (&pr_opcodes[OP_STORE_F], args[i].ref, d, NULL, 0));
#endif
} }
else else
QCC_FreeTemp(args[i].ref); QCC_FreeTemp(args[i].ref);
@ -12530,7 +12535,7 @@ static pbool QCC_CheckUninitialised(int firststatement, int laststatement)
continue; //not a real local, so will be properly initialised. continue; //not a real local, so will be properly initialised.
if (local->symbolheader != local) if (local->symbolheader != local)
continue; //ignore slave symbols, cos they're not interesting and should have been checked as part of the parent. continue; //ignore slave symbols, cos they're not interesting and should have been checked as part of the parent.
if (local->ofs < paramend) if (local->isparameter)
continue; continue;
err = QCC_CheckOneUninitialised(firststatement, laststatement, local, local->ofs, local->ofs + local->type->size * (local->arraysize?local->arraysize:1)); err = QCC_CheckOneUninitialised(firststatement, laststatement, local, local->ofs, local->ofs + local->type->size * (local->arraysize?local->arraysize:1));
if (err > 0) if (err > 0)
@ -13039,7 +13044,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *typ
QCC_def_t *arg; QCC_def_t *arg;
for (u=0, p=0, arg=f->firstlocal ; u<type->num_parms; u++, arg = arg->deftail->nextlocal) for (u=0, p=0, arg=f->firstlocal ; u<type->num_parms; u++, arg = arg->deftail->nextlocal)
{ {
QCC_PR_DummyDef(type->params[u].type, pr_parm_names[u], pr_scope, 0, arg, 0, true, false); QCC_PR_DummyDef(type->params[u].type, pr_parm_names[u], pr_scope, 0, arg, 0, true, GDF_PARAMETER);
} }
if (type->vargcount) if (type->vargcount)
@ -13047,7 +13052,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *typ
if (!pr_parm_argcount_name) if (!pr_parm_argcount_name)
QCC_Error(ERR_INTERNAL, "I forgot what the va_count argument is meant to be called"); QCC_Error(ERR_INTERNAL, "I forgot what the va_count argument is meant to be called");
else else
QCC_PR_DummyDef(type_float, pr_parm_argcount_name, pr_scope, 0, arg, 0, true, false); QCC_PR_DummyDef(type_float, pr_parm_argcount_name, pr_scope, 0, arg, 0, true, 0);
} }
} }
else else
@ -13060,14 +13065,17 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *typ
QC_snprintfz(pr_parm_names[u], sizeof(pr_parm_names[u]), "$arg_%u", u); QC_snprintfz(pr_parm_names[u], sizeof(pr_parm_names[u]), "$arg_%u", u);
QCC_PR_ParseWarning(WARN_PARAMWITHNONAME, "Parameter %u of %s is not named", u+1, pr_scope->name); QCC_PR_ParseWarning(WARN_PARAMWITHNONAME, "Parameter %u of %s is not named", u+1, pr_scope->name);
} }
parm = QCC_PR_GetSRef (type->params[u].type, pr_parm_names[u], pr_scope, 2, 0, false); parm = QCC_PR_GetSRef (type->params[u].type, pr_parm_names[u], pr_scope, 2, 0, 0);
parm.sym->used = true; //make sure system parameters get seen by the engine, even if the names are stripped.. parm.sym->used = true; //make sure system parameters get seen by the engine, even if the names are stripped..
parm.sym->referenced = true; parm.sym->referenced = true;
for (o = 0; o < (type->params[u].type->size+2)/3; o++) for (o = 0; o < (type->params[u].type->size+2)/3; o++)
{ {
if (p < MAX_PARMS) if (p < MAX_PARMS)
{
parm.sym->isparameter = true;
parm.ofs+=3;//no need to copy anything, as the engine will do it for us. parm.ofs+=3;//no need to copy anything, as the engine will do it for us.
}
else else
{ //extra parms need to be explicitly copied. { //extra parms need to be explicitly copied.
if (!extra_parms[p - MAX_PARMS].sym) if (!extra_parms[p - MAX_PARMS].sym)
@ -13859,6 +13867,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, const char *name, QCC_function_t *s
def->scope = scope; def->scope = scope;
def->constant = !!(flags & GDF_CONST); def->constant = !!(flags & GDF_CONST);
def->isstatic = !!(flags & GDF_STATIC); def->isstatic = !!(flags & GDF_STATIC);
def->isparameter = !!(flags & GDF_PARAMETER);
if (arraysize && a < 0) if (arraysize && a < 0)
{ //array headers can be stripped safely. { //array headers can be stripped safely.
def->saved = false; def->saved = false;
@ -15386,20 +15395,16 @@ void QCC_PR_ParseDefs (char *classname, pbool fatal)
isstatic = true; isstatic = true;
else if (!pr_scope && QCC_PR_CheckKeyword(keyword_nonstatic, "nonstatic")) else if (!pr_scope && QCC_PR_CheckKeyword(keyword_nonstatic, "nonstatic"))
isstatic = false; isstatic = false;
else if (QCC_PR_CheckKeyword(keyword_noref, "noref")) else if (QCC_PR_CheckKeyword(keyword_unused, "unused") || QCC_PR_CheckKeyword(keyword_noref, "noref"))
noref=true;
else if (QCC_PR_CheckKeyword(keyword_unused, "unused"))
noref=true; noref=true;
else if (QCC_PR_CheckKeyword(keyword_used, "used")) else if (QCC_PR_CheckKeyword(keyword_used, "used"))
forceused=true; forceused=true;
else if (QCC_PR_CheckKeyword(keyword_nosave, "nosave")) else if (QCC_PR_CheckKeyword(keyword_nosave, "nosave"))
nosave = true; nosave = true;
else if (QCC_PR_CheckKeyword(keyword_strip, "strip")) else if (QCC_PR_CheckKeyword(keyword_strip, "strip") || QCC_PR_CheckKeyword(keyword_ignore, "ignore"))
dostrip = true; dostrip = true;
else if (QCC_PR_CheckKeyword(keyword_inline, "inline")) else if (QCC_PR_CheckKeyword(keyword_inline, "inline"))
allowinline = true; allowinline = true;
else if (QCC_PR_CheckKeyword(keyword_ignore, "ignore"))
dostrip = true;
else if (QCC_PR_CheckKeyword(keyword_wrap, "wrap")) else if (QCC_PR_CheckKeyword(keyword_wrap, "wrap"))
dowrap = true; dowrap = true;
else if (QCC_PR_CheckKeyword(keyword_weak, "weak")) else if (QCC_PR_CheckKeyword(keyword_weak, "weak"))