From 45bf43d76e04f6d129802d4a6e8a4bb26ab54397 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Tue, 9 Dec 2014 22:26:59 +0100 Subject: [PATCH 1/4] FIx regression with member tag of an enum not being checked on assigment --- compiler/libpc300/sc.h | 1 + compiler/libpc300/sc3.c | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/compiler/libpc300/sc.h b/compiler/libpc300/sc.h index 2d8c8c24..5b90995e 100755 --- a/compiler/libpc300/sc.h +++ b/compiler/libpc300/sc.h @@ -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 */ diff --git a/compiler/libpc300/sc3.c b/compiler/libpc300/sc3.c index a268a1b1..43ee9ed3 100755 --- a/compiler/libpc300/sc3.c +++ b/compiler/libpc300/sc3.c @@ -973,10 +973,33 @@ 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)) - error(213); - else if (!lval3.sym && !matchtag(lval3.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.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); @@ -1122,11 +1145,12 @@ static int hier3(value *lval) static int hier2(value *lval) { int lvalue,tok; - int tag,paranthese; + int tag, paranthese; cell val; 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; From 78940b46a4d876d32315252473efdab17fae04ee Mon Sep 17 00:00:00 2001 From: Arkshine Date: Tue, 9 Dec 2014 22:29:43 +0100 Subject: [PATCH 2/4] Untabify code --- compiler/libpc300/sc3.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/compiler/libpc300/sc3.c b/compiler/libpc300/sc3.c index 43ee9ed3..ddaace8e 100755 --- a/compiler/libpc300/sc3.c +++ b/compiler/libpc300/sc3.c @@ -974,27 +974,27 @@ static int hier14(value *lval1) } /* if */ if (!oper) { /* tagname mismatch (if "oper", warning already given in plunge2()) */ - /* 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 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.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; + 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. + 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)) { @@ -1225,10 +1225,10 @@ static int hier2(value *lval) return FALSE; case tLABEL: /* tagname override */ tag=pc_addtag(st); - forceuntag=(*st == '_'); /* forced to be untagged with _: */ + forceuntag=(*st == '_'); /* forced to be untagged with _: */ lvalue=hier2(lval); lval->tag=tag; - lval->forceuntag=forceuntag; + lval->forceuntag=forceuntag; return lvalue; case tDEFINED: paranthese=0; From 4b11a543450414eaac5445c8f4fa71c009b6cf92 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Tue, 9 Dec 2014 22:59:57 +0100 Subject: [PATCH 3/4] Make sure overriden tag is done with _: --- compiler/libpc300/sc3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/libpc300/sc3.c b/compiler/libpc300/sc3.c index ddaace8e..bcd29d59 100755 --- a/compiler/libpc300/sc3.c +++ b/compiler/libpc300/sc3.c @@ -1225,7 +1225,7 @@ static int hier2(value *lval) return FALSE; case tLABEL: /* tagname override */ tag=pc_addtag(st); - forceuntag=(*st == '_'); /* forced to be untagged with _: */ + forceuntag=(*st == '_' && !tag); /* forced to be untagged with _: */ lvalue=hier2(lval); lval->tag=tag; lval->forceuntag=forceuntag; From c068eed19d2026da98a6d6d60299c1e070d7e2e3 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Sat, 13 Dec 2014 11:15:06 +0100 Subject: [PATCH 4/4] Simplify code. --- compiler/libpc300/sc3.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/compiler/libpc300/sc3.c b/compiler/libpc300/sc3.c index bcd29d59..13c45c42 100755 --- a/compiler/libpc300/sc3.c +++ b/compiler/libpc300/sc3.c @@ -974,12 +974,9 @@ static int hier14(value *lval1) } /* if */ if (!oper) { /* tagname mismatch (if "oper", warning already given in plunge2()) */ - /* 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 the left value is a tagged symbol, assume that it is not an "enum struct." For + example, for "enum X { A, B }; new Float:array[X]" we assume that `A` and `B` + are not tagged and the array is an array of floats. */ if (lval3.sym && lval3.sym->tag != 0) { if (!matchtag(lval3.sym->tag, lval2.tag, TRUE)) @@ -1150,7 +1147,6 @@ static int hier2(value *lval) char *st; symbol *sym=NULL; int saveresult; - char forceuntag=FALSE; sym = NULL; tok=lex(&val,&st); @@ -1225,10 +1221,9 @@ static int hier2(value *lval) return FALSE; case tLABEL: /* tagname override */ tag=pc_addtag(st); - forceuntag=(*st == '_' && !tag); /* forced to be untagged with _: */ lvalue=hier2(lval); lval->tag=tag; - lval->forceuntag=forceuntag; + lval->forceuntag=!tag; /* forced to be untagged with _: */ return lvalue; case tDEFINED: paranthese=0;