From 66bbe6c4df3593c28fcc229b04c2be428d1da070 Mon Sep 17 00:00:00 2001 From: Yashas Date: Wed, 3 Oct 2018 17:05:10 +0530 Subject: [PATCH 1/6] share usage information across function definitions --- source/compiler/sc1.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index fcec5ec..6c8281f 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); @@ -3680,8 +3680,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; @@ -3857,6 +3857,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); @@ -4001,7 +4021,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) { @@ -4116,7 +4136,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; @@ -4210,6 +4230,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) From b32aea5faf3cf5168cf69b1143de6b49853f0879 Mon Sep 17 00:00:00 2001 From: Yashas Date: Tue, 16 Oct 2018 23:07:47 +0530 Subject: [PATCH 2/6] add test for issue #371 --- .../tests/share_arg_flags_fstates_gh_371.meta | 7 +++ .../tests/share_arg_flags_fstates_gh_371.pwn | 55 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 source/compiler/tests/share_arg_flags_fstates_gh_371.meta create mode 100644 source/compiler/tests/share_arg_flags_fstates_gh_371.pwn 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); +} From b7fd80382a3481acfcb4e1335cee7071fda064f3 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Fri, 5 Jul 2019 19:10:09 +0700 Subject: [PATCH 3/6] __emit: Do not allow pseudo-opcodes to modify constant variables/arrays --- source/compiler/sc1.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 1314e52..b39d64d 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6063,8 +6063,9 @@ static regid SC_FASTCALL emit_findreg(char *opname) * Looks for an lvalue and generates code to get cell address in PRI * if the lvalue is an array element (iARRAYCELL or iARRAYCHAR). */ -static int SC_FASTCALL emit_getlval(int *identptr,emit_outval *p,int *islocal, regid reg, - int allow_char, int store_pri,int store_alt,int *ispushed) +static int SC_FASTCALL emit_getlval(int *identptr,emit_outval *p,int *islocal, + regid reg,int allow_char,int allow_const, + int store_pri,int store_alt,int *ispushed) { int tok,index,ident,close; cell cidx,val,length; @@ -6095,6 +6096,8 @@ invalid_lvalue: return FALSE; } /* if */ markusage(sym,uREAD | uWRITTEN); + if (!allow_const && (sym->usage & uCONST)!=0) + goto invalid_lvalue; p->type=eotNUMBER; switch (sym->ident) @@ -6430,7 +6433,8 @@ static void SC_FASTCALL emit_param_integer(emit_outval *p) emit_param_any_internal(p,tNUMBER,FALSE,TRUE); } -static void SC_FASTCALL emit_param_index(emit_outval *p,int isrange,const cell *valid_values,int numvalues) +static void SC_FASTCALL emit_param_index(emit_outval *p,int isrange, + const cell *valid_values,int numvalues) { int i; cell val; @@ -7069,7 +7073,7 @@ static void SC_FASTCALL emit_do_stor_u_pri_alt(char *name) int ident,islocal,ispushed; reg=emit_findreg(name); - if (!emit_getlval(&ident,&p[0],&islocal,sALT,TRUE,(reg==sPRI),(reg==sALT),&ispushed)) + if (!emit_getlval(&ident,&p[0],&islocal,sALT,TRUE,FALSE,(reg==sPRI),(reg==sALT),&ispushed)) return; switch (ident) { case iVARIABLE: @@ -7105,7 +7109,7 @@ static void SC_FASTCALL emit_do_addr_u_pri_alt(char *name) int ident,islocal; reg=emit_findreg(name); - if (!emit_getlval(&ident,&p[0],&islocal,reg,TRUE,FALSE,FALSE,NULL)) + if (!emit_getlval(&ident,&p[0],&islocal,reg,TRUE,TRUE,FALSE,FALSE,NULL)) return; switch (ident) { case iVARIABLE: @@ -7156,7 +7160,7 @@ static void SC_FASTCALL emit_do_push_u_adr(char *name) emit_outval p[1]; int ident,islocal; - if (!emit_getlval(&ident,&p[0],&islocal,sPRI,FALSE,FALSE,FALSE,NULL)) + if (!emit_getlval(&ident,&p[0],&islocal,sPRI,FALSE,TRUE,FALSE,FALSE,NULL)) return; switch (ident) { case iVARIABLE: @@ -7180,7 +7184,7 @@ static void SC_FASTCALL emit_do_zero_u(char *name) emit_outval p[1]; int ident,islocal; - if (!emit_getlval(&ident,&p[0],&islocal,sALT,TRUE,FALSE,FALSE,NULL)) + if (!emit_getlval(&ident,&p[0],&islocal,sALT,TRUE,FALSE,FALSE,FALSE,NULL)) return; switch (ident) { case iVARIABLE: @@ -7212,7 +7216,7 @@ static void SC_FASTCALL emit_do_inc_dec_u(char *name) assert(strcmp(name,"inc.u")==0 || strcmp(name,"dec.u")==0); - if (!emit_getlval(&ident,&p[0],&islocal,sPRI,TRUE,FALSE,FALSE,NULL)) + if (!emit_getlval(&ident,&p[0],&islocal,sPRI,TRUE,FALSE,FALSE,FALSE,NULL)) return; switch (ident) { case iVARIABLE: @@ -7417,7 +7421,6 @@ static int emit_findopcode(const char *instr) high=(sizeof emit_opcodelist / sizeof emit_opcodelist[0])-1; while (low0) low=mid+1; From 448aa3b0517a48bf1eb23e143716a1d2543f0ee2 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Fri, 5 Jul 2019 19:10:25 +0700 Subject: [PATCH 4/6] Update tests for __emit --- source/compiler/tests/__emit.inc | 1 + source/compiler/tests/__emit_p6.meta | 21 +++++++++++---------- source/compiler/tests/__emit_p6.pwn | 4 +++- source/compiler/tests/__emit_p7.meta | 24 +++++++++++++----------- source/compiler/tests/__emit_p7.pwn | 7 +++++-- 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/source/compiler/tests/__emit.inc b/source/compiler/tests/__emit.inc index 834ec6d..3febc1e 100644 --- a/source/compiler/tests/__emit.inc +++ b/source/compiler/tests/__emit.inc @@ -3,5 +3,6 @@ const global_const = 0; new stock global_var = 0; new stock global_array[2]; +new stock const global_const_var = 0; forward global_func(); public global_func() { return 0; } native global_native(const string[]) = print; diff --git a/source/compiler/tests/__emit_p6.meta b/source/compiler/tests/__emit_p6.meta index d747d6d..81b62b3 100644 --- a/source/compiler/tests/__emit_p6.meta +++ b/source/compiler/tests/__emit_p6.meta @@ -9,17 +9,18 @@ __emit_p6.pwn(45) : error 022: must be lvalue (non-constant) __emit_p6.pwn(46) : error 022: must be lvalue (non-constant) __emit_p6.pwn(47) : error 022: must be lvalue (non-constant) __emit_p6.pwn(48) : error 022: must be lvalue (non-constant) -__emit_p6.pwn(49) : error 033: array must be indexed (variable "local_array") -__emit_p6.pwn(50) : error 033: array must be indexed (variable "local_refarray") -__emit_p6.pwn(69) : error 022: must be lvalue (non-constant) -__emit_p6.pwn(70) : error 022: must be lvalue (non-constant) +__emit_p6.pwn(49) : error 022: must be lvalue (non-constant) +__emit_p6.pwn(50) : error 033: array must be indexed (variable "local_array") +__emit_p6.pwn(51) : error 033: array must be indexed (variable "local_refarray") __emit_p6.pwn(71) : error 022: must be lvalue (non-constant) __emit_p6.pwn(72) : error 022: must be lvalue (non-constant) -__emit_p6.pwn(73) : error 033: array must be indexed (variable "local_array") -__emit_p6.pwn(74) : error 033: array must be indexed (variable "local_refarray") -__emit_p6.pwn(96) : error 076: syntax error in the expression, or invalid function call -__emit_p6.pwn(97) : error 076: syntax error in the expression, or invalid function call -__emit_p6.pwn(98) : error 033: array must be indexed (variable "local_array") -__emit_p6.pwn(99) : error 033: array must be indexed (variable "local_refarray") +__emit_p6.pwn(73) : error 022: must be lvalue (non-constant) +__emit_p6.pwn(74) : error 022: must be lvalue (non-constant) +__emit_p6.pwn(75) : error 033: array must be indexed (variable "local_array") +__emit_p6.pwn(76) : error 033: array must be indexed (variable "local_refarray") +__emit_p6.pwn(98) : error 076: syntax error in the expression, or invalid function call +__emit_p6.pwn(99) : error 076: syntax error in the expression, or invalid function call +__emit_p6.pwn(100) : error 033: array must be indexed (variable "local_array") +__emit_p6.pwn(101) : error 033: array must be indexed (variable "local_refarray") """ } diff --git a/source/compiler/tests/__emit_p6.pwn b/source/compiler/tests/__emit_p6.pwn index 0e9a543..ca09b7b 100644 --- a/source/compiler/tests/__emit_p6.pwn +++ b/source/compiler/tests/__emit_p6.pwn @@ -45,6 +45,7 @@ stock test__op_stor_u_pri_alt(&local_refvar, local_refarray[]) emit stor.u.pri global_const; emit stor.u.pri global_func; emit stor.u.pri global_native; + emit stor.u.pri global_const_var; emit stor.u.pri local_const; emit stor.u.pri local_array; emit stor.u.pri local_refarray; @@ -59,6 +60,7 @@ stock test__op_addr_u_pri_alt(&local_refvar, local_refarray[]) // ok emit addr.u.pri global_var; + emit addr.u.pri global_const_var; emit addr.u.pri local_var; emit addr.u.pri local_static_var; emit addr.u.pri local_refvar; @@ -104,7 +106,7 @@ main() { new t, a[2]; test__op_load_u_pri_alt(t, a); // 4 - test__op_stor_u_pri_alt(t, a); // 6 + test__op_stor_u_pri_alt(t, a); // 7 test__op_addr_u_pri_alt(t, a); // 6 test__push_u(t, a); // 4 } diff --git a/source/compiler/tests/__emit_p7.meta b/source/compiler/tests/__emit_p7.meta index e32da8a..a9c185f 100644 --- a/source/compiler/tests/__emit_p7.meta +++ b/source/compiler/tests/__emit_p7.meta @@ -1,25 +1,27 @@ { 'test_type': 'output_check', 'errors': """ -__emit_p7.pwn(20) : error 022: must be lvalue (non-constant) __emit_p7.pwn(21) : error 022: must be lvalue (non-constant) __emit_p7.pwn(22) : error 022: must be lvalue (non-constant) __emit_p7.pwn(23) : error 022: must be lvalue (non-constant) -__emit_p7.pwn(24) : error 033: array must be indexed (variable "local_array") -__emit_p7.pwn(25) : error 033: array must be indexed (variable "local_refarray") -__emit_p7.pwn(26) : error 035: argument type mismatch (argument 1) +__emit_p7.pwn(24) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(25) : error 033: array must be indexed (variable "local_array") +__emit_p7.pwn(26) : error 033: array must be indexed (variable "local_refarray") __emit_p7.pwn(27) : error 035: argument type mismatch (argument 1) -__emit_p7.pwn(46) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(28) : error 035: argument type mismatch (argument 1) __emit_p7.pwn(47) : error 022: must be lvalue (non-constant) __emit_p7.pwn(48) : error 022: must be lvalue (non-constant) __emit_p7.pwn(49) : error 022: must be lvalue (non-constant) -__emit_p7.pwn(50) : error 033: array must be indexed (variable "local_array") -__emit_p7.pwn(51) : error 033: array must be indexed (variable "local_refarray") -__emit_p7.pwn(70) : error 022: must be lvalue (non-constant) -__emit_p7.pwn(71) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(50) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(51) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(52) : error 033: array must be indexed (variable "local_array") +__emit_p7.pwn(53) : error 033: array must be indexed (variable "local_refarray") __emit_p7.pwn(72) : error 022: must be lvalue (non-constant) __emit_p7.pwn(73) : error 022: must be lvalue (non-constant) -__emit_p7.pwn(74) : error 033: array must be indexed (variable "local_array") -__emit_p7.pwn(75) : error 033: array must be indexed (variable "local_refarray") +__emit_p7.pwn(74) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(75) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(76) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(77) : error 033: array must be indexed (variable "local_array") +__emit_p7.pwn(78) : error 033: array must be indexed (variable "local_refarray") """ } diff --git a/source/compiler/tests/__emit_p7.pwn b/source/compiler/tests/__emit_p7.pwn index 65e7773..0ee4e44 100644 --- a/source/compiler/tests/__emit_p7.pwn +++ b/source/compiler/tests/__emit_p7.pwn @@ -10,6 +10,7 @@ stock test__push_u_adr(&local_refvar, local_refarray[]) // ok emit push.u.adr global_var; + emit push.u.adr global_const_var; emit push.u.adr local_refvar; emit push.u.adr local_var; emit push.u.adr local_static_var; @@ -46,6 +47,7 @@ stock test__zero_u(&local_refvar, local_refarray[]) emit zero.u global_const; emit zero.u global_func; emit zero.u global_native; + emit zero.u global_const_var; emit zero.u local_const; emit zero.u local_array; emit zero.u local_refarray; @@ -70,6 +72,7 @@ stock test__inc_dec_u(&local_refvar, local_refarray[]) emit inc.u global_const; emit inc.u global_func; emit inc.u global_native; + emit inc.u global_const_var; emit inc.u local_const; emit inc.u local_array; emit inc.u local_refarray; @@ -80,6 +83,6 @@ main() { new t, a[2]; test__push_u_adr(t, a); // 8 - test__zero_u(t, a); // 6 - test__inc_dec_u(t, a); // 6 + test__zero_u(t, a); // 7 + test__inc_dec_u(t, a); // 7 } From 913eac5e3dea8125e7a6d47d6398f30d3eb660ad Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Fri, 26 Jul 2019 20:08:52 +0700 Subject: [PATCH 5/6] Revert "disable 239 for native functions" This reverts commit 8948f207ea9c7cef4e7808751a499310d1407148. --- source/compiler/sc3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/compiler/sc3.c b/source/compiler/sc3.c index 993e358..f87274c 100644 --- a/source/compiler/sc3.c +++ b/source/compiler/sc3.c @@ -2216,7 +2216,7 @@ static int nesting=0; if (arg[argidx].numdim!=1) { error(48); /* array dimensions must match */ } else { - if (lval.sym==NULL && (arg[argidx].usage & uCONST)==0 && (sym->usage & uNATIVE)==0) + if (lval.sym==NULL && (arg[argidx].usage & uCONST)==0) error(239); if (arg[argidx].dim[0]!=0) { assert(arg[argidx].dim[0]>0); From 3f87cf177352d2fa7f6f793d51cf77c9dbdd62a1 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Fri, 26 Jul 2019 20:21:36 +0700 Subject: [PATCH 6/6] Update tests for 239 --- source/compiler/tests/const_array_args_and_literals_gh_276.meta | 1 + 1 file changed, 1 insertion(+) diff --git a/source/compiler/tests/const_array_args_and_literals_gh_276.meta b/source/compiler/tests/const_array_args_and_literals_gh_276.meta index 861e659..1dc0f51 100644 --- a/source/compiler/tests/const_array_args_and_literals_gh_276.meta +++ b/source/compiler/tests/const_array_args_and_literals_gh_276.meta @@ -7,5 +7,6 @@ const_array_args_and_literals_gh_276.pwn(30) : warning 214: possibly a "const" a const_array_args_and_literals_gh_276.pwn(39) : warning 239: literal array/string passed to a non-const parameter const_array_args_and_literals_gh_276.pwn(40) : warning 239: literal array/string passed to a non-const parameter const_array_args_and_literals_gh_276.pwn(41) : warning 239: literal array/string passed to a non-const parameter +const_array_args_and_literals_gh_276.pwn(60) : warning 239: literal array/string passed to a non-const parameter """ }