FIx regression with member tag of an enum not being checked on assigment
This commit is contained in:
parent
2bba5ce69a
commit
45bf43d76e
|
@ -240,6 +240,7 @@ typedef struct s_value {
|
|||
cell constval; /* value of the constant expression (if ident==iCONSTEXPR)
|
||||
* also used for the size of a literal array */
|
||||
int tag; /* tagname id (of the expression) */
|
||||
char forceuntag; /* whether expression is untagged using _: */
|
||||
char ident; /* iCONSTEXPR, iVARIABLE, iARRAY, iARRAYCELL,
|
||||
* iEXPRESSION or iREFERENCE */
|
||||
char boolresult; /* boolean result for relational operators */
|
||||
|
|
|
@ -973,11 +973,34 @@ static int hier14(value *lval1)
|
|||
store(&lval3); /* now, store the expression result */
|
||||
} /* if */
|
||||
if (!oper) { /* tagname mismatch (if "oper", warning already given in plunge2()) */
|
||||
if (lval3.sym && !matchtag(lval3.sym->tag, lval2.tag, TRUE))
|
||||
|
||||
/* If left value is a symbol and is tagged, we want to check that first.
|
||||
If we tag array and an enum member is passed as index, we assume enum
|
||||
is a simple list of constants (as opposite, not a "structure"). E.g.:
|
||||
enum X {A, B}; new Float:array[X];
|
||||
array[A] = 1.0;
|
||||
^ tag of array is checked instead of tag of A.
|
||||
*/
|
||||
if (lval3.sym && lval3.sym->tag != 0) {
|
||||
if (!matchtag(lval3.sym->tag, lval2.tag, TRUE))
|
||||
error(213);
|
||||
else if (!lval3.sym && !matchtag(lval3.tag, lval2.tag, TRUE))
|
||||
}
|
||||
else if (lval3.tag && !lval2.tag && lval2.forceuntag) {
|
||||
/* Because of the above fix included in AMXX 1.60, a regression has been introduced
|
||||
as well, where any tagged members of an enum is ignored when a tag check is required.
|
||||
E.g.: enum X {Float:A, SomeTag:B }; new array[X];
|
||||
array[A] = 1.0;
|
||||
With the original fix, tag of array is checked instead of tag of A. Result: tag mismatch.
|
||||
To bypass the issue, plugin has to untag the value like _:1.0.
|
||||
To fix this and to avoid old plugins suddenly getting spammed by warnings, we track
|
||||
when a value is untagged, and if the related enum member is tagged and the value is forced
|
||||
to be untagged, we assume this matches.
|
||||
*/
|
||||
}
|
||||
else if (!matchtag(lval3.tag, lval2.tag, TRUE)) {
|
||||
error(213);
|
||||
}
|
||||
}
|
||||
if (lval3.sym)
|
||||
markusage(lval3.sym,uWRITTEN);
|
||||
sideeffect=TRUE;
|
||||
|
@ -1127,6 +1150,7 @@ static int hier2(value *lval)
|
|||
char *st;
|
||||
symbol *sym=NULL;
|
||||
int saveresult;
|
||||
char forceuntag=FALSE;
|
||||
|
||||
sym = NULL;
|
||||
tok=lex(&val,&st);
|
||||
|
@ -1201,8 +1225,10 @@ static int hier2(value *lval)
|
|||
return FALSE;
|
||||
case tLABEL: /* tagname override */
|
||||
tag=pc_addtag(st);
|
||||
forceuntag=(*st == '_'); /* forced to be untagged with _: */
|
||||
lvalue=hier2(lval);
|
||||
lval->tag=tag;
|
||||
lval->forceuntag=forceuntag;
|
||||
return lvalue;
|
||||
case tDEFINED:
|
||||
paranthese=0;
|
||||
|
|
Loading…
Reference in New Issue
Block a user