Merge pull request #259 from alliedmodders/rm-sizeof-defarg

Remove sizeof() as a special-case default argument value.
This commit is contained in:
David Anderson 2015-02-03 12:44:00 -08:00
commit 7e9b22cb6e
7 changed files with 15 additions and 148 deletions

View File

@ -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"

View File

@ -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;

View File

@ -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 */

View File

@ -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++;

View File

@ -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

View File

@ -0,0 +1,9 @@
stock void crab(int[] eggs, int numEggs = sizeof(eggs))
{
}
public main()
{
int eggs[12];
crab(eggs);
}

View File

@ -0,0 +1 @@
(1) : error 163: indeterminate array size in "sizeof" expression (symbol "eggs")