From 1102bc315a0590b19bed3199f626c9b3168a0f1f Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Wed, 24 Jul 2019 22:14:18 +0700 Subject: [PATCH 1/4] Implement warning 210 --- source/compiler/sc.h | 8 +++++- source/compiler/sc1.c | 44 +++++++++++++++++++---------- source/compiler/sc2.c | 33 ++++++++++++++++++++++ source/compiler/sc3.c | 65 ++++++++++++++++++++++++++++++++++--------- 4 files changed, 122 insertions(+), 28 deletions(-) diff --git a/source/compiler/sc.h b/source/compiler/sc.h index 4b9ed03f..1431a170 100644 --- a/source/compiler/sc.h +++ b/source/compiler/sc.h @@ -241,7 +241,11 @@ typedef struct s_symbol { * used during parsing a function, to detect a mix of "return;" and * "return value;" in a few special cases. */ -#define uRETNONE 0x10 +#define uRETNONE 0x010 +/* uEXPLINIT is set when a variable/array is explicitly initialized at + * definition or assigned a value. This flag differs from uWRITTEN + * because it doesn't mean the variable/array has been used somewhere. */ +#define uEXPLINIT 0x020 #define flagDEPRECATED 0x01 /* symbol is deprecated (avoid use) */ #define flagNAKED 0x10 /* function is naked */ @@ -650,6 +654,8 @@ SC_FUNC void delete_symbol(symbol *root,symbol *sym); SC_FUNC void delete_symbols(symbol *root,int level,int del_labels,int delete_functions); SC_FUNC int refer_symbol(symbol *entry,symbol *bywhom); SC_FUNC void markusage(symbol *sym,int usage); +SC_FUNC void markinitialized(symbol *sym); +SC_FUNC void checkinitialized(symbol *sym); SC_FUNC void rename_symbol(symbol *sym,const char *newname); SC_FUNC symbol *findglb(const char *name,int filter); SC_FUNC symbol *findloc(const char *name); diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 1314e52e..f6e1abb6 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -95,7 +95,7 @@ static void decl_const(int table); static void decl_enum(int table,int fstatic); static cell needsub(int *tag,constvalue_root **enumroot); static void initials(int ident,int tag,cell *size,int dim[],int numdim, - constvalue_root *enumroot); + constvalue_root *enumroot,int *explicit_init); static cell initarray(int ident,int tag,int dim[],int numdim,int cur, int startlit,int counteddim[],constvalue_root *lastdim, constvalue_root *enumroot,int *errorfound); @@ -2004,6 +2004,7 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fst char *str; int dim[sDIMEN_MAX]; int numdim; + int explicit_init; short filenum; symbol *sym; constvalue_root *enumroot=NULL; @@ -2108,7 +2109,7 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fst litidx=0; /* global initial data is dumped, so restart at zero */ } /* if */ assert(litidx==0); /* literal queue should be empty (again) */ - initials(ident,tag,&size,dim,numdim,enumroot);/* stores values in the literal queue */ + initials(ident,tag,&size,dim,numdim,enumroot,&explicit_init);/* stores values in the literal queue */ assert(size>=litidx); if (numdim==1) dim[0]=(int)size; @@ -2232,6 +2233,8 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fst sym->usage|=uSTOCK; if (fstatic) sym->fnumber=filenum; + if (explicit_init) + markinitialized(sym); sc_attachdocumentation(sym);/* attach any documenation to the variable */ if (sc_status==statSKIP) { sc_status=statWRITE; @@ -2268,6 +2271,7 @@ static int declloc(int fstatic) int numdim; int fconst; int staging_start; + int explicit_init; /* is the variable explicitly initialized? */ fconst=matchtoken(tCONST); do { @@ -2318,7 +2322,7 @@ static int declloc(int fstatic) sc_alignnext=FALSE; } /* if */ cur_lit=litidx; /* save current index in the literal table */ - initials(ident,tag,&size,dim,numdim,enumroot); + initials(ident,tag,&size,dim,numdim,enumroot,&explicit_init); if (size==0) return ident; /* error message already given */ if (numdim==1) @@ -2357,7 +2361,7 @@ static int declloc(int fstatic) if (ident==iVARIABLE) { /* simple variable, also supports initialization */ int ctag = tag; /* set to "tag" by default */ - int explicit_init=FALSE;/* is the variable explicitly initialized? */ + explicit_init=FALSE; if (matchtoken('=')) { sym->usage &= ~uDEFINE; /* temporarily mark the variable as undefined to prevent * possible self-assignment through its initialization expression */ @@ -2416,6 +2420,8 @@ static int declloc(int fstatic) } /* if */ } /* if */ } /* if */ + if (explicit_init) + markinitialized(sym); } while (matchtoken(',')); /* enddo */ /* more? */ needtoken(tTERM); /* if not comma, must be semicolumn */ return ident; @@ -2496,7 +2502,7 @@ static int base; * Global references: litidx (altered) */ static void initials(int ident,int tag,cell *size,int dim[],int numdim, - constvalue_root *enumroot) + constvalue_root *enumroot,int *explicit_init) { int ctag; cell tablesize; @@ -2504,6 +2510,8 @@ static void initials(int ident,int tag,cell *size,int dim[],int numdim, int err=0; int i; + if (explicit_init!=NULL) + *explicit_init=FALSE; if (!matchtoken('=')) { assert(ident!=iARRAY || numdim>0); if (ident==iARRAY) { @@ -2534,6 +2542,8 @@ static void initials(int ident,int tag,cell *size,int dim[],int numdim, return; } /* if */ + if (explicit_init!=NULL) + *explicit_init=TRUE; if (ident==iVARIABLE) { assert(*size==1); init(ident,&ctag,NULL); @@ -4160,7 +4170,7 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags, lexpush(); /* initials() needs the "=" token again */ assert(litidx==0); /* at the start of a function, this is reset */ assert(numtags>0); - initials(ident,tags[0],&size,arg->dim,arg->numdim,enumroot); + initials(ident,tags[0],&size,arg->dim,arg->numdim,enumroot,NULL); assert(size>=litidx); /* allocate memory to hold the initial values */ arg->defvalue.array.data=(cell *)malloc(litidx*sizeof(cell)); @@ -4237,14 +4247,15 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags, assert(numtags>0); argsym=addvariable(name,offset,ident,sLOCAL,tags[0], arg->dim,arg->numdim,arg->idxtag,0); + markinitialized(argsym); if (fpublic) { - argsym->usage|=uREAD; /* arguments of public functions are always "used" */ - if(argsym->ident==iREFARRAY || argsym->ident==iREFERENCE) - argsym->usage|=uWRITTEN; - } + argsym->usage |= uREAD; /* arguments of public functions are always "used" */ + if (argsym->ident==iREFARRAY || argsym->ident==iREFERENCE) + argsym->usage |= uWRITTEN; + } /* if */ if (fconst) - argsym->usage|=uCONST; + argsym->usage |= uCONST; } /* if */ } @@ -5240,9 +5251,9 @@ SC_FUNC symbol *add_builtin_string_constant(char *name,const char *val, glb_declared+=litidx; dumplits(); litidx=0; - } - sym->usage|=uDEFINE; - sym->flags|=flagPREDEF; + } /* if */ + sym->usage |= (uDEFINE | uEXPLINIT); + sym->flags |= flagPREDEF; return sym; } @@ -6094,6 +6105,7 @@ static int SC_FASTCALL emit_getlval(int *identptr,emit_outval *p,int *islocal, r error(17,str); /* undefined symbol */ return FALSE; } /* if */ + markinitialized(sym); markusage(sym,uREAD | uWRITTEN); p->type=eotNUMBER; @@ -6490,6 +6502,7 @@ static void SC_FASTCALL emit_param_data(emit_outval *p) case tSYMBOL: sym=findloc(str); if (sym!=NULL) { + markinitialized(sym); markusage(sym,uREAD | uWRITTEN); if (sym->ident==iLABEL) { tok=tLABEL; @@ -6508,6 +6521,7 @@ static void SC_FASTCALL emit_param_data(emit_outval *p) error(17,str); /* undefined symbol */ return; } /* if */ + markinitialized(sym); markusage(sym,(sym->ident==iFUNCTN || sym->ident==iREFFUNC) ? uREAD : (uREAD | uWRITTEN)); if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) { tok=((sym->usage & uNATIVE)!=0) ? teNATIVE : teFUNCTN; @@ -6548,6 +6562,7 @@ static void SC_FASTCALL emit_param_local(emit_outval *p,int allow_ref) case tSYMBOL: sym=findloc(str); if (sym!=NULL) { + markinitialized(sym); markusage(sym,uREAD | uWRITTEN); if (sym->ident==iLABEL) { tok=tLABEL; @@ -6571,6 +6586,7 @@ static void SC_FASTCALL emit_param_local(emit_outval *p,int allow_ref) error(17,str); /* undefined symbol */ return; } /* if */ + markinitialized(sym); markusage(sym,(sym->ident==iFUNCTN || sym->ident==iREFFUNC) ? uREAD : (uREAD | uWRITTEN)); if (sym->ident!=iCONSTEXPR) { if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) diff --git a/source/compiler/sc2.c b/source/compiler/sc2.c index d822cf60..3e5a63d8 100644 --- a/source/compiler/sc2.c +++ b/source/compiler/sc2.c @@ -1421,6 +1421,7 @@ static int command(void) } else { outval(sym->addr,FALSE); /* mark symbol as "used", unknown whether for read or write */ + markinitialized(sym); markusage(sym,uREAD | uWRITTEN); } /* if */ code_idx+=opargs(1); @@ -3160,6 +3161,8 @@ SC_FUNC void markusage(symbol *sym,int usage) sym->usage |= (char)usage; if ((usage & uWRITTEN)!=0) sym->lnumber=fline; + if ((usage & uREAD)!=0) + checkinitialized(sym); /* check if (global) reference must be added to the symbol */ if ((usage & (uREAD | uWRITTEN))!=0) { /* only do this for global symbols */ @@ -3174,6 +3177,36 @@ SC_FUNC void markusage(symbol *sym,int usage) } /* if */ } +SC_FUNC void markinitialized(symbol *sym) +{ + symbol *cursym; + assert(sym!=NULL); + if (sym->ident!=iVARIABLE && sym->ident!=iARRAY) + return; + if (sc_status==statFIRST && (sym->vclass==sLOCAL || sym->vclass==sSTATIC)) + return; + cursym=sym; + do { + cursym->usage |= uEXPLINIT; + } while ((cursym=cursym->child)!=NULL); + cursym=sym; + while ((cursym=cursym->parent)!=NULL) + cursym->usage |= uEXPLINIT; +} + +SC_FUNC void checkinitialized(symbol *sym) +{ + assert(sym!=NULL); + if (sc_status==statFIRST) + return; + if (sym->ident!=iVARIABLE && sym->ident!=iARRAY) + return; + if ((sym->usage & uDEFINE)==0 || (sym->usage & uEXPLINIT)!=0) + return; + error(210,sym->name); /* possible use of symbol before initialization */ + markinitialized(sym); /* don't issue the same error for this symbol again */ +} + /* findglb * diff --git a/source/compiler/sc3.c b/source/compiler/sc3.c index 993e3589..d2957dea 100644 --- a/source/compiler/sc3.c +++ b/source/compiler/sc3.c @@ -478,6 +478,10 @@ static int plnge(int *opstr,int opoff,int (*hier)(value *lval),value *lval, if (chkbitwise && count++>0 && bitwise_opercount!=0) error(212); opidx+=opoff; /* add offset to index returned by nextop() */ + if (lval->sym!=NULL) + checkinitialized(lval->sym); + if (lval2.sym!=NULL) + checkinitialized(lval2.sym); plnge2(op1[opidx],hier,lval,&lval2); if (op1[opidx]==ob_and || op1[opidx]==ob_or) bitwise_opercount++; @@ -823,6 +827,7 @@ static int hier14(value *lval1) int bwcount,leftarray; cell arrayidx1[sDIMEN_MAX],arrayidx2[sDIMEN_MAX]; /* last used array indices */ cell *org_arrayidx; + int markinit=FALSE; bwcount=bitwise_opercount; bitwise_opercount=0; @@ -877,6 +882,7 @@ static int hier14(value *lval1) oper=ob_sal; break; case '=': /* simple assignment */ + markinit=TRUE; oper=NULL; if (sc_intest) error(211); /* possibly unintended assignment */ @@ -926,6 +932,8 @@ static int hier14(value *lval1) plnge2(oper,hier14,lval1,&lval2); if (lval2.ident!=iARRAYCELL && lval2.ident!=iARRAYCHAR) lval2.arrayidx=NULL; + if (lval2.ident==iARRAYCELL || lval2.ident==iARRAYCHAR || lval2.ident==iREFARRAY) + checkinitialized(lval2.sym); if (oper) popreg(sALT); if (!oper && lval3.arrayidx!=NULL && lval2.arrayidx!=NULL @@ -1063,6 +1071,10 @@ static int hier14(value *lval1) pc_sideeffect=TRUE; bitwise_opercount=bwcount; lval1->ident=iEXPRESSION; + if (markinit) + markinitialized(lval3.sym); + else + checkinitialized(lval3.sym); return FALSE; /* expression result is never an lvalue */ } @@ -1241,6 +1253,7 @@ static int hier2(value *lval) assert(lval->sym!=NULL); if ((lval->sym->usage & uCONST)!=0) return error(22); /* assignment to const argument */ + checkinitialized(lval->sym); if (!check_userop(user_inc,lval->tag,0,1,lval,&lval->tag)) inc(lval); /* increase variable first */ rvalue(lval); /* and read the result into PRI */ @@ -1252,6 +1265,7 @@ static int hier2(value *lval) assert(lval->sym!=NULL); if ((lval->sym->usage & uCONST)!=0) return error(22); /* assignment to const argument */ + checkinitialized(lval->sym); if (!check_userop(user_dec,lval->tag,0,1,lval,&lval->tag)) dec(lval); /* decrease variable first */ rvalue(lval); /* and read the result into PRI */ @@ -1502,6 +1516,7 @@ static int hier2(value *lval) assert(lval->sym!=NULL); if ((lval->sym->usage & uCONST)!=0) return error(22); /* assignment to const argument */ + checkinitialized(lval->sym); /* on incrementing array cells, the address in PRI must be saved for * incremening the value, whereas the current value must be in PRI * on exit. @@ -1524,6 +1539,7 @@ static int hier2(value *lval) assert(lval->sym!=NULL); if ((lval->sym->usage & uCONST)!=0) return error(22); /* assignment to const argument */ + checkinitialized(lval->sym); saveresult= (lval->ident==iARRAYCELL || lval->ident==iARRAYCHAR); if (saveresult) pushreg(sPRI); /* save address in PRI */ @@ -1614,6 +1630,8 @@ static int hier1(value *lval1) rvalue(&lval2); if (lval2.ident==iARRAY || lval2.ident==iREFARRAY) error(33,lval2.sym->name); /* array must be indexed */ + else if (lval2.ident==iARRAYCELL || lval2.ident==iARRAYCHAR) + checkinitialized(lval2.sym); needtoken(close); check_tagmismatch(sym->x.tags.index,lval2.tag,TRUE,-1); if (lval2.ident==iCONSTEXPR) { /* constant expression */ @@ -1839,7 +1857,14 @@ static int primary(value *lval) lval->ident=sym->ident; lval->tag=sym->tag; if (sym->ident==iARRAY || sym->ident==iREFARRAY) { + /* temporarily mark the symbol as initialized before obtaining its address + * in order to avoid warning 210 on assignment to an array cell */ + const int was_uninitialized=((sym->usage & uEXPLINIT)==0); + sym->usage |= uEXPLINIT; address(sym,sPRI); /* get starting address in primary register */ + /* clear the initialization flag that was temporarily set earlier */ + if (was_uninitialized) + sym->usage &= ~uEXPLINIT; return FALSE; /* return 0 for array (not lvalue) */ } else { return TRUE; /* return 1 if lvalue (not label or array) */ @@ -1861,7 +1886,14 @@ static int primary(value *lval) lval->ident=sym->ident; lval->tag=sym->tag; if (sym->ident==iARRAY || sym->ident==iREFARRAY) { + /* temporarily mark the symbol as initialized before obtaining its address + * in order to avoid warning 210 on assignment to an array cell */ + const int was_uninitialized=((sym->usage & uEXPLINIT)==0); + sym->usage |= uEXPLINIT; address(sym,sPRI); /* get starting address in primary register */ + /* clear the initialization flag that was temporarily set earlier */ + if (was_uninitialized) + sym->usage &= ~uEXPLINIT; return FALSE; /* return 0 for array (not lvalue) */ } else { return TRUE; /* return 1 if lvalue (not function or array) */ @@ -2108,13 +2140,6 @@ static int nesting=0; if (arg[argidx].ident!=0 && arg[argidx].numtags==1) lval.cmptag=arg[argidx].tags[0]; /* set the expected tag, if any */ lvalue=hier14(&lval); - /* Mark the symbol as "read" so it won't be omitted from P-code. - * Native functions are marked as read at the point of their call, - * so we don't handle them here; see ffcall(). - */ - if (lval.sym!=NULL && (lval.sym->usage & uNATIVE)==0) { - markusage(lval.sym,uREAD); - } /* if */ assert(sc_status==statFIRST || arg[argidx].ident==0 || arg[argidx].tags!=NULL); switch (arg[argidx].ident) { case 0: @@ -2122,6 +2147,10 @@ static int nesting=0; break; case iVARARGS: /* always pass by reference */ + if (lval.sym!=NULL) { + markinitialized(lval.sym); + markusage(lval.sym,uWRITTEN); + } /* if */ if (lval.ident==iVARIABLE || lval.ident==iREFERENCE) { assert(lval.sym!=NULL); if ((lval.sym->usage & uCONST)!=0 && (arg[argidx].usage & uCONST)==0) { @@ -2156,8 +2185,6 @@ static int nesting=0; } /* if */ /* ??? handle const array passed by reference */ /* otherwise, the address is already in PRI */ - if (lval.sym!=NULL) - markusage(lval.sym,uWRITTEN); check_tagmismatch_multiple(arg[argidx].tags,arg[argidx].numtags,lval.tag,-1); if (lval.tag!=0) append_constval(&taglst,arg[argidx].name,lval.tag,0); @@ -2177,6 +2204,11 @@ static int nesting=0; argidx++; /* argument done */ break; case iREFERENCE: + if (lval.sym!=NULL) { + if ((arg[argidx].usage & uCONST)==0) + markinitialized(lval.sym); + markusage(lval.sym,uWRITTEN); + } /* if */ if (!lvalue || lval.ident==iARRAYCHAR) error(35,argidx+1); /* argument type mismatch */ if (lval.sym!=NULL && (lval.sym->usage & uCONST)!=0 && (arg[argidx].usage & uCONST)==0) @@ -2196,10 +2228,12 @@ static int nesting=0; if (lval.tag!=0) append_constval(&taglst,arg[argidx].name,lval.tag,0); argidx++; /* argument done */ - if (lval.sym!=NULL) - markusage(lval.sym,uWRITTEN); break; case iREFARRAY: + if (lval.sym!=NULL && (arg[argidx].usage & uCONST)==0) { + markinitialized(lval.sym); + markusage(lval.sym,uWRITTEN); + } /* if */ if (lval.ident!=iARRAY && lval.ident!=iREFARRAY && lval.ident!=iARRAYCELL) { @@ -2275,11 +2309,16 @@ static int nesting=0; check_tagmismatch_multiple(arg[argidx].tags,arg[argidx].numtags,lval.tag,-1); if (lval.tag!=0) append_constval(&taglst,arg[argidx].name,lval.tag,0); - if (lval.sym!=NULL && (arg[argidx].usage & uCONST)==0) - markusage(lval.sym,uWRITTEN); argidx++; /* argument done */ break; } /* switch */ + /* Mark the symbol as "read" so it won't be omitted from P-code. + * Native functions are marked as read at the point of their call, + * so we don't handle them here; see ffcall(). + */ + if (lval.sym!=NULL && (lval.sym->usage & uNATIVE)==0) { + markusage(lval.sym,uREAD); + } /* if */ pushreg(sPRI); /* store the function argument on the stack */ markexpr(sPARM,NULL,0); /* mark the end of a sub-expression */ nest_stkusage++; From 1b64b42dd542598fd40013179aa1a66d1ca9c465 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Sat, 27 Jul 2019 03:32:58 +0700 Subject: [PATCH 2/4] Add tests for warning 210 --- source/compiler/tests/warning_210.meta | 31 ++++ source/compiler/tests/warning_210.pwn | 196 +++++++++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 source/compiler/tests/warning_210.meta create mode 100644 source/compiler/tests/warning_210.pwn diff --git a/source/compiler/tests/warning_210.meta b/source/compiler/tests/warning_210.meta new file mode 100644 index 00000000..b5e53e60 --- /dev/null +++ b/source/compiler/tests/warning_210.meta @@ -0,0 +1,31 @@ +{ + 'test_type': 'output_check', + 'errors': """ +warning_210.pwn(59) : warning 210: possible use of symbol before initialization: "local_var3" +warning_210.pwn(62) : warning 210: possible use of symbol before initialization: "local_var4" +warning_210.pwn(66) : warning 210: possible use of symbol before initialization: "local_var5" +warning_210.pwn(70) : warning 210: possible use of symbol before initialization: "local_var6" +warning_210.pwn(85) : warning 210: possible use of symbol before initialization: "local_arr1d4" +warning_210.pwn(88) : warning 210: possible use of symbol before initialization: "local_arr1d5" +warning_210.pwn(92) : warning 210: possible use of symbol before initialization: "local_arr1d6" +warning_210.pwn(96) : warning 210: possible use of symbol before initialization: "local_arr1d7" +warning_210.pwn(100) : warning 210: possible use of symbol before initialization: "local_arr1d8" +warning_210.pwn(104) : warning 210: possible use of symbol before initialization: "local_arr1d9" +warning_210.pwn(119) : warning 210: possible use of symbol before initialization: "local_arr2d4" +warning_210.pwn(122) : warning 210: possible use of symbol before initialization: "local_arr2d5" +warning_210.pwn(126) : warning 210: possible use of symbol before initialization: "local_arr2d6" +warning_210.pwn(130) : warning 210: possible use of symbol before initialization: "local_arr2d7" +warning_210.pwn(134) : warning 210: possible use of symbol before initialization: "local_arr2d8" +warning_210.pwn(138) : warning 210: possible use of symbol before initialization: "local_arr2d9" +warning_210.pwn(142) : warning 210: possible use of symbol before initialization: "local_arr2d10" +warning_210.pwn(149) : warning 210: possible use of symbol before initialization: "global_var3" +warning_210.pwn(151) : warning 210: possible use of symbol before initialization: "global_var4" +warning_210.pwn(154) : warning 210: possible use of symbol before initialization: "global_var5" +warning_210.pwn(165) : warning 210: possible use of symbol before initialization: "global_arr1d4" +warning_210.pwn(167) : warning 210: possible use of symbol before initialization: "global_arr1d5" +warning_210.pwn(170) : warning 210: possible use of symbol before initialization: "global_arr1d6" +warning_210.pwn(181) : warning 210: possible use of symbol before initialization: "global_arr2d4" +warning_210.pwn(184) : warning 210: possible use of symbol before initialization: "global_arr2d5" +warning_210.pwn(187) : warning 210: possible use of symbol before initialization: "global_arr2d6" + """ +} diff --git a/source/compiler/tests/warning_210.pwn b/source/compiler/tests/warning_210.pwn new file mode 100644 index 00000000..2390a45d --- /dev/null +++ b/source/compiler/tests/warning_210.pwn @@ -0,0 +1,196 @@ +stock UseVariable(arg) +{ + #pragma unused arg +} + +stock UseVariableRef(&arg) +{ + #pragma unused arg +} + +stock Use1DArray(const arg[]) +{ + #pragma unused arg +} + +stock Use1DArrayConst(const arg[]) +{ + #pragma unused arg +} + +stock Use2DArray(const arg[][]) +{ + #pragma unused arg +} + + +new global_var1 = 0; +new global_var2; +new global_var3; +new global_var4; +new global_var5; +new global_arr1d1[] = "hi there!"; +new global_arr1d2[8]; +new global_arr1d3[8]; +new global_arr1d4[8]; +new global_arr1d5[8]; +new global_arr1d6[8]; +new global_arr2d1[2][8] = { { 0 }, ... }; +new global_arr2d2[2][8]; +new global_arr2d3[2][8]; +new global_arr2d4[2][8]; +new global_arr2d5[2][8]; +new global_arr2d6[2][8]; + +TestFunc(arg_var, const arg_arr1d[], const arg_arr2d[][]) +{ + UseVariable(arg_var); + Use1DArray(arg_arr1d); + Use2DArray(arg_arr2d); + + new local_var1 = 0; + UseVariable(local_var1); + + new local_var2; + local_var2 = 0; + UseVariable(local_var2); + + new local_var3; + UseVariable(local_var3); // warning + + new local_var4; + local_var4 = local_var4 + 1; // warning + UseVariable(local_var4); + + new local_var5; + ++local_var5; // warning + UseVariable(local_var5); + + new local_var6; + local_var6++; // warning + UseVariable(local_var6); + + new local_arr1d1[] = "hi there!"; + Use1DArray(local_arr1d1); + + new local_arr1d2[8]; + local_arr1d2 = "oh, hi!"; + Use1DArray(local_arr1d2); + + new local_arr1d3[8]; + local_arr1d3[0] = 1; + Use1DArray(local_arr1d3); + + new local_arr1d4[8]; + Use1DArray(local_arr1d4); // warning + + new local_arr1d5[8]; + local_arr1d5[0] = local_arr1d5[0] + 1; // warning + Use1DArray(local_arr1d5); + + new local_arr1d6[8]; + local_arr1d6[0] = local_arr1d6[1]; // warning + Use1DArray(local_arr1d6); + + new local_arr1d7[8]; + local_arr1d7[local_arr1d7[0]] = 1; // warning + Use1DArray(local_arr1d7); + + new local_arr1d8[8]; + ++local_arr1d8[0]; // warning + Use1DArray(local_arr1d8); + + new local_arr1d9[8]; + local_arr1d9[0]++; // warning + Use1DArray(local_arr1d9); + + new local_arr2d1[2][8] = { { 0 }, ... }; + Use2DArray(local_arr2d1); + + new local_arr2d2[2][8]; + local_arr2d2[0] = "oh, hi!"; + Use2DArray(local_arr2d2); + + new local_arr2d3[2][8]; + local_arr2d3[0][0] = 1; + Use2DArray(local_arr2d3); + + new local_arr2d4[2][8]; + Use2DArray(local_arr2d4); // warning + + new local_arr2d5[2][8]; + local_arr2d5[0][0] = local_arr2d5[0][0] + 1; // warning + Use2DArray(local_arr2d5); + + new local_arr2d6[2][8]; + local_arr2d6[0][0] = local_arr2d6[1][0]; // warning + Use2DArray(local_arr2d6); + + new local_arr2d7[2][8]; + local_arr2d7[0][local_arr2d7[0][0]] = 0; // warning + Use2DArray(local_arr2d7); + + new local_arr2d8[2][8]; + local_arr2d8[0] = local_arr2d8[1]; // warning + Use2DArray(local_arr2d8); + + new local_arr2d9[2][8]; + ++local_arr2d9[0][0]; // warning + Use2DArray(local_arr2d9); + + new local_arr2d10[2][8]; + local_arr2d10[0][0]++; // warning + Use2DArray(local_arr2d10); + UseVariable(global_var1); + + global_var2 = 0; + UseVariable(global_var2); + + UseVariable(global_var3); // warning + + ++global_var4; // warning + UseVariable(global_var4); + + global_var5++; // warning + UseVariable(global_var5); + + Use1DArray(global_arr1d1); + + global_arr1d2 = "oh, hi!"; + Use1DArray(global_arr1d2); + + global_arr1d3[0] = 1; + Use1DArray(global_arr1d3); + + Use1DArray(global_arr1d4); // warning + + ++global_arr1d5[0]; // warning + Use1DArray(global_arr1d5); + + global_arr1d6[0]++; // warning + Use1DArray(global_arr1d6); + + Use2DArray(global_arr2d1); + + global_arr2d2[0] = "oh, hi!"; + Use2DArray(global_arr2d2); + + global_arr2d3[0][0] = 1; + Use2DArray(global_arr2d3); + + Use2DArray(global_arr2d4); // warning + + ++global_arr2d5[0][0]; // warning + Use2DArray(global_arr2d5); + + global_arr2d6[0][0]++; // warning + Use2DArray(global_arr2d6); +} + +main() +{ + static arr1d[2] = { 0, 0 }; + static arr2d[2][2] = { { 0, 0 }, { 0, 0 } }; + TestFunc(0, arr1d, arr2d); +} + From 1b5f89b69f8dcc26fb301d1edfb624b77eab9910 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Sat, 27 Jul 2019 03:33:12 +0700 Subject: [PATCH 3/4] Update the other affected tests --- source/compiler/tests/__emit_p6.pwn | 2 +- source/compiler/tests/meaningless_class_specifiers_gh_172.pwn | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/compiler/tests/__emit_p6.pwn b/source/compiler/tests/__emit_p6.pwn index 0e9a5432..612e41a6 100644 --- a/source/compiler/tests/__emit_p6.pwn +++ b/source/compiler/tests/__emit_p6.pwn @@ -102,7 +102,7 @@ stock test__push_u(&local_refvar, local_refarray[]) main() { - new t, a[2]; + new t = 0, a[2] = { 0, ... }; test__op_load_u_pri_alt(t, a); // 4 test__op_stor_u_pri_alt(t, a); // 6 test__op_addr_u_pri_alt(t, a); // 6 diff --git a/source/compiler/tests/meaningless_class_specifiers_gh_172.pwn b/source/compiler/tests/meaningless_class_specifiers_gh_172.pwn index 1fd4d91a..1f722bee 100755 --- a/source/compiler/tests/meaningless_class_specifiers_gh_172.pwn +++ b/source/compiler/tests/meaningless_class_specifiers_gh_172.pwn @@ -14,7 +14,7 @@ f6(&v) { } main() { - new a; + new a = 0; f1(a); f2(a); f3(a); From 8462b806e82877737733b58dc62a61d5d45c0a9e Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Sat, 27 Jul 2019 03:36:40 +0700 Subject: [PATCH 4/4] Don't issue warning 210 in a few special cases: * A variable is defined as a loop counter inside a 'for' loop. * A variable is incremented/decremented using the '++'/'--' operator. --- source/compiler/sc1.c | 5 +++++ source/compiler/sc3.c | 8 ++++---- source/compiler/tests/warning_210.meta | 12 ------------ source/compiler/tests/warning_210.pwn | 24 ++++++++++++------------ 4 files changed, 21 insertions(+), 28 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index f6e1abb6..be6e6a74 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -5730,8 +5730,13 @@ static int dofor(void) /* The variable in expr1 of the for loop is at a * 'compound statement' level of it own. */ + symbol *sym; nestlevel++; declloc(FALSE); /* declare local variable */ + for (sym=loctab.next; sym!=NULL; sym=sym->next) { + if (sym->compound==nestlevel) + markinitialized(sym); + } /* for */ } else { doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE); /* expression 1 */ needtoken(';'); diff --git a/source/compiler/sc3.c b/source/compiler/sc3.c index d2957dea..1066de8f 100644 --- a/source/compiler/sc3.c +++ b/source/compiler/sc3.c @@ -1253,7 +1253,7 @@ static int hier2(value *lval) assert(lval->sym!=NULL); if ((lval->sym->usage & uCONST)!=0) return error(22); /* assignment to const argument */ - checkinitialized(lval->sym); + markinitialized(lval->sym); if (!check_userop(user_inc,lval->tag,0,1,lval,&lval->tag)) inc(lval); /* increase variable first */ rvalue(lval); /* and read the result into PRI */ @@ -1265,7 +1265,7 @@ static int hier2(value *lval) assert(lval->sym!=NULL); if ((lval->sym->usage & uCONST)!=0) return error(22); /* assignment to const argument */ - checkinitialized(lval->sym); + markinitialized(lval->sym); if (!check_userop(user_dec,lval->tag,0,1,lval,&lval->tag)) dec(lval); /* decrease variable first */ rvalue(lval); /* and read the result into PRI */ @@ -1516,7 +1516,7 @@ static int hier2(value *lval) assert(lval->sym!=NULL); if ((lval->sym->usage & uCONST)!=0) return error(22); /* assignment to const argument */ - checkinitialized(lval->sym); + markinitialized(lval->sym); /* on incrementing array cells, the address in PRI must be saved for * incremening the value, whereas the current value must be in PRI * on exit. @@ -1539,7 +1539,7 @@ static int hier2(value *lval) assert(lval->sym!=NULL); if ((lval->sym->usage & uCONST)!=0) return error(22); /* assignment to const argument */ - checkinitialized(lval->sym); + markinitialized(lval->sym); saveresult= (lval->ident==iARRAYCELL || lval->ident==iARRAYCHAR); if (saveresult) pushreg(sPRI); /* save address in PRI */ diff --git a/source/compiler/tests/warning_210.meta b/source/compiler/tests/warning_210.meta index b5e53e60..ecf05b10 100644 --- a/source/compiler/tests/warning_210.meta +++ b/source/compiler/tests/warning_210.meta @@ -3,29 +3,17 @@ 'errors': """ warning_210.pwn(59) : warning 210: possible use of symbol before initialization: "local_var3" warning_210.pwn(62) : warning 210: possible use of symbol before initialization: "local_var4" -warning_210.pwn(66) : warning 210: possible use of symbol before initialization: "local_var5" -warning_210.pwn(70) : warning 210: possible use of symbol before initialization: "local_var6" warning_210.pwn(85) : warning 210: possible use of symbol before initialization: "local_arr1d4" warning_210.pwn(88) : warning 210: possible use of symbol before initialization: "local_arr1d5" warning_210.pwn(92) : warning 210: possible use of symbol before initialization: "local_arr1d6" warning_210.pwn(96) : warning 210: possible use of symbol before initialization: "local_arr1d7" -warning_210.pwn(100) : warning 210: possible use of symbol before initialization: "local_arr1d8" -warning_210.pwn(104) : warning 210: possible use of symbol before initialization: "local_arr1d9" warning_210.pwn(119) : warning 210: possible use of symbol before initialization: "local_arr2d4" warning_210.pwn(122) : warning 210: possible use of symbol before initialization: "local_arr2d5" warning_210.pwn(126) : warning 210: possible use of symbol before initialization: "local_arr2d6" warning_210.pwn(130) : warning 210: possible use of symbol before initialization: "local_arr2d7" warning_210.pwn(134) : warning 210: possible use of symbol before initialization: "local_arr2d8" -warning_210.pwn(138) : warning 210: possible use of symbol before initialization: "local_arr2d9" -warning_210.pwn(142) : warning 210: possible use of symbol before initialization: "local_arr2d10" warning_210.pwn(149) : warning 210: possible use of symbol before initialization: "global_var3" -warning_210.pwn(151) : warning 210: possible use of symbol before initialization: "global_var4" -warning_210.pwn(154) : warning 210: possible use of symbol before initialization: "global_var5" warning_210.pwn(165) : warning 210: possible use of symbol before initialization: "global_arr1d4" -warning_210.pwn(167) : warning 210: possible use of symbol before initialization: "global_arr1d5" -warning_210.pwn(170) : warning 210: possible use of symbol before initialization: "global_arr1d6" warning_210.pwn(181) : warning 210: possible use of symbol before initialization: "global_arr2d4" -warning_210.pwn(184) : warning 210: possible use of symbol before initialization: "global_arr2d5" -warning_210.pwn(187) : warning 210: possible use of symbol before initialization: "global_arr2d6" """ } diff --git a/source/compiler/tests/warning_210.pwn b/source/compiler/tests/warning_210.pwn index 2390a45d..6eb07a9b 100644 --- a/source/compiler/tests/warning_210.pwn +++ b/source/compiler/tests/warning_210.pwn @@ -63,11 +63,11 @@ TestFunc(arg_var, const arg_arr1d[], const arg_arr2d[][]) UseVariable(local_var4); new local_var5; - ++local_var5; // warning + ++local_var5; UseVariable(local_var5); new local_var6; - local_var6++; // warning + local_var6++; UseVariable(local_var6); new local_arr1d1[] = "hi there!"; @@ -97,11 +97,11 @@ TestFunc(arg_var, const arg_arr1d[], const arg_arr2d[][]) Use1DArray(local_arr1d7); new local_arr1d8[8]; - ++local_arr1d8[0]; // warning + ++local_arr1d8[0]; Use1DArray(local_arr1d8); new local_arr1d9[8]; - local_arr1d9[0]++; // warning + local_arr1d9[0]++; Use1DArray(local_arr1d9); new local_arr2d1[2][8] = { { 0 }, ... }; @@ -135,11 +135,11 @@ TestFunc(arg_var, const arg_arr1d[], const arg_arr2d[][]) Use2DArray(local_arr2d8); new local_arr2d9[2][8]; - ++local_arr2d9[0][0]; // warning + ++local_arr2d9[0][0]; Use2DArray(local_arr2d9); new local_arr2d10[2][8]; - local_arr2d10[0][0]++; // warning + local_arr2d10[0][0]++; Use2DArray(local_arr2d10); UseVariable(global_var1); @@ -148,10 +148,10 @@ TestFunc(arg_var, const arg_arr1d[], const arg_arr2d[][]) UseVariable(global_var3); // warning - ++global_var4; // warning + ++global_var4; UseVariable(global_var4); - global_var5++; // warning + global_var5++; UseVariable(global_var5); Use1DArray(global_arr1d1); @@ -164,10 +164,10 @@ TestFunc(arg_var, const arg_arr1d[], const arg_arr2d[][]) Use1DArray(global_arr1d4); // warning - ++global_arr1d5[0]; // warning + ++global_arr1d5[0]; Use1DArray(global_arr1d5); - global_arr1d6[0]++; // warning + global_arr1d6[0]++; Use1DArray(global_arr1d6); Use2DArray(global_arr2d1); @@ -180,10 +180,10 @@ TestFunc(arg_var, const arg_arr1d[], const arg_arr2d[][]) Use2DArray(global_arr2d4); // warning - ++global_arr2d5[0][0]; // warning + ++global_arr2d5[0][0]; Use2DArray(global_arr2d5); - global_arr2d6[0][0]++; // warning + global_arr2d6[0][0]++; Use2DArray(global_arr2d6); }