Improve reparse check
Only reparse if the function has a tagged result (old behavior) or a global variable is passed as one of its arguments at some point before declaration/definition. Also warn if need to reparse so that developers are aware of potential performance hit. Fixes #131.
This commit is contained in:
parent
f96f3b978b
commit
25b21eb0aa
@ -189,6 +189,7 @@ typedef struct s_symbol {
|
|||||||
* 6 (uSTOCK) the function is discardable (without warning)
|
* 6 (uSTOCK) the function is discardable (without warning)
|
||||||
* 7 (uMISSING) the function is not implemented in this source file
|
* 7 (uMISSING) the function is not implemented in this source file
|
||||||
* 8 (uFORWARD) the function is explicitly forwardly declared
|
* 8 (uFORWARD) the function is explicitly forwardly declared
|
||||||
|
* 9 (uGLOBALARGS) the function is called with global variables as arguments
|
||||||
*
|
*
|
||||||
* CONSTANT
|
* CONSTANT
|
||||||
* bits: 0 (uDEFINE) the symbol is defined in the source file
|
* bits: 0 (uDEFINE) the symbol is defined in the source file
|
||||||
@ -212,6 +213,7 @@ typedef struct s_symbol {
|
|||||||
#define uENUMFIELD 0x040
|
#define uENUMFIELD 0x040
|
||||||
#define uMISSING 0x080
|
#define uMISSING 0x080
|
||||||
#define uFORWARD 0x100
|
#define uFORWARD 0x100
|
||||||
|
#define uGLOBALARGS 0x200
|
||||||
/* uRETNONE is not stored in the "usage" field of a symbol. It is
|
/* uRETNONE is not stored in the "usage" field of a symbol. It is
|
||||||
* used during parsing a function, to detect a mix of "return;" and
|
* used during parsing a function, to detect a mix of "return;" and
|
||||||
* "return value;" in a few special cases.
|
* "return value;" in a few special cases.
|
||||||
|
@ -3338,8 +3338,14 @@ static void check_reparse(symbol *sym)
|
|||||||
* be marked as read (uREAD) and may therefore be omitted from the
|
* be marked as read (uREAD) and may therefore be omitted from the
|
||||||
* resulting P-code
|
* resulting P-code
|
||||||
*/
|
*/
|
||||||
if ((sym->usage & (uPROTOTYPED | uREAD))==uREAD)
|
if ((sym->usage & (uPROTOTYPED | uREAD))==uREAD
|
||||||
|
&& (sym->tag!=0 || (sym->usage & uGLOBALARGS)!=0)) {
|
||||||
|
int curstatus=sc_status;
|
||||||
|
sc_status=statWRITE; /* temporarily set status to WRITE, so the warning isn't blocked */
|
||||||
|
error(208);
|
||||||
|
sc_status=curstatus;
|
||||||
sc_reparse=TRUE; /* must add another pass to "initial scan" phase */
|
sc_reparse=TRUE; /* must add another pass to "initial scan" phase */
|
||||||
|
} /* if */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void funcstub(int fnative)
|
static void funcstub(int fnative)
|
||||||
@ -3742,7 +3748,7 @@ static int declargs(symbol *sym,int chkshadow)
|
|||||||
ident=iVARIABLE;
|
ident=iVARIABLE;
|
||||||
numtags=0;
|
numtags=0;
|
||||||
fconst=FALSE;
|
fconst=FALSE;
|
||||||
fpublic=(sym->usage & uPUBLIC)!=0;
|
fpublic= (sym->usage & uPUBLIC)!=0;
|
||||||
/* the '(' parantheses has already been parsed */
|
/* the '(' parantheses has already been parsed */
|
||||||
if (!matchtoken(')')){
|
if (!matchtoken(')')){
|
||||||
do { /* there are arguments; process them */
|
do { /* there are arguments; process them */
|
||||||
|
@ -2077,7 +2077,9 @@ static int nesting=0;
|
|||||||
if (arg[argidx].ident!=0 && arg[argidx].numtags==1)
|
if (arg[argidx].ident!=0 && arg[argidx].numtags==1)
|
||||||
lval.cmptag=arg[argidx].tags[0]; /* set the expected tag, if any */
|
lval.cmptag=arg[argidx].tags[0]; /* set the expected tag, if any */
|
||||||
lvalue=hier14(&lval);
|
lvalue=hier14(&lval);
|
||||||
assert(sc_status==statFIRST || arg[argidx].ident== 0 || arg[argidx].tags!=NULL);
|
assert(sc_status==statFIRST || arg[argidx].ident==0 || arg[argidx].tags!=NULL);
|
||||||
|
if (lval.sym!=NULL && lval.sym->ident==iVARIABLE && lval.sym->vclass==sGLOBAL)
|
||||||
|
sym->usage|=uGLOBALARGS;
|
||||||
switch (arg[argidx].ident) {
|
switch (arg[argidx].ident) {
|
||||||
case 0:
|
case 0:
|
||||||
error(202); /* argument count mismatch */
|
error(202); /* argument count mismatch */
|
||||||
|
@ -161,7 +161,7 @@ static char *warnmsg[] = {
|
|||||||
/*205*/ "redundant code: constant expression is zero\n",
|
/*205*/ "redundant code: constant expression is zero\n",
|
||||||
/*206*/ "redundant test: constant expression is non-zero\n",
|
/*206*/ "redundant test: constant expression is non-zero\n",
|
||||||
/*207*/ "unknown #pragma\n",
|
/*207*/ "unknown #pragma\n",
|
||||||
/*208*/ "function with tag result used before definition, forcing reparse\n",
|
/*208*/ "function with tag result or global variables as arguments is used before definition, forcing reparse\n",
|
||||||
/*209*/ "function \"%s\" should return a value\n",
|
/*209*/ "function \"%s\" should return a value\n",
|
||||||
/*210*/ "possible use of symbol before initialization: \"%s\"\n",
|
/*210*/ "possible use of symbol before initialization: \"%s\"\n",
|
||||||
/*211*/ "possibly unintended assignment\n",
|
/*211*/ "possibly unintended assignment\n",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user