Merge pull request #259 from alliedmodders/rm-sizeof-defarg
Remove sizeof() as a special-case default argument value.
This commit is contained in:
commit
7e9b22cb6e
@ -79,10 +79,6 @@ typedef struct s_arginfo { /* function argument info */
|
|||||||
unsigned char hasdefault; /* bit0: is there a default value? bit6: "tagof"; bit7: "sizeof" */
|
unsigned char hasdefault; /* bit0: is there a default value? bit6: "tagof"; bit7: "sizeof" */
|
||||||
union {
|
union {
|
||||||
cell val; /* default value */
|
cell val; /* default value */
|
||||||
struct {
|
|
||||||
char *symname; /* name of another symbol */
|
|
||||||
short level; /* indirection level for that symbol */
|
|
||||||
} size; /* used for "sizeof" default value */
|
|
||||||
struct {
|
struct {
|
||||||
cell *data; /* values of default array */
|
cell *data; /* values of default array */
|
||||||
int size; /* complete length of default array */
|
int size; /* complete length of default array */
|
||||||
@ -230,10 +226,6 @@ typedef struct s_symbol {
|
|||||||
|
|
||||||
#define flgDEPRECATED 0x01 /* symbol is deprecated (avoid use) */
|
#define flgDEPRECATED 0x01 /* symbol is deprecated (avoid use) */
|
||||||
|
|
||||||
#define uCOUNTOF 0x20 /* set in the "hasdefault" field of the arginfo struct */
|
|
||||||
#define uTAGOF 0x40 /* set in the "hasdefault" field of the arginfo struct */
|
|
||||||
#define uSIZEOF 0x80 /* set in the "hasdefault" field of the arginfo struct */
|
|
||||||
|
|
||||||
#define uMAINFUNC "main"
|
#define uMAINFUNC "main"
|
||||||
#define uENTRYFUNC "entry"
|
#define uENTRYFUNC "entry"
|
||||||
|
|
||||||
|
@ -5612,12 +5612,7 @@ static int argcompare(arginfo *a1,arginfo *a2)
|
|||||||
* Pawn currently does not forbid them) */
|
* Pawn currently does not forbid them) */
|
||||||
} else {
|
} else {
|
||||||
if (result) {
|
if (result) {
|
||||||
if ((a1->hasdefault & uSIZEOF)!=0 || (a1->hasdefault & uTAGOF)!=0 || (a1->hasdefault & uCOUNTOF)!=0)
|
result= a1->defvalue.val==a2->defvalue.val;
|
||||||
result= a1->hasdefault==a2->hasdefault
|
|
||||||
&& strcmp(a1->defvalue.size.symname,a2->defvalue.size.symname)==0
|
|
||||||
&& a1->defvalue.size.level==a2->defvalue.size.level;
|
|
||||||
else
|
|
||||||
result= a1->defvalue.val==a2->defvalue.val;
|
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* if */
|
} /* if */
|
||||||
if (result)
|
if (result)
|
||||||
@ -5754,9 +5749,6 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
|
|||||||
/* may need to free default array argument and the tag list */
|
/* may need to free default array argument and the tag list */
|
||||||
if (arg.ident==iREFARRAY && arg.hasdefault)
|
if (arg.ident==iREFARRAY && arg.hasdefault)
|
||||||
free(arg.defvalue.array.data);
|
free(arg.defvalue.array.data);
|
||||||
else if ((arg.ident==iVARIABLE
|
|
||||||
&& ((arg.hasdefault & uSIZEOF)!=0 || (arg.hasdefault & uTAGOF)!=0)) || (arg.hasdefault & uCOUNTOF)!=0)
|
|
||||||
free(arg.defvalue.size.symname);
|
|
||||||
free(arg.tags);
|
free(arg.tags);
|
||||||
} /* if */
|
} /* if */
|
||||||
argcnt++;
|
argcnt++;
|
||||||
@ -5764,47 +5756,6 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
|
|||||||
/* if the next token is not ",", it should be ")" */
|
/* if the next token is not ",", it should be ")" */
|
||||||
needtoken(')');
|
needtoken(')');
|
||||||
} /* if */
|
} /* if */
|
||||||
/* resolve any "sizeof" arguments (now that all arguments are known) */
|
|
||||||
assert(sym->dim.arglist!=NULL);
|
|
||||||
arglist=sym->dim.arglist;
|
|
||||||
for (idx=0; idx<argcnt && arglist[idx].ident!=0; idx++) {
|
|
||||||
if ((arglist[idx].hasdefault & uSIZEOF)!=0
|
|
||||||
|| (arglist[idx].hasdefault & uTAGOF)!=0
|
|
||||||
|| (arglist[idx].hasdefault & uCOUNTOF)!=0) {
|
|
||||||
int altidx;
|
|
||||||
/* Find the argument with the name mentioned after the "sizeof". Note
|
|
||||||
* that we cannot use findloc here because we need the arginfo struct,
|
|
||||||
* not the symbol.
|
|
||||||
*/
|
|
||||||
ptr=arglist[idx].defvalue.size.symname;
|
|
||||||
assert(ptr!=NULL);
|
|
||||||
for (altidx=0; altidx<argcnt && strcmp(ptr,arglist[altidx].name)!=0; altidx++)
|
|
||||||
/* nothing */;
|
|
||||||
if (altidx>=argcnt) {
|
|
||||||
error(17,ptr); /* undefined symbol */
|
|
||||||
} else {
|
|
||||||
assert(arglist[idx].defvalue.size.symname!=NULL);
|
|
||||||
/* check the level against the number of dimensions */
|
|
||||||
if (arglist[idx].defvalue.size.level>0
|
|
||||||
&& arglist[idx].defvalue.size.level>=arglist[altidx].numdim)
|
|
||||||
error(28,arglist[idx].name); /* invalid subscript */
|
|
||||||
/* check the type of the argument whose size to take; for a iVARIABLE
|
|
||||||
* or a iREFERENCE, this is always 1 (so the code is redundant)
|
|
||||||
*/
|
|
||||||
assert(arglist[altidx].ident!=iVARARGS);
|
|
||||||
if (arglist[altidx].ident!=iREFARRAY
|
|
||||||
&& (((arglist[idx].hasdefault & uSIZEOF)!=0)
|
|
||||||
|| (arglist[idx].hasdefault & uCOUNTOF)!=0)) {
|
|
||||||
if ((arglist[idx].hasdefault & uTAGOF)!=0) {
|
|
||||||
error(81,arglist[idx].name); /* cannot take "tagof" an indexed array */
|
|
||||||
} else {
|
|
||||||
assert(arglist[altidx].ident==iVARIABLE || arglist[altidx].ident==iREFERENCE);
|
|
||||||
error(223,ptr); /* redundant sizeof */
|
|
||||||
} /* if */
|
|
||||||
} /* if */
|
|
||||||
} /* if */
|
|
||||||
} /* if */
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
sym->usage|=uPROTOTYPED;
|
sym->usage|=uPROTOTYPED;
|
||||||
errorset(sRESET,0); /* reset error flag (clear the "panic mode")*/
|
errorset(sRESET,0); /* reset error flag (clear the "panic mode")*/
|
||||||
@ -5902,42 +5853,9 @@ static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, argi
|
|||||||
unsigned char size_tag_token;
|
unsigned char size_tag_token;
|
||||||
assert(type->ident==iVARIABLE || type->ident==iREFERENCE);
|
assert(type->ident==iVARIABLE || type->ident==iREFERENCE);
|
||||||
arg->hasdefault=TRUE; /* argument has a default value */
|
arg->hasdefault=TRUE; /* argument has a default value */
|
||||||
size_tag_token=(unsigned char)(matchtoken(tSIZEOF) ? uSIZEOF : 0);
|
exprconst(&arg->defvalue.val,&arg->defvalue_tag,NULL);
|
||||||
if (size_tag_token==0)
|
assert(type->numtags <= 1);
|
||||||
size_tag_token=(unsigned char)(matchtoken(tTAGOF) ? uTAGOF : 0);
|
matchtag(type->tags[0], arg->defvalue_tag, TRUE);
|
||||||
if (size_tag_token==0)
|
|
||||||
size_tag_token=(unsigned char)(matchtoken(tCELLSOF) ? uCOUNTOF : 0);
|
|
||||||
if (size_tag_token!=0) {
|
|
||||||
int paranthese;
|
|
||||||
if (type->ident==iREFERENCE)
|
|
||||||
error(66, decl->name); /* argument may not be a reference */
|
|
||||||
paranthese=0;
|
|
||||||
while (matchtoken('('))
|
|
||||||
paranthese++;
|
|
||||||
if (needtoken(tSYMBOL)) {
|
|
||||||
/* save the name of the argument whose size id to take */
|
|
||||||
char *name;
|
|
||||||
cell val;
|
|
||||||
tokeninfo(&val,&name);
|
|
||||||
if ((arg->defvalue.size.symname=duplicatestring(name)) == NULL)
|
|
||||||
error(FATAL_ERROR_OOM); /* insufficient memory */
|
|
||||||
arg->defvalue.size.level=0;
|
|
||||||
if (size_tag_token==uSIZEOF || size_tag_token==uCOUNTOF) {
|
|
||||||
while (matchtoken('[')) {
|
|
||||||
arg->defvalue.size.level+=(short)1;
|
|
||||||
needtoken(']');
|
|
||||||
} /* while */
|
|
||||||
} /* if */
|
|
||||||
if (type->ident==iVARIABLE) /* make sure we set this only if not a reference */
|
|
||||||
arg->hasdefault |= size_tag_token; /* uSIZEOF or uTAGOF */
|
|
||||||
} /* if */
|
|
||||||
while (paranthese--)
|
|
||||||
needtoken(')');
|
|
||||||
} else {
|
|
||||||
exprconst(&arg->defvalue.val,&arg->defvalue_tag,NULL);
|
|
||||||
assert(type->numtags > 0);
|
|
||||||
matchtag(type->tags[0], arg->defvalue_tag, TRUE);
|
|
||||||
} /* if */
|
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* if */
|
} /* if */
|
||||||
arg->ident=(char)type->ident;
|
arg->ident=(char)type->ident;
|
||||||
|
@ -2734,9 +2734,6 @@ static void free_symbol(symbol *sym)
|
|||||||
for (arg=sym->dim.arglist; arg->ident!=0; arg++) {
|
for (arg=sym->dim.arglist; arg->ident!=0; arg++) {
|
||||||
if (arg->ident==iREFARRAY && arg->hasdefault)
|
if (arg->ident==iREFARRAY && arg->hasdefault)
|
||||||
free(arg->defvalue.array.data);
|
free(arg->defvalue.array.data);
|
||||||
else if (arg->ident==iVARIABLE
|
|
||||||
&& ((arg->hasdefault & uSIZEOF)!=0 || (arg->hasdefault & uTAGOF)!=0))
|
|
||||||
free(arg->defvalue.size.symname);
|
|
||||||
assert(arg->tags!=NULL);
|
assert(arg->tags!=NULL);
|
||||||
free(arg->tags);
|
free(arg->tags);
|
||||||
} /* for */
|
} /* for */
|
||||||
|
@ -3009,13 +3009,6 @@ static int nesting=0;
|
|||||||
for (argidx=0; arg[argidx].ident!=0 && arg[argidx].ident!=iVARARGS; argidx++) {
|
for (argidx=0; arg[argidx].ident!=0 && arg[argidx].ident!=iVARARGS; argidx++) {
|
||||||
if (arglist[argidx]==ARG_DONE)
|
if (arglist[argidx]==ARG_DONE)
|
||||||
continue; /* already seen and handled this argument */
|
continue; /* already seen and handled this argument */
|
||||||
/* in this first stage, we also skip the arguments with uSIZEOF and uTAGOF;
|
|
||||||
* these are handled last
|
|
||||||
*/
|
|
||||||
if ((arg[argidx].hasdefault & uSIZEOF)!=0 || (arg[argidx].hasdefault & uTAGOF)!=0) {
|
|
||||||
assert(arg[argidx].ident==iVARIABLE);
|
|
||||||
continue;
|
|
||||||
} /* if */
|
|
||||||
stgmark((char)(sEXPRSTART+argidx));/* mark beginning of new expression in stage */
|
stgmark((char)(sEXPRSTART+argidx));/* mark beginning of new expression in stage */
|
||||||
if (arg[argidx].hasdefault) {
|
if (arg[argidx].hasdefault) {
|
||||||
if (arg[argidx].ident==iREFARRAY) {
|
if (arg[argidx].ident==iREFARRAY) {
|
||||||
@ -3063,49 +3056,6 @@ static int nesting=0;
|
|||||||
nargs++;
|
nargs++;
|
||||||
arglist[argidx]=ARG_DONE;
|
arglist[argidx]=ARG_DONE;
|
||||||
} /* for */
|
} /* for */
|
||||||
/* now a second loop to catch the arguments with default values that are
|
|
||||||
* the "sizeof" or "tagof" of other arguments
|
|
||||||
*/
|
|
||||||
for (argidx=0; arg[argidx].ident!=0 && arg[argidx].ident!=iVARARGS; argidx++) {
|
|
||||||
constvalue *asz;
|
|
||||||
cell array_sz;
|
|
||||||
if (arglist[argidx]==ARG_DONE)
|
|
||||||
continue; /* already seen and handled this argument */
|
|
||||||
stgmark((char)(sEXPRSTART+argidx));/* mark beginning of new expression in stage */
|
|
||||||
assert(arg[argidx].ident==iVARIABLE); /* if "sizeof", must be single cell */
|
|
||||||
/* if unseen, must be "sizeof" or "tagof" */
|
|
||||||
assert((arg[argidx].hasdefault & uSIZEOF)!=0 || (arg[argidx].hasdefault & uTAGOF)!=0);
|
|
||||||
if ((arg[argidx].hasdefault & uSIZEOF)!=0) {
|
|
||||||
/* find the argument; if it isn't found, the argument's default value
|
|
||||||
* was a "sizeof" of a non-array (a warning for this was already given
|
|
||||||
* when declaring the function)
|
|
||||||
*/
|
|
||||||
asz=find_constval(&arrayszlst,arg[argidx].defvalue.size.symname,
|
|
||||||
arg[argidx].defvalue.size.level);
|
|
||||||
if (asz!=NULL) {
|
|
||||||
array_sz=asz->value;
|
|
||||||
if (array_sz==0)
|
|
||||||
error(163,arg[argidx].name); /* indeterminate array size in "sizeof" expression */
|
|
||||||
} else {
|
|
||||||
array_sz=1;
|
|
||||||
} /* if */
|
|
||||||
} else {
|
|
||||||
asz=find_constval(&taglst,arg[argidx].defvalue.size.symname,
|
|
||||||
arg[argidx].defvalue.size.level);
|
|
||||||
if (asz != NULL) {
|
|
||||||
array_sz=asz->value; /* must be set, because it just was exported */
|
|
||||||
} else {
|
|
||||||
array_sz=0;
|
|
||||||
} /* if */
|
|
||||||
} /* if */
|
|
||||||
ldconst(array_sz,sPRI);
|
|
||||||
pushreg(sPRI); /* store the function argument on the stack */
|
|
||||||
markexpr(sPARM,NULL,0);
|
|
||||||
nest_stkusage++;
|
|
||||||
if (arglist[argidx]==ARG_UNHANDLED)
|
|
||||||
nargs++;
|
|
||||||
arglist[argidx]=ARG_DONE;
|
|
||||||
} /* for */
|
|
||||||
stgmark(sENDREORDER); /* mark end of reversed evaluation */
|
stgmark(sENDREORDER); /* mark end of reversed evaluation */
|
||||||
pushval((cell)nargs /* *sizeof(cell)*/ );
|
pushval((cell)nargs /* *sizeof(cell)*/ );
|
||||||
nest_stkusage++;
|
nest_stkusage++;
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
(2) : error 141: natives, forwards, and public functions cannot return arrays
|
(2) : error 141: natives, forwards, and public functions cannot return arrays
|
||||||
(3) : error 143: new-style declarations should not have "new"
|
(3) : error 143: new-style declarations should not have "new"
|
||||||
(5) : error 121: cannot specify array dimensions on both type and name
|
(5) : error 121: cannot specify array dimensions on both type and name
|
||||||
(9) : error 025: function heading differs from prototype
|
(11) : error 025: function heading differs from prototype
|
||||||
|
9
sourcepawn/compiler/tests/fail-sizeof-default-arg.sp
Normal file
9
sourcepawn/compiler/tests/fail-sizeof-default-arg.sp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
stock void crab(int[] eggs, int numEggs = sizeof(eggs))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public main()
|
||||||
|
{
|
||||||
|
int eggs[12];
|
||||||
|
crab(eggs);
|
||||||
|
}
|
1
sourcepawn/compiler/tests/fail-sizeof-default-arg.txt
Normal file
1
sourcepawn/compiler/tests/fail-sizeof-default-arg.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
(1) : error 163: indeterminate array size in "sizeof" expression (symbol "eggs")
|
Loading…
Reference in New Issue
Block a user