diff --git a/source/compiler/sc.h b/source/compiler/sc.h index 299d671c..e739f73d 100644 --- a/source/compiler/sc.h +++ b/source/compiler/sc.h @@ -226,7 +226,9 @@ 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 +/* uASSIGNED indicates that a value assigned to the variable is not used yet */ +#define uASSIGNED 0x080 #define flagDEPRECATED 0x01 /* symbol is deprecated (avoid use) */ #define flagNAKED 0x10 /* function is naked */ @@ -684,6 +686,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,int assignment); +SC_FUNC void clearassignments(symbol *root); 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); @@ -934,6 +938,7 @@ SC_VDECL short fnumber; /* number of files in the file table (debugging) * SC_VDECL short fcurrent; /* current file being processed (debugging) */ SC_VDECL short sc_intest; /* true if inside a test */ SC_VDECL int pc_sideeffect; /* true if an expression causes a side-effect */ +SC_VDECL int pc_ovlassignment;/* true if an expression contains an overloaded assignment */ SC_VDECL int stmtindent; /* current indent of the statement */ SC_VDECL int indent_nowarn; /* skip warning "217 loose indentation" */ SC_VDECL int sc_tabsize; /* number of spaces that a TAB represents */ diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index e95adae9..0313d410 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -98,7 +98,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); @@ -123,7 +123,7 @@ static void statement(int *lastindent,int allow_decl); static void compound(int stmt_sameline,int starttok); static int test(int label,int parens,int invert); static int doexpr(int comma,int chkeffect,int allowarray,int mark_endexpr, - int *tag,symbol **symptr,int chkfuncresult); + int *tag,symbol **symptr,int chkfuncresult,cell *val); static void doassert(void); static void doexit(void); static int doif(void); @@ -893,6 +893,7 @@ static void resetglobals(void) fcurrent=0; /* current file being processed (debugging) */ sc_intest=FALSE; /* true if inside a test */ pc_sideeffect=FALSE; /* true if an expression causes a side-effect */ + pc_ovlassignment=FALSE;/* true if an expression contains an overloaded assignment */ stmtindent=0; /* current indent of the statement */ indent_nowarn=FALSE; /* do not skip warning "217 loose indentation" */ sc_allowtags=TRUE; /* allow/detect tagnames */ @@ -2018,6 +2019,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; @@ -2122,7 +2124,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; @@ -2246,6 +2248,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,TRUE); sc_attachdocumentation(sym);/* attach any documenation to the variable */ if (sc_status==statSKIP) { sc_status=statWRITE; @@ -2282,6 +2286,8 @@ static int declloc(int fstatic) int numdim; int fconst; int staging_start; + int explicit_init; /* is the variable explicitly initialized? */ + int suppress_w240=FALSE; fconst=matchtoken(tCONST); do { @@ -2332,7 +2338,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) @@ -2371,13 +2377,16 @@ 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('=')) { + int initexpr_ident; + cell val; sym->usage &= ~uDEFINE; /* temporarily mark the variable as undefined to prevent * possible self-assignment through its initialization expression */ - doexpr(FALSE,FALSE,FALSE,FALSE,&ctag,NULL,TRUE); + initexpr_ident=doexpr(FALSE,FALSE,FALSE,FALSE,&ctag,NULL,TRUE,&val); sym->usage |= uDEFINE; explicit_init=TRUE; + suppress_w240=(initexpr_ident==iCONSTEXPR && val==0); } else { ldconst(0,sPRI); /* uninitialized variable, set to zero */ } /* if */ @@ -2386,7 +2395,7 @@ static int declloc(int fstatic) lval.ident=iVARIABLE; lval.constval=0; lval.tag=tag; - check_userop(NULL,ctag,lval.tag,2,NULL,&ctag); + suppress_w240 |= check_userop(NULL,ctag,lval.tag,2,NULL,&ctag); store(&lval); markexpr(sEXPR,NULL,0); /* full expression ends after the store */ assert(staging); /* end staging phase (optimize expression) */ @@ -2430,6 +2439,10 @@ static int declloc(int fstatic) } /* if */ } /* if */ } /* if */ + if (explicit_init) + markinitialized(sym,!suppress_w240); + if (pc_ovlassignment) + sym->usage |= uREAD; } while (matchtoken(',')); /* enddo */ /* more? */ needtoken(tTERM); /* if not comma, must be semicolumn */ return ident; @@ -2510,7 +2523,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; @@ -2518,6 +2531,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) { @@ -2548,6 +2563,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); @@ -4203,7 +4220,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)); @@ -4291,7 +4308,9 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags, argsym->usage|=uREAD; /* arguments of public functions are always "used" */ if(argsym->ident==iREFARRAY || argsym->ident==iREFERENCE) argsym->usage|=uWRITTEN; - } + } else if (argsym->ident==iVARIABLE) { + argsym->usage|=uASSIGNED; + } /* if */ if (fconst) argsym->usage|=uCONST; @@ -5077,6 +5096,14 @@ static void destructsymbols(symbol *root,int level) if ((opsym->usage & uNATIVE)!=0 && opsym->x.lib!=NULL) opsym->x.lib->value += 1; /* increment "usage count" of the library */ } /* if */ + /* check that the assigned value was used, but don't show the warning + * if the variable is completely unused (we already have warning 203 for that) */ + if ((sym->usage & (uASSIGNED | uREAD | uWRITTEN))==(uASSIGNED | uREAD | uWRITTEN) + && sym->vclass!=sSTATIC) { + errorset(sSETPOS,sym->lnumber); + error(204,sym->name); /* symbol is assigned a value that is never used */ + errorset(sSETPOS,-1); + } /* if */ } /* if */ sym=sym->next; } /* while */ @@ -5440,7 +5467,7 @@ static void statement(int *lastindent,int allow_decl) default: /* non-empty expression */ sc_allowproccall=optproccall; lexpush(); /* analyze token later */ - doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE); + doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE,NULL); needtoken(tTERM); lastst=tEXPR; sc_allowproccall=FALSE; @@ -5510,11 +5537,10 @@ static void compound(int stmt_sameline,int starttok) * Global references: stgidx (referred to only) */ static int doexpr(int comma,int chkeffect,int allowarray,int mark_endexpr, - int *tag,symbol **symptr,int chkfuncresult) + int *tag,symbol **symptr,int chkfuncresult,cell *val) { int index,ident; int localstaging=FALSE; - cell val; if (!staging) { stgset(TRUE); /* start stage-buffering */ @@ -5528,7 +5554,8 @@ static int doexpr(int comma,int chkeffect,int allowarray,int mark_endexpr, if (index!=stgidx) markexpr(sEXPR,NULL,0); pc_sideeffect=FALSE; - ident=expression(&val,tag,symptr,chkfuncresult); + pc_ovlassignment=FALSE; + ident=expression(val,tag,symptr,chkfuncresult); if (!allowarray && (ident==iARRAY || ident==iREFARRAY)) error(33,"-unknown-"); /* array must be indexed */ if (chkeffect && !pc_sideeffect) @@ -5668,6 +5695,7 @@ static int doif(void) ifindent=stmtindent; /* save the indent of the "if" instruction */ flab1=getlabel(); /* get label number for false branch */ test(flab1,TEST_THEN,FALSE); /* get expression, branch to flab1 if false */ + clearassignments(&loctab); statement(NULL,FALSE); /* if true, do a statement */ if (!matchtoken(tELSE)) { /* if...else ? */ setlabel(flab1); /* no, simple if..., print false label */ @@ -5677,6 +5705,7 @@ static int doif(void) * has a lower indent than the matching "if" */ if (stmtindent0) error(217); /* loose indentation */ + clearassignments(&loctab); flab2=getlabel(); if ((lastst!=tRETURN) && (lastst!=tGOTO)) jumplabel(flab2); /* "true" branch jumps around "else" clause, unless the "true" branch statement already jumped */ @@ -5707,7 +5736,9 @@ static int dowhile(void) */ setline(TRUE); endlessloop=test(wq[wqEXIT],TEST_DO,FALSE);/* branch to wq[wqEXIT] if false */ + clearassignments(&loctab); statement(NULL,FALSE); /* if so, do a statement */ + clearassignments(&loctab); jumplabel(wq[wqLOOP]); /* and loop to "while" start */ setlabel(wq[wqEXIT]); /* exit label */ delwhile(); /* delete queue entry */ @@ -5730,7 +5761,9 @@ static int dodo(void) addwhile(wq); /* see "dowhile" for more info */ top=getlabel(); /* make a label first */ setlabel(top); /* loop label */ + clearassignments(&loctab); statement(NULL,FALSE); + clearassignments(&loctab); needtoken(tWHILE); setlabel(wq[wqLOOP]); /* "continue" always jumps to WQLOOP. */ setline(TRUE); @@ -5769,7 +5802,7 @@ static int dofor(void) nestlevel++; declloc(FALSE); /* declare local variable */ } else { - doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE); /* expression 1 */ + doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE,NULL); /* expression 1 */ needtoken(';'); } /* if */ } /* if */ @@ -5804,13 +5837,15 @@ static int dofor(void) } /* if */ stgmark((char)(sEXPRSTART+1)); /* mark start of 3th expression in stage */ if (!matchtoken(endtok)) { - doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE); /* expression 3 */ + doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE,NULL); /* expression 3 */ needtoken(endtok); } /* if */ stgmark(sENDREORDER); /* mark end of reversed evaluation */ stgout(index); stgset(FALSE); /* stop staging */ + clearassignments(&loctab); statement(NULL,FALSE); + clearassignments(&loctab); jumplabel(wq[wqLOOP]); setlabel(wq[wqEXIT]); delwhile(); @@ -5858,7 +5893,7 @@ static void doswitch(void) char labelname[sNAMEMAX+1]; endtok= matchtoken('(') ? ')' : tDO; - doexpr(TRUE,FALSE,FALSE,FALSE,&swtag,NULL,TRUE);/* evaluate switch expression */ + doexpr(TRUE,FALSE,FALSE,FALSE,&swtag,NULL,TRUE,NULL);/* evaluate switch expression */ needtoken(endtok); /* generate the code for the switch statement, the label is the address * of the case table (to be generated later). @@ -5880,6 +5915,7 @@ static void doswitch(void) tok=lex(&val,&str); /* read in (new) token */ switch (tok) { case tCASE: + clearassignments(&loctab); if (swdefault!=FALSE) error(15); /* "default" case must be last in switch statement */ lbl_case=getlabel(); @@ -5947,6 +5983,7 @@ static void doswitch(void) jumplabel(lbl_exit); break; case tDEFAULT: + clearassignments(&loctab); if (swdefault!=FALSE) error(16); /* multiple defaults in switch */ lbl_case=getlabel(); @@ -6029,6 +6066,8 @@ static void dogoto(void) if (lex(&val,&st)==tSYMBOL) { sym=fetchlab(st); + if ((sym->usage & uDEFINE)!=0) + clearassignments(&loctab); jumplabel((int)sym->addr); sym->usage|=uREAD; /* set "uREAD" bit */ // ??? if the label is defined (check sym->usage & uDEFINE), check @@ -7587,7 +7626,7 @@ static void doreturn(void) /* "return " */ if ((rettype & uRETNONE)!=0) error(78); /* mix "return;" and "return value;" */ - ident=doexpr(TRUE,FALSE,TRUE,FALSE,&tag,&sym,TRUE); + ident=doexpr(TRUE,FALSE,TRUE,FALSE,&tag,&sym,TRUE,NULL); needtoken(tTERM); /* see if this function already has a sub type (an array attached) */ assert(curfunc!=NULL); @@ -7759,7 +7798,7 @@ static void doexit(void) int tag=0; if (matchtoken(tTERM)==0){ - doexpr(TRUE,FALSE,FALSE,FALSE,&tag,NULL,TRUE); + doexpr(TRUE,FALSE,FALSE,FALSE,&tag,NULL,TRUE,NULL); needtoken(tTERM); } else { ldconst(0,sPRI); @@ -7775,7 +7814,7 @@ static void dosleep(void) int tag=0; if (matchtoken(tTERM)==0){ - doexpr(TRUE,FALSE,FALSE,FALSE,&tag,NULL,TRUE); + doexpr(TRUE,FALSE,FALSE,FALSE,&tag,NULL,TRUE,NULL); needtoken(tTERM); } else { ldconst(0,sPRI); diff --git a/source/compiler/sc2.c b/source/compiler/sc2.c index 2d198c0b..08d7a20e 100644 --- a/source/compiler/sc2.c +++ b/source/compiler/sc2.c @@ -1013,6 +1013,7 @@ static int command(void) iflevel++; if (SKIPPING) break; /* break out of switch */ + clearassignments(&loctab); skiplevel=iflevel; preproc_expr(&val,NULL); /* get value (or 0 on error) */ ifstack[iflevel-1]=(char)(val ? PARSEMODE : SKIPMODE); @@ -1052,6 +1053,7 @@ static int command(void) } /* if */ } else { /* previous conditions were all FALSE */ + clearassignments(&loctab); if (tok==tpELSEIF) { /* if we were already skipping this section, allow expressions with * undefined symbols; otherwise check the expression to catch errors @@ -1078,6 +1080,7 @@ static int command(void) error(26); /* no matching "#if" */ errorset(sRESET,0); } else { + clearassignments(&loctab); iflevel--; if (iflevelusage |= read; if (sym->ident==iVARIABLE || sym->ident==iREFERENCE - || sym->ident==iARRAY || sym->ident==iREFARRAY) + || sym->ident==iARRAY || sym->ident==iREFARRAY) { sym->usage |= write; + sym->usage &= ~uASSIGNED; + } /* if */ } else { error(17,name); /* undefined symbol */ } /* if */ @@ -3180,6 +3185,8 @@ SC_FUNC void markusage(symbol *sym,int usage) sym->usage |= (char)usage; if ((usage & uWRITTEN)!=0) sym->lnumber=fline; + if ((usage & uREAD)!=0 && (sym->ident==iVARIABLE || sym->ident==iREFERENCE)) + sym->usage &= ~uASSIGNED; /* check if (global) reference must be added to the symbol */ if ((usage & (uREAD | uWRITTEN))!=0) { /* only do this for global symbols */ @@ -3192,6 +3199,27 @@ SC_FUNC void markusage(symbol *sym,int usage) } /* if */ } +SC_FUNC void markinitialized(symbol *sym,int assignment) +{ + assert(sym!=NULL); + if (sym->ident!=iVARIABLE && sym->ident!=iARRAY) + return; + if (sc_status==statFIRST && (sym->vclass==sLOCAL || sym->vclass==sSTATIC)) + return; + if (assignment && sym->ident==iVARIABLE) + sym->usage |= uASSIGNED; +} + +SC_FUNC void clearassignments(symbol *root) +{ + /* clear the unused assignment flag for all variables in the table */ + symbol *sym=root->next; + while (sym!=NULL) { + sym->usage &= ~uASSIGNED; + sym=sym->next; + } /* while */ +} + /* findglb * diff --git a/source/compiler/sc3.c b/source/compiler/sc3.c index e1c1545c..32625a60 100644 --- a/source/compiler/sc3.c +++ b/source/compiler/sc3.c @@ -190,6 +190,8 @@ static void (*unopers[])(void) = { lneg, neg, user_inc, user_dec }; if (sym==NULL /*|| (sym->usage & uDEFINE)==0*/) return FALSE; } /* if */ + if (oper==NULL) + pc_ovlassignment=TRUE; /* check existance and the proper declaration of this function */ if ((sym->usage & uMISSING)!=0 || (sym->usage & uPROTOTYPED)==0) { @@ -1063,6 +1065,15 @@ static int hier14(value *lval1) pc_sideeffect=TRUE; bitwise_opercount=bwcount; lval1->ident=iEXPRESSION; + if (oper==NULL) { + symbol *sym=lval3.sym; + assert(sym!=NULL); + if ((sym->usage & uASSIGNED)!=0 && (sym->vclass==sLOCAL || sym->vclass==sSTATIC)) + error(240,sym->name); /* previously assigned value is unused */ + markinitialized(sym,TRUE); + if (pc_ovlassignment) + markusage(sym,uREAD); + } /* if */ return FALSE; /* expression result is never an lvalue */ } diff --git a/source/compiler/sc5.c b/source/compiler/sc5.c index 34259735..441a6fce 100644 --- a/source/compiler/sc5.c +++ b/source/compiler/sc5.c @@ -196,7 +196,8 @@ static char *warnmsg[] = { /*236*/ "unknown parameter in substitution (incorrect #define pattern)\n", /*237*/ "user warning: %s\n", /*238*/ "meaningless combination of class specifiers (%s)\n", -/*239*/ "literal array/string passed to a non-const parameter\n" +/*239*/ "literal array/string passed to a non-const parameter\n", +/*240*/ "previously assigned value is never used (symbol \"%s\")\n" }; static char *noticemsg[] = { diff --git a/source/compiler/scvars.c b/source/compiler/scvars.c index 03271cd2..0c7a915c 100644 --- a/source/compiler/scvars.c +++ b/source/compiler/scvars.c @@ -80,6 +80,7 @@ SC_VDEFINE short fnumber=0; /* the file number in the file table SC_VDEFINE short fcurrent=0; /* current file being processed (debugging) */ SC_VDEFINE short sc_intest=FALSE; /* true if inside a test */ SC_VDEFINE int pc_sideeffect=FALSE; /* true if an expression causes a side-effect */ +SC_VDEFINE int pc_ovlassignment=FALSE; /* true if an expression contains an overloaded assignment */ SC_VDEFINE int stmtindent=0; /* current indent of the statement */ SC_VDEFINE int indent_nowarn=FALSE; /* skip warning "217 loose indentation" */ SC_VDEFINE int sc_tabsize=8; /* number of spaces that a TAB represents */ diff --git a/source/compiler/tests/md_array_size_chk_gh_314.pwn b/source/compiler/tests/md_array_size_chk_gh_314.pwn index f926648c..c1a5c0e1 100644 --- a/source/compiler/tests/md_array_size_chk_gh_314.pwn +++ b/source/compiler/tests/md_array_size_chk_gh_314.pwn @@ -28,9 +28,9 @@ main () { arr5[0][0] = 0; new a = sizeof(arr1); - a = sizeof(arr1[]); - a = sizeof(arr5[][]); - #pragma unused a + new b = sizeof(arr1[]); + new c = sizeof(arr5[][]); + #pragma unused a, b, c f1(arr1); f2(arr2); diff --git a/source/compiler/tests/warning_240.meta b/source/compiler/tests/warning_240.meta new file mode 100644 index 00000000..0758308d --- /dev/null +++ b/source/compiler/tests/warning_240.meta @@ -0,0 +1,18 @@ +{ + 'test_type': 'output_check', + 'errors': """ +warning_240.pwn(11) : warning 240: previously assigned value is never used (symbol "local_var") +warning_240.pwn(12) : warning 240: previously assigned value is never used (symbol "local_var") +warning_240.pwn(14) : warning 204: symbol is assigned a value that is never used: "local_var" +warning_240.pwn(31) : warning 204: symbol is assigned a value that is never used: "local_var2" +warning_240.pwn(25) : warning 204: symbol is assigned a value that is never used: "local_var" +warning_240.pwn(53) : warning 204: symbol is assigned a value that is never used: "local_var2" +warning_240.pwn(63) : warning 240: previously assigned value is never used (symbol "local_static_var") +warning_240.pwn(64) : warning 240: previously assigned value is never used (symbol "local_static_var") +warning_240.pwn(89) : warning 240: previously assigned value is never used (symbol "arg") +warning_240.pwn(90) : warning 240: previously assigned value is never used (symbol "arg") +warning_240.pwn(90) : warning 204: symbol is assigned a value that is never used: "arg" +warning_240.pwn(96) : warning 204: symbol is assigned a value that is never used: "arg" +warning_240.pwn(103) : warning 204: symbol is assigned a value that is never used: "arg" +""" +} diff --git a/source/compiler/tests/warning_240.pwn b/source/compiler/tests/warning_240.pwn new file mode 100644 index 00000000..dc0f05b0 --- /dev/null +++ b/source/compiler/tests/warning_240.pwn @@ -0,0 +1,131 @@ +#include +#include + +new global_var; +static global_static_var; + +test_local() +{ + new local_var; + local_var = 1; + local_var = 2; // warning 240 + local_var = 3; // warning 240 + #pragma unused local_var + local_var = 4; // warning 204 + new local_var2 = 0; + local_var2 = 1; + #pragma unused local_var2 +} + +test_local2() +{ + new local_var, local_var2; + if (random(2)) + { + local_var = 1; // warning 204 + } + switch (random(2)) + { + case 0: + { + local_var2 = 1; // warning 204 + } + } +} + +test_goto() +{ + { + new local_var; + #pragma unused local_var +lbl_1: + if (random(2)) + { + local_var = 1; // no warning(s) + goto lbl_1; + } + } + { + new local_var2; + #pragma unused local_var2 + if (random(2)) + { + local_var2 = 1; // warning 204 + goto lbl_2; + } +lbl_2: + } +} + +test_local_static() +{ + static local_static_var = 0; + local_static_var = 1; // warning 240 + local_static_var = 2; // warning 240 + #pragma unused local_static_var + local_static_var = 4; +} + +test_global() +{ + global_var = 1; + global_var = 2; + global_var = 3; + #pragma unused global_var + global_var = 4; +} + +test_global_static() +{ + global_static_var = 1; + global_static_var = 2; + global_static_var = 3; + #pragma unused global_static_var + global_static_var = 4; +} + +test_arg1(arg) +{ + arg = 0; // warning 240 + arg = 1; // warning 240, warning 204 +} + +test_arg2(arg) +{ + if (arg) + arg = 1; // warning 204 +} + +test_arg3(arg) +{ + switch (arg) + { + case 0: arg = 1; // warning 204 + } +} + +stock Tag:operator =(oper) + return Tag:oper; + +test_ovl_assignment() +{ + // Overloaded assignments are essentially function calls which may have + // desirable side effects, so they shouldn't trigger warning 204. + new Tag:a = 1; + new Tag:b; + b = 2; +} + +main() +{ + test_local(); + test_local2(); + test_goto(); + test_local_static(); + test_global(); + test_global_static(); + test_arg1(1); + test_arg2(1); + test_arg3(1); + test_ovl_assignment(); +}