From 106280bb6293833350bd478c3bc021d93397ecb8 Mon Sep 17 00:00:00 2001 From: Stanislav Gromov Date: Wed, 24 Jun 2020 21:44:23 +0800 Subject: [PATCH 01/10] Fix enum increments `*= 1` and `<<= 0` working as `+= 1` --- source/compiler/sc1.c | 33 +++++---- source/compiler/tests/enum_increment.meta | 5 ++ source/compiler/tests/enum_increment.pwn | 86 +++++++++++++++++++++++ 3 files changed, 110 insertions(+), 14 deletions(-) create mode 100644 source/compiler/tests/enum_increment.meta create mode 100644 source/compiler/tests/enum_increment.pwn diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 41084d1f..21a2b56c 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -2928,7 +2928,8 @@ static void decl_enum(int vclass,int fstatic) cell val,value,size; char *str; int tag,explicittag; - cell increment,multiplier; + int inctok; + cell increment; constvalue_root *enumroot=NULL; symbol *enumsym=NULL; short filenum; @@ -2958,18 +2959,18 @@ static void decl_enum(int vclass,int fstatic) enumname[0]='\0'; } /* if */ - /* get increment and multiplier */ + /* get the increment */ increment=1; - multiplier=1; + inctok=taADD; if (matchtoken('(')) { - if (matchtoken(taADD)) { + int tok=lex(&val,&str); + if (tok==taADD || tok==taMULT || tok==taSHL) { + inctok=tok; constexpr(&increment,NULL,NULL); - } else if (matchtoken(taMULT)) { - constexpr(&multiplier,NULL,NULL); - } else if (matchtoken(taSHL)) { - constexpr(&val,NULL,NULL); - while (val-->0) - multiplier*=2; + if (tok==taSHL && increment<0) + increment=0; + } else { + lexpush(); } /* if */ needtoken(')'); } /* if */ @@ -3005,7 +3006,7 @@ static void decl_enum(int vclass,int fstatic) } else { constname[0]='\0'; } /* if */ - size=increment; /* default increment of 'val' */ + size=(inctok==taADD) ? increment : 1;/* default increment of 'val' */ fieldtag=0; /* default field tag */ if (matchtoken('[')) { constexpr(&size,&fieldtag,NULL); /* get size */ @@ -3027,6 +3028,8 @@ static void decl_enum(int vclass,int fstatic) sym->parent=enumsym; if (enumsym) enumsym->child=sym; + if (vclass==sLOCAL) + sym->compound=nestlevel; if (fstatic) sym->fnumber=filenum; @@ -3036,10 +3039,12 @@ static void decl_enum(int vclass,int fstatic) sym->usage |= uENUMFIELD; append_constval(enumroot,constname,value,tag); } /* if */ - if (multiplier==1) + if (inctok==taADD) value+=size; - else - value*=size*multiplier; + else if (inctok==taMULT) + value*=(size*increment); + else // taSHL + value*=(size << increment); } while (matchtoken(',')); needtoken('}'); /* terminates the constant list */ matchtoken(';'); /* eat an optional ; */ diff --git a/source/compiler/tests/enum_increment.meta b/source/compiler/tests/enum_increment.meta new file mode 100644 index 00000000..bfdf2528 --- /dev/null +++ b/source/compiler/tests/enum_increment.meta @@ -0,0 +1,5 @@ +{ + 'test_type': 'output_check', + 'errors': """ + """ +} diff --git a/source/compiler/tests/enum_increment.pwn b/source/compiler/tests/enum_increment.pwn new file mode 100644 index 00000000..c549d713 --- /dev/null +++ b/source/compiler/tests/enum_increment.pwn @@ -0,0 +1,86 @@ +#pragma option -d1 // TODO: Remove this line when #544 is merged + +main() +{ + enum e1 + { + e1Elem1[3], + e1Elem2, + e1Elem3 + }; + new arr1[e1]; + #pragma unused arr1 + #assert sizeof arr1[e1Elem1] == 3 + #assert sizeof arr1[e1Elem2] == 1 + #assert sizeof arr1[e1Elem3] == 1 + #assert _:e1Elem1 == 0 + #assert _:e1Elem2 == 3 + #assert _:e1Elem3 == 4 + + enum e2 (+= 2) + { + e2Elem1[3], + e2Elem2, + e2Elem3 + }; + new arr2[e2]; + #pragma unused arr2 + #assert sizeof arr2[e2Elem1] == 3 + #assert sizeof arr2[e2Elem2] == 2 + #assert sizeof arr2[e2Elem3] == 2 + #assert _:e2Elem1 == 0 + #assert _:e2Elem2 == 3 + #assert _:e2Elem3 == 5 + + enum e3 (*= 2) + { + e3Elem1 = 1, + e3Elem2[3], + e3Elem3 + }; + new arr3[e3]; + #pragma unused arr3 + #assert sizeof arr3[e3Elem1] == 1 + #assert sizeof arr3[e3Elem2] == 3 + #assert sizeof arr3[e3Elem3] == 1 + #assert _:e3Elem1 == 1 + #assert _:e3Elem2 == 2 // 1 * (1 * 2); the first "1" is the value of the previous + // enum item, the second "1" is the size of the previous + // item, and "2" is the increment (multiplier) + #assert _:e3Elem3 == 12 // 2 * (3 * 2) + + enum e4 (<<= 2) + { + e4Elem1 = 1, + e4Elem2[3], + e4Elem3 + }; + new arr4[e4]; + #pragma unused arr4 + #assert sizeof arr4[e4Elem1] == 1 + #assert sizeof arr4[e4Elem2] == 3 + #assert sizeof arr4[e4Elem3] == 1 + #assert _:e4Elem1 == 1 + #assert _:e4Elem2 == 4 // 1 * (1 << 2) = 4 + #assert _:e4Elem3 == 48 // 4 * (3 << 2) = 48 + + enum (<<= 0) + { + e5Elem1, + e5Elem2, + e5Elem3 + }; + #assert _:e5Elem1 == 0 + #assert _:e5Elem2 == 0 + #assert _:e5Elem3 == 0 + + enum (*= 1) + { + e5Elem1, + e5Elem2, + e5Elem3 + }; + #assert _:e5Elem1 == 0 + #assert _:e5Elem2 == 0 + #assert _:e5Elem3 == 0 +} From f4a399fba7621b49b3290b6882820bb803784a1e Mon Sep 17 00:00:00 2001 From: Stanislav Gromov Date: Thu, 27 Feb 2020 02:55:07 +0700 Subject: [PATCH 02/10] Warn if the shift count is negative or too big --- source/compiler/sc1.c | 2 +- source/compiler/sc3.c | 21 +++++++++++++-------- source/compiler/sc5.c | 3 ++- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 21a2b56c..145161a3 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6550,7 +6550,7 @@ static void SC_FASTCALL emit_param_index(emit_outval *p,int isrange, if (val==valid_values[i]) return; } /* if */ - error(50); /* invalid range */ + error(241); /* negative or too big shift count */ } static void SC_FASTCALL emit_param_nonneg(emit_outval *p) diff --git a/source/compiler/sc3.c b/source/compiler/sc3.c index 46486997..9eda02aa 100644 --- a/source/compiler/sc3.c +++ b/source/compiler/sc3.c @@ -626,15 +626,20 @@ static void plnge2(void (*oper)(void), if (check_userop(oper,lval1->tag,lval2->tag,2,NULL,&lval1->tag)) { lval1->ident=iEXPRESSION; lval1->constval=0; - } else if (lval1->ident==iCONSTEXPR && lval2->ident==iCONSTEXPR) { - /* only constant expression if both constant */ - stgdel(index,cidx); /* scratch generated code and calculate */ - check_tagmismatch(lval1->tag,lval2->tag,FALSE,-1); - lval1->constval=calc(lval1->constval,oper,lval2->constval,&lval1->boolresult); } else { - check_tagmismatch(lval1->tag,lval2->tag,FALSE,-1); - (*oper)(); /* do the (signed) operation */ - lval1->ident=iEXPRESSION; + if ((oper==ob_sal || oper==os_sar || oper==ou_sar) + && (lval2->ident==iCONSTEXPR && (lval2->constval<0 || lval2->constval>=PAWN_CELL_SIZE))) + error(241); /* negative or too big shift count */ + if (lval1->ident==iCONSTEXPR && lval2->ident==iCONSTEXPR) { + /* only constant expression if both constant */ + stgdel(index,cidx); /* scratch generated code and calculate */ + check_tagmismatch(lval1->tag,lval2->tag,FALSE,-1); + lval1->constval=calc(lval1->constval,oper,lval2->constval,&lval1->boolresult); + } else { + check_tagmismatch(lval1->tag,lval2->tag,FALSE,-1); + (*oper)(); /* do the (signed) operation */ + lval1->ident=iEXPRESSION; + } /* if */ } /* if */ } /* if */ } diff --git a/source/compiler/sc5.c b/source/compiler/sc5.c index c5b31845..73733dd1 100644 --- a/source/compiler/sc5.c +++ b/source/compiler/sc5.c @@ -197,7 +197,8 @@ static char *warnmsg[] = { /*237*/ "user warning: %s\n", /*238*/ "meaningless combination of class specifiers (%s)\n", /*239*/ "literal array/string passed to a non-const parameter\n", -/*240*/ "previously assigned value is never used (symbol \"%s\")\n" +/*240*/ "previously assigned value is never used (symbol \"%s\")\n", +/*241*/ "negative or too big shift count\n" }; static char *noticemsg[] = { From b384a759ed68c5f581ec8a792618e36cc28df864 Mon Sep 17 00:00:00 2001 From: Stanislav Gromov Date: Wed, 17 Jun 2020 18:24:35 +0800 Subject: [PATCH 03/10] Add tests --- source/compiler/tests/warning_241.meta | 13 ++++++++++++ source/compiler/tests/warning_241.pwn | 29 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 source/compiler/tests/warning_241.meta create mode 100644 source/compiler/tests/warning_241.pwn diff --git a/source/compiler/tests/warning_241.meta b/source/compiler/tests/warning_241.meta new file mode 100644 index 00000000..9ef00cd0 --- /dev/null +++ b/source/compiler/tests/warning_241.meta @@ -0,0 +1,13 @@ +{ + 'test_type': 'output_check', + 'errors': """ +warning_241.pwn(8) : warning 241: negative or too big shift count +warning_241.pwn(9) : warning 241: negative or too big shift count +warning_241.pwn(14) : warning 241: negative or too big shift count +warning_241.pwn(15) : warning 241: negative or too big shift count +warning_241.pwn(18) : warning 241: negative or too big shift count +warning_241.pwn(19) : warning 241: negative or too big shift count +warning_241.pwn(24) : warning 241: negative or too big shift count +warning_241.pwn(25) : warning 241: negative or too big shift count +""" +} diff --git a/source/compiler/tests/warning_241.pwn b/source/compiler/tests/warning_241.pwn new file mode 100644 index 00000000..3f1afdd0 --- /dev/null +++ b/source/compiler/tests/warning_241.pwn @@ -0,0 +1,29 @@ +#include + +main() +{ + new var = 1; + + // Case 1: Both values are compile-time constants + printf("%d", 1 << -1); // warning 241 + printf("%d", 1 << -2); // warning 241 + printf("%d", 1 << 0); + printf("%d", 1 << 1); + printf("%d", 1 << 30); + printf("%d", 1 << 31); + printf("%d", 1 << 32); // warning 241 + printf("%d", 1 << 33); // warning 241 + + // Case 2: Only the shift count is constant + printf("%d", var << -1); // warning 241 + printf("%d", var << -2); // warning 241 + printf("%d", var << 0); + printf("%d", var << 1); + printf("%d", var << 30); + printf("%d", var << 31); + printf("%d", var << 32); // warning 241 + printf("%d", var << 33); // warning 241 + + printf("%d", 1 << var); // Just to make sure the warning works only + // if the shift count is a constant value +} From 5af4bbbd1c6cba058bf685306592b5e6562682d0 Mon Sep 17 00:00:00 2001 From: Stanislav Gromov Date: Wed, 17 Jun 2020 18:32:41 +0800 Subject: [PATCH 04/10] Update one of the tests for `__emit` Now `__emit` too uses warning 241 for `shl.c.pri/alt` and `shr.c.pri/alt`. --- source/compiler/tests/__emit_p5.meta | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source/compiler/tests/__emit_p5.meta b/source/compiler/tests/__emit_p5.meta index 6652ac2e..fb6118e5 100644 --- a/source/compiler/tests/__emit_p5.meta +++ b/source/compiler/tests/__emit_p5.meta @@ -1,29 +1,29 @@ { 'test_type': 'output_check', 'errors': """ -__emit_p5.pwn(25) : error 050: invalid range +__emit_p5.pwn(25) : warning 241: negative or too big shift count __emit_p5.pwn(26) : error 001: expected token: "-integer value-", but found "-data offset-" __emit_p5.pwn(27) : error 001: expected token: "-integer value-", but found "-function-" __emit_p5.pwn(28) : error 001: expected token: "-integer value-", but found "-reference-" -__emit_p5.pwn(29) : error 050: invalid range +__emit_p5.pwn(29) : warning 241: negative or too big shift count __emit_p5.pwn(30) : error 001: expected token: "-integer value-", but found "-local variable-" __emit_p5.pwn(31) : error 001: expected token: "-integer value-", but found "-data offset-" __emit_p5.pwn(32) : error 001: expected token: "-integer value-", but found "-label-" -__emit_p5.pwn(33) : error 050: invalid range -__emit_p5.pwn(34) : error 050: invalid range -__emit_p5.pwn(35) : error 050: invalid range -__emit_p5.pwn(36) : error 050: invalid range -__emit_p5.pwn(37) : error 050: invalid range -__emit_p5.pwn(38) : error 050: invalid range +__emit_p5.pwn(33) : warning 241: negative or too big shift count +__emit_p5.pwn(34) : warning 241: negative or too big shift count +__emit_p5.pwn(35) : warning 241: negative or too big shift count +__emit_p5.pwn(36) : warning 241: negative or too big shift count +__emit_p5.pwn(37) : warning 241: negative or too big shift count +__emit_p5.pwn(38) : warning 241: negative or too big shift count __emit_p5.pwn(61) : error 001: expected token: "-integer value-", but found "-data offset-" __emit_p5.pwn(62) : error 001: expected token: "-integer value-", but found "-function-" __emit_p5.pwn(63) : error 001: expected token: "-integer value-", but found "-reference-" __emit_p5.pwn(64) : error 001: expected token: "-integer value-", but found "-local variable-" __emit_p5.pwn(65) : error 001: expected token: "-integer value-", but found "-data offset-" __emit_p5.pwn(66) : error 001: expected token: "-integer value-", but found "-label-" -__emit_p5.pwn(67) : error 050: invalid range -__emit_p5.pwn(68) : error 050: invalid range -__emit_p5.pwn(69) : error 050: invalid range -__emit_p5.pwn(70) : error 050: invalid range +__emit_p5.pwn(67) : warning 241: negative or too big shift count +__emit_p5.pwn(68) : warning 241: negative or too big shift count +__emit_p5.pwn(69) : warning 241: negative or too big shift count +__emit_p5.pwn(70) : warning 241: negative or too big shift count """ } From 1f64f87ae165ba6eb7eaf91422fdac8129ec35a0 Mon Sep 17 00:00:00 2001 From: Stanislav Gromov Date: Sun, 21 Jun 2020 23:02:10 +0800 Subject: [PATCH 05/10] Update the tests to cover right shift operations --- source/compiler/tests/warning_241.meta | 28 +++++++++++++++++----- source/compiler/tests/warning_241.pwn | 32 ++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/source/compiler/tests/warning_241.meta b/source/compiler/tests/warning_241.meta index 9ef00cd0..589d5d34 100644 --- a/source/compiler/tests/warning_241.meta +++ b/source/compiler/tests/warning_241.meta @@ -3,11 +3,27 @@ 'errors': """ warning_241.pwn(8) : warning 241: negative or too big shift count warning_241.pwn(9) : warning 241: negative or too big shift count -warning_241.pwn(14) : warning 241: negative or too big shift count -warning_241.pwn(15) : warning 241: negative or too big shift count -warning_241.pwn(18) : warning 241: negative or too big shift count -warning_241.pwn(19) : warning 241: negative or too big shift count -warning_241.pwn(24) : warning 241: negative or too big shift count -warning_241.pwn(25) : warning 241: negative or too big shift count +warning_241.pwn(10) : warning 241: negative or too big shift count +warning_241.pwn(11) : warning 241: negative or too big shift count +warning_241.pwn(12) : warning 241: negative or too big shift count +warning_241.pwn(13) : warning 241: negative or too big shift count +warning_241.pwn(26) : warning 241: negative or too big shift count +warning_241.pwn(27) : warning 241: negative or too big shift count +warning_241.pwn(28) : warning 241: negative or too big shift count +warning_241.pwn(29) : warning 241: negative or too big shift count +warning_241.pwn(30) : warning 241: negative or too big shift count +warning_241.pwn(31) : warning 241: negative or too big shift count +warning_241.pwn(34) : warning 241: negative or too big shift count +warning_241.pwn(35) : warning 241: negative or too big shift count +warning_241.pwn(36) : warning 241: negative or too big shift count +warning_241.pwn(37) : warning 241: negative or too big shift count +warning_241.pwn(38) : warning 241: negative or too big shift count +warning_241.pwn(39) : warning 241: negative or too big shift count +warning_241.pwn(52) : warning 241: negative or too big shift count +warning_241.pwn(53) : warning 241: negative or too big shift count +warning_241.pwn(54) : warning 241: negative or too big shift count +warning_241.pwn(55) : warning 241: negative or too big shift count +warning_241.pwn(56) : warning 241: negative or too big shift count +warning_241.pwn(57) : warning 241: negative or too big shift count """ } diff --git a/source/compiler/tests/warning_241.pwn b/source/compiler/tests/warning_241.pwn index 3f1afdd0..17bbe726 100644 --- a/source/compiler/tests/warning_241.pwn +++ b/source/compiler/tests/warning_241.pwn @@ -7,22 +7,54 @@ main() // Case 1: Both values are compile-time constants printf("%d", 1 << -1); // warning 241 printf("%d", 1 << -2); // warning 241 + printf("%d", 1 >> -1); // warning 241 + printf("%d", 1 >> -2); // warning 241 + printf("%d", 1 >>> -1); // warning 241 + printf("%d", 1 >>> -2); // warning 241 printf("%d", 1 << 0); printf("%d", 1 << 1); + printf("%d", 1 >> 0); + printf("%d", 1 >> 1); + printf("%d", 1 >>> 0); + printf("%d", 1 >>> 1); printf("%d", 1 << 30); printf("%d", 1 << 31); + printf("%d", 1 >> 30); + printf("%d", 1 >> 31); + printf("%d", 1 >>> 30); + printf("%d", 1 >>> 31); printf("%d", 1 << 32); // warning 241 printf("%d", 1 << 33); // warning 241 + printf("%d", 1 >> 32); // warning 241 + printf("%d", 1 >> 33); // warning 241 + printf("%d", 1 >>> 32); // warning 241 + printf("%d", 1 >>> 33); // warning 241 // Case 2: Only the shift count is constant printf("%d", var << -1); // warning 241 printf("%d", var << -2); // warning 241 + printf("%d", var >> -1); // warning 241 + printf("%d", var >> -2); // warning 241 + printf("%d", var >>> -1); // warning 241 + printf("%d", var >>> -2); // warning 241 printf("%d", var << 0); printf("%d", var << 1); + printf("%d", var >> 0); + printf("%d", var >> 1); + printf("%d", var >>> 0); + printf("%d", var >>> 1); printf("%d", var << 30); printf("%d", var << 31); + printf("%d", var >> 30); + printf("%d", var >> 31); + printf("%d", var >>> 30); + printf("%d", var >>> 31); printf("%d", var << 32); // warning 241 printf("%d", var << 33); // warning 241 + printf("%d", var >> 32); // warning 241 + printf("%d", var >> 33); // warning 241 + printf("%d", var >>> 32); // warning 241 + printf("%d", var >>> 33); // warning 241 printf("%d", 1 << var); // Just to make sure the warning works only // if the shift count is a constant value From 681fbdb97da2d824d874ff1c0be821fcef8b2c8f Mon Sep 17 00:00:00 2001 From: Stanislav Gromov Date: Fri, 26 Jun 2020 18:11:03 +0800 Subject: [PATCH 06/10] Warn on invalid shift count for enum increment --- source/compiler/sc1.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 145161a3..a23eccb5 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -2967,8 +2967,12 @@ static void decl_enum(int vclass,int fstatic) if (tok==taADD || tok==taMULT || tok==taSHL) { inctok=tok; constexpr(&increment,NULL,NULL); - if (tok==taSHL && increment<0) - increment=0; + if (tok==taSHL) { + if (increment<0 || increment>=PAWN_CELL_SIZE) + error(241); /* negative or too big shift count */ + if (increment<0) + increment=0; + } /* if */ } else { lexpush(); } /* if */ From 9bbd7b458c0490d65c92538a3b519ec564febcba Mon Sep 17 00:00:00 2001 From: Stanislav Gromov Date: Tue, 30 Jun 2020 00:01:17 +0800 Subject: [PATCH 07/10] Warn about shift overflow in enum item declarations --- source/compiler/sc1.c | 21 +++++++++++++++++---- source/compiler/sc5.c | 3 ++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index a23eccb5..864c6e5a 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -2929,6 +2929,7 @@ static void decl_enum(int vclass,int fstatic) char *str; int tag,explicittag; int inctok; + int overflow; cell increment; constvalue_root *enumroot=NULL; symbol *enumsym=NULL; @@ -2996,13 +2997,16 @@ static void decl_enum(int vclass,int fstatic) needtoken('{'); /* go through all constants */ value=0; /* default starting value */ + overflow=FALSE; do { int idxtag,fieldtag; + int symline; symbol *sym; if (matchtoken('}')) { /* quick exit if '}' follows ',' */ lexpush(); break; } /* if */ + symline=fline; idxtag=(enumname[0]=='\0') ? tag : pc_addtag(NULL); /* optional explicit item tag */ if (needtoken(tSYMBOL)) { /* read in (new) token */ tokeninfo(&val,&str); /* get the information */ @@ -3016,8 +3020,14 @@ static void decl_enum(int vclass,int fstatic) constexpr(&size,&fieldtag,NULL); /* get size */ needtoken(']'); } /* if */ - if (matchtoken('=')) + if (matchtoken('=')) { constexpr(&value,NULL,NULL); /* get value */ + overflow=FALSE; + } else if (overflow) { + errorset(sSETPOS,symline); + error(242,constname); /* shift overflow for enum item */ + errorset(sSETPOS,-1); + } /* if */ /* add_constant() checks whether a variable (global or local) or * a constant with the same name already exists */ @@ -3043,12 +3053,15 @@ static void decl_enum(int vclass,int fstatic) sym->usage |= uENUMFIELD; append_constval(enumroot,constname,value,tag); } /* if */ - if (inctok==taADD) + if (inctok==taADD) { value+=size; - else if (inctok==taMULT) + } else if (inctok==taMULT) { value*=(size*increment); - else // taSHL + } else { // taSHL + if ((ucell)value>=((ucell)1 << (PAWN_CELL_SIZE-increment))) + overflow=TRUE; value*=(size << increment); + } /* if */ } while (matchtoken(',')); needtoken('}'); /* terminates the constant list */ matchtoken(';'); /* eat an optional ; */ diff --git a/source/compiler/sc5.c b/source/compiler/sc5.c index 73733dd1..7aa845ad 100644 --- a/source/compiler/sc5.c +++ b/source/compiler/sc5.c @@ -198,7 +198,8 @@ static char *warnmsg[] = { /*238*/ "meaningless combination of class specifiers (%s)\n", /*239*/ "literal array/string passed to a non-const parameter\n", /*240*/ "previously assigned value is never used (symbol \"%s\")\n", -/*241*/ "negative or too big shift count\n" +/*241*/ "negative or too big shift count\n", +/*242*/ "shift overflow in enum item declaration (symbol \"%s\")\n" }; static char *noticemsg[] = { From 093097724d1f18959355df21862a218a47dd7789 Mon Sep 17 00:00:00 2001 From: Stanislav Gromov Date: Tue, 30 Jun 2020 00:17:28 +0800 Subject: [PATCH 08/10] Update tests --- source/compiler/tests/warning_241.meta | 29 ------ source/compiler/tests/warning_241_242.meta | 33 +++++++ .../{warning_241.pwn => warning_241_242.pwn} | 95 +++++++++++++++++++ 3 files changed, 128 insertions(+), 29 deletions(-) delete mode 100644 source/compiler/tests/warning_241.meta create mode 100644 source/compiler/tests/warning_241_242.meta rename source/compiler/tests/{warning_241.pwn => warning_241_242.pwn} (70%) diff --git a/source/compiler/tests/warning_241.meta b/source/compiler/tests/warning_241.meta deleted file mode 100644 index 589d5d34..00000000 --- a/source/compiler/tests/warning_241.meta +++ /dev/null @@ -1,29 +0,0 @@ -{ - 'test_type': 'output_check', - 'errors': """ -warning_241.pwn(8) : warning 241: negative or too big shift count -warning_241.pwn(9) : warning 241: negative or too big shift count -warning_241.pwn(10) : warning 241: negative or too big shift count -warning_241.pwn(11) : warning 241: negative or too big shift count -warning_241.pwn(12) : warning 241: negative or too big shift count -warning_241.pwn(13) : warning 241: negative or too big shift count -warning_241.pwn(26) : warning 241: negative or too big shift count -warning_241.pwn(27) : warning 241: negative or too big shift count -warning_241.pwn(28) : warning 241: negative or too big shift count -warning_241.pwn(29) : warning 241: negative or too big shift count -warning_241.pwn(30) : warning 241: negative or too big shift count -warning_241.pwn(31) : warning 241: negative or too big shift count -warning_241.pwn(34) : warning 241: negative or too big shift count -warning_241.pwn(35) : warning 241: negative or too big shift count -warning_241.pwn(36) : warning 241: negative or too big shift count -warning_241.pwn(37) : warning 241: negative or too big shift count -warning_241.pwn(38) : warning 241: negative or too big shift count -warning_241.pwn(39) : warning 241: negative or too big shift count -warning_241.pwn(52) : warning 241: negative or too big shift count -warning_241.pwn(53) : warning 241: negative or too big shift count -warning_241.pwn(54) : warning 241: negative or too big shift count -warning_241.pwn(55) : warning 241: negative or too big shift count -warning_241.pwn(56) : warning 241: negative or too big shift count -warning_241.pwn(57) : warning 241: negative or too big shift count -""" -} diff --git a/source/compiler/tests/warning_241_242.meta b/source/compiler/tests/warning_241_242.meta new file mode 100644 index 00000000..82f310bb --- /dev/null +++ b/source/compiler/tests/warning_241_242.meta @@ -0,0 +1,33 @@ +{ + 'test_type': 'output_check', + 'errors': """ +warning_241_242.pwn(3) : warning 241: negative or too big shift count +warning_241_242.pwn(8) : warning 241: negative or too big shift count +warning_241_242.pwn(56) : warning 242: shift overflow in enum item declaration (symbol "e32") +warning_241_242.pwn(95) : warning 242: shift overflow in enum item declaration (symbol "f34") +warning_241_242.pwn(103) : warning 241: negative or too big shift count +warning_241_242.pwn(104) : warning 241: negative or too big shift count +warning_241_242.pwn(105) : warning 241: negative or too big shift count +warning_241_242.pwn(106) : warning 241: negative or too big shift count +warning_241_242.pwn(107) : warning 241: negative or too big shift count +warning_241_242.pwn(108) : warning 241: negative or too big shift count +warning_241_242.pwn(121) : warning 241: negative or too big shift count +warning_241_242.pwn(122) : warning 241: negative or too big shift count +warning_241_242.pwn(123) : warning 241: negative or too big shift count +warning_241_242.pwn(124) : warning 241: negative or too big shift count +warning_241_242.pwn(125) : warning 241: negative or too big shift count +warning_241_242.pwn(126) : warning 241: negative or too big shift count +warning_241_242.pwn(129) : warning 241: negative or too big shift count +warning_241_242.pwn(130) : warning 241: negative or too big shift count +warning_241_242.pwn(131) : warning 241: negative or too big shift count +warning_241_242.pwn(132) : warning 241: negative or too big shift count +warning_241_242.pwn(133) : warning 241: negative or too big shift count +warning_241_242.pwn(134) : warning 241: negative or too big shift count +warning_241_242.pwn(147) : warning 241: negative or too big shift count +warning_241_242.pwn(148) : warning 241: negative or too big shift count +warning_241_242.pwn(149) : warning 241: negative or too big shift count +warning_241_242.pwn(150) : warning 241: negative or too big shift count +warning_241_242.pwn(151) : warning 241: negative or too big shift count +warning_241_242.pwn(152) : warning 241: negative or too big shift count +""" +} diff --git a/source/compiler/tests/warning_241.pwn b/source/compiler/tests/warning_241_242.pwn similarity index 70% rename from source/compiler/tests/warning_241.pwn rename to source/compiler/tests/warning_241_242.pwn index 17bbe726..1cd6d04c 100644 --- a/source/compiler/tests/warning_241.pwn +++ b/source/compiler/tests/warning_241_242.pwn @@ -1,5 +1,100 @@ #include +enum (<<= 32) +{ + a0 = 0 +}; + +enum (<<= -1) +{ + b0 = 0 +}; + +enum (<<= 1) +{ + c0 = 0 +}; +enum (<<= 31) +{ + d0 = 0 +}; + +enum (<<= 1) +{ + e0 = 1, + e1, + e2, + e3, + e4, + e5, + e6, + e7, + e8, + e9, + e10, + e11, + e12, + e13, + e14, + e15, + e16, + e17, + e18, + e19, + e20, + e21, + e22, + e23, + e24, + e25, + e26, + e27, + e28, + e29, + e30, + e31, // 0b10000000000000000000000000000000 + e32 // overflow +}; + +enum (<<= 1) +{ + f0 = 1, + f1, + f2, + f3, + f4, + f5, + f6, + f7, + f8, + f9, + f10, + f11, + f12, + f13, + f14, + f15, + f16, + f17, + f18, + f19, + f20, + f21, + f22, + f23, + f24, + f25, + f26, + f27, + f28, + f29, + f30, + f31, // 0b10000000000000000000000000000000 + f32 = f31-1,// 0b01111111111111111111111111111111 + f33, // 0b11111111111111111111111111111110 + f34 // overflow +}; + main() { new var = 1; From 3d0ca3208e8d78431c0876c9a6b51011694f9b46 Mon Sep 17 00:00:00 2001 From: Stanislav Gromov Date: Wed, 16 Sep 2020 19:21:12 +0800 Subject: [PATCH 09/10] Reset variable "overflow" when the warning has been shown, so it won't be shown again for the next enum item. Also rename the variable into more descriptive "warn_overflow". --- source/compiler/sc1.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 864c6e5a..ff711bad 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -2929,7 +2929,7 @@ static void decl_enum(int vclass,int fstatic) char *str; int tag,explicittag; int inctok; - int overflow; + int warn_overflow; cell increment; constvalue_root *enumroot=NULL; symbol *enumsym=NULL; @@ -2997,7 +2997,7 @@ static void decl_enum(int vclass,int fstatic) needtoken('{'); /* go through all constants */ value=0; /* default starting value */ - overflow=FALSE; + warn_overflow=FALSE; do { int idxtag,fieldtag; int symline; @@ -3022,11 +3022,12 @@ static void decl_enum(int vclass,int fstatic) } /* if */ if (matchtoken('=')) { constexpr(&value,NULL,NULL); /* get value */ - overflow=FALSE; - } else if (overflow) { + warn_overflow=FALSE; + } else if (warn_overflow) { errorset(sSETPOS,symline); error(242,constname); /* shift overflow for enum item */ errorset(sSETPOS,-1); + warn_overflow=FALSE; } /* if */ /* add_constant() checks whether a variable (global or local) or * a constant with the same name already exists @@ -3059,7 +3060,7 @@ static void decl_enum(int vclass,int fstatic) value*=(size*increment); } else { // taSHL if ((ucell)value>=((ucell)1 << (PAWN_CELL_SIZE-increment))) - overflow=TRUE; + warn_overflow=TRUE; value*=(size << increment); } /* if */ } while (matchtoken(',')); From e7451046b0c34cbe0ccb6f50251cfbfccacee254 Mon Sep 17 00:00:00 2001 From: Stanislav Gromov Date: Wed, 16 Sep 2020 20:23:18 +0800 Subject: [PATCH 10/10] Update tests --- source/compiler/tests/warning_241_242.meta | 19 ++++++++++--------- source/compiler/tests/warning_241_242.pwn | 8 +++++--- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/source/compiler/tests/warning_241_242.meta b/source/compiler/tests/warning_241_242.meta index 82f310bb..b9aba086 100644 --- a/source/compiler/tests/warning_241_242.meta +++ b/source/compiler/tests/warning_241_242.meta @@ -4,30 +4,31 @@ warning_241_242.pwn(3) : warning 241: negative or too big shift count warning_241_242.pwn(8) : warning 241: negative or too big shift count warning_241_242.pwn(56) : warning 242: shift overflow in enum item declaration (symbol "e32") -warning_241_242.pwn(95) : warning 242: shift overflow in enum item declaration (symbol "f34") -warning_241_242.pwn(103) : warning 241: negative or too big shift count -warning_241_242.pwn(104) : warning 241: negative or too big shift count +warning_241_242.pwn(96) : warning 242: shift overflow in enum item declaration (symbol "f34") +warning_241_242.pwn(97) : warning 242: shift overflow in enum item declaration (symbol "f35") warning_241_242.pwn(105) : warning 241: negative or too big shift count warning_241_242.pwn(106) : warning 241: negative or too big shift count warning_241_242.pwn(107) : warning 241: negative or too big shift count warning_241_242.pwn(108) : warning 241: negative or too big shift count -warning_241_242.pwn(121) : warning 241: negative or too big shift count -warning_241_242.pwn(122) : warning 241: negative or too big shift count +warning_241_242.pwn(109) : warning 241: negative or too big shift count +warning_241_242.pwn(110) : warning 241: negative or too big shift count warning_241_242.pwn(123) : warning 241: negative or too big shift count warning_241_242.pwn(124) : warning 241: negative or too big shift count warning_241_242.pwn(125) : warning 241: negative or too big shift count warning_241_242.pwn(126) : warning 241: negative or too big shift count -warning_241_242.pwn(129) : warning 241: negative or too big shift count -warning_241_242.pwn(130) : warning 241: negative or too big shift count +warning_241_242.pwn(127) : warning 241: negative or too big shift count +warning_241_242.pwn(128) : warning 241: negative or too big shift count warning_241_242.pwn(131) : warning 241: negative or too big shift count warning_241_242.pwn(132) : warning 241: negative or too big shift count warning_241_242.pwn(133) : warning 241: negative or too big shift count warning_241_242.pwn(134) : warning 241: negative or too big shift count -warning_241_242.pwn(147) : warning 241: negative or too big shift count -warning_241_242.pwn(148) : warning 241: negative or too big shift count +warning_241_242.pwn(135) : warning 241: negative or too big shift count +warning_241_242.pwn(136) : warning 241: negative or too big shift count warning_241_242.pwn(149) : warning 241: negative or too big shift count warning_241_242.pwn(150) : warning 241: negative or too big shift count warning_241_242.pwn(151) : warning 241: negative or too big shift count warning_241_242.pwn(152) : warning 241: negative or too big shift count +warning_241_242.pwn(153) : warning 241: negative or too big shift count +warning_241_242.pwn(154) : warning 241: negative or too big shift count """ } diff --git a/source/compiler/tests/warning_241_242.pwn b/source/compiler/tests/warning_241_242.pwn index 1cd6d04c..74daa095 100644 --- a/source/compiler/tests/warning_241_242.pwn +++ b/source/compiler/tests/warning_241_242.pwn @@ -51,9 +51,10 @@ enum (<<= 1) e27, e28, e29, - e30, + e30, // 0b01000000000000000000000000000000 e31, // 0b10000000000000000000000000000000 - e32 // overflow + e32, // 0b00000000000000000000000000000000 (overflow) + e33 // 0b00000000000000000000000000000000 }; enum (<<= 1) @@ -92,7 +93,8 @@ enum (<<= 1) f31, // 0b10000000000000000000000000000000 f32 = f31-1,// 0b01111111111111111111111111111111 f33, // 0b11111111111111111111111111111110 - f34 // overflow + f34, // 0b11111111111111111111111111111100 (overflow) + f35 // 0b11111111111111111111111111111000 (overflow) }; main()