diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 4ef25b8..103cc0d 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -108,7 +108,7 @@ static void funcstub(int fnative); static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stock); static int declargs(symbol *sym,int chkshadow); static void doarg(char *name,int ident,int offset,int tags[],int numtags, - int fpublic,int fconst,int chkshadow,arginfo *arg); + int fpublic,int fconst,int written,int chkshadow,arginfo *arg); static void make_report(symbol *root,FILE *log,char *sourcefile); static void reduce_referrers(symbol *root); static long max_stacksize(symbol *root,int *recursion); @@ -3697,8 +3697,8 @@ static void funcstub(int fnative) */ static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stock) { - symbol *sym; - int argcnt,tok,tag,funcline; + symbol *sym,*lvar,*depend; + int argcnt,tok,tag,funcline,i; int opertok,opererror; char symbolname[sNAMEMAX+1]; char *str; @@ -3874,6 +3874,26 @@ static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stoc dumplits(); /* dump literal strings */ litidx=0; } /* if */ + for (i=0; idim.arglist[i].ident==iREFARRAY) { + lvar=findloc(sym->dim.arglist[i].name); + assert(lvar!=NULL); + if ((sym->dim.arglist[i].usage & uWRITTEN)==0) { + /* check if the argument was written in this definition */ + depend=lvar; + while (depend!=NULL) { + if ((depend->usage & uWRITTEN)!=0) { + sym->dim.arglist[i].usage|=depend->usage & uWRITTEN; + break; + } + depend=finddepend(depend); + } /* while */ + } /* if */ + /* mark argument as written if it was written in another definition */ + lvar->usage|=sym->dim.arglist[i].usage & uWRITTEN; + } /* if */ + } /* for */ + testsymbols(&loctab,0,TRUE,TRUE); /* test for unused arguments and labels */ delete_symbols(&loctab,0,TRUE,TRUE); /* clear local variables queue */ assert(loctab.next==NULL); @@ -4018,7 +4038,7 @@ static int declargs(symbol *sym,int chkshadow) * base + 3*sizeof(cell) == first argument of the function * So the offset of each argument is "(argcnt+3) * sizeof(cell)". */ - doarg(name,ident,(argcnt+3)*sizeof(cell),tags,numtags,fpublic,fconst,chkshadow,&arg); + doarg(name,ident,(argcnt+3)*sizeof(cell),tags,numtags,fpublic,fconst,!!(sym->dim.arglist[argcnt].usage & uWRITTEN),chkshadow,&arg); if (fpublic && arg.hasdefault) error(59,name); /* arguments of a public function may not have a default value */ if ((sym->usage & uPROTOTYPED)==0) { @@ -4135,7 +4155,7 @@ static int declargs(symbol *sym,int chkshadow) * The arguments themselves are never public. */ static void doarg(char *name,int ident,int offset,int tags[],int numtags, - int fpublic,int fconst,int chkshadow,arginfo *arg) + int fpublic,int fconst,int written,int chkshadow,arginfo *arg) { symbol *argsym; constvalue_root *enumroot=NULL; @@ -4229,6 +4249,7 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags, } /* if */ arg->ident=(char)ident; arg->usage=(char)(fconst ? uCONST : 0); + arg->usage|=(char)(written ? uWRITTEN : 0); arg->numtags=numtags; arg->tags=(int*)malloc(numtags*sizeof tags[0]); if (arg->tags==NULL) diff --git a/source/compiler/tests/share_arg_flags_fstates_gh_371.meta b/source/compiler/tests/share_arg_flags_fstates_gh_371.meta new file mode 100644 index 0000000..51ea5e9 --- /dev/null +++ b/source/compiler/tests/share_arg_flags_fstates_gh_371.meta @@ -0,0 +1,7 @@ +{ + 'test_type': 'output_check', + 'errors': """ +share_arg_flags_fstates_gh_371.pwn(1) : warning 214: possibly a "const" array argument was intended: "str" +share_arg_flags_fstates_gh_371.pwn(7) : warning 214: possibly a "const" array argument was intended: "str" +""" +} diff --git a/source/compiler/tests/share_arg_flags_fstates_gh_371.pwn b/source/compiler/tests/share_arg_flags_fstates_gh_371.pwn new file mode 100644 index 0000000..6c1e3a8 --- /dev/null +++ b/source/compiler/tests/share_arg_flags_fstates_gh_371.pwn @@ -0,0 +1,55 @@ +f0(str[]) +{ + new a = str[0]; + #pragma unused a +} + +f0(str[]) +{ + new a = str[0] + str[1]; + #pragma unused a +} + +f1(str[]) +{ + new a = str[0]; + #pragma unused a +} + +f1(str[]) +{ + str[0] = 5; +} + +f2(const str[]) +{ + new a = str[0]; + #pragma unused a +} + +f2(const str[]) +{ + new a = str[0] + str[1]; + #pragma unused a +} + +f3(str[]) +{ + str[0] = 5; +} + +f3(str[]) +{ + new a = str[0]; + #pragma unused a +} + +main() +{ + state fstate : a; + new arr[10]; + f0(arr); + f1(arr); + f2(arr); + f3(arr); +}