From de2266d40000963aeb9ef56cf8075aa7573e2caa Mon Sep 17 00:00:00 2001 From: Stanislav Gromov Date: Sat, 28 Dec 2019 17:13:34 +0700 Subject: [PATCH 1/3] Check switch/case values for tag mismatch --- source/compiler/sc1.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 04193eee..5e319c77 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -5828,6 +5828,7 @@ static void doswitch(void) int lbl_table,lbl_exit,lbl_case; int swdefault,casecount; int tok,endtok; + int swtag,csetag; cell val; char *str; constvalue_root caselist = { NULL, NULL}; /* case list starts empty */ @@ -5835,7 +5836,7 @@ static void doswitch(void) char labelname[sNAMEMAX+1]; endtok= matchtoken('(') ? ')' : tDO; - doexpr(TRUE,FALSE,FALSE,FALSE,NULL,NULL,TRUE);/* evaluate switch expression */ + doexpr(TRUE,FALSE,FALSE,FALSE,&swtag,NULL,TRUE);/* evaluate switch expression */ needtoken(endtok); /* generate the code for the switch statement, the label is the address * of the case table (to be generated later). @@ -5874,7 +5875,8 @@ static void doswitch(void) * parse all expressions until that special token. */ - constexpr(&val,NULL,NULL); + constexpr(&val,&csetag,NULL); + check_tagmismatch(swtag,csetag,TRUE,-1); /* Search the insertion point (the table is kept in sorted order, so * that advanced abstract machines can sift the case table with a * binary search). Check for duplicate case values at the same time. From cecbfe704373f54aa5c1e20e83d04ae99a58cb2b Mon Sep 17 00:00:00 2001 From: Stanislav Gromov Date: Sat, 28 Dec 2019 17:47:45 +0700 Subject: [PATCH 2/3] Add tests --- .../tests/switch-case-tag-control.meta | 8 ++++++++ .../tests/switch-case-tag-control.pwn | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 source/compiler/tests/switch-case-tag-control.meta create mode 100644 source/compiler/tests/switch-case-tag-control.pwn diff --git a/source/compiler/tests/switch-case-tag-control.meta b/source/compiler/tests/switch-case-tag-control.meta new file mode 100644 index 00000000..8d84b11d --- /dev/null +++ b/source/compiler/tests/switch-case-tag-control.meta @@ -0,0 +1,8 @@ +{ + 'test_type': 'output_check', + 'errors': """ +switch-case-tag-control.pwn(10) : warning 213: tag mismatch: expected tag none ("_"), but found "Float" +switch-case-tag-control.pwn(16) : warning 213: tag mismatch: expected tag "Float", but found "bool" +switch-case-tag-control.pwn(17) : warning 213: tag mismatch: expected tag "Float", but found none ("_") +""" +} diff --git a/source/compiler/tests/switch-case-tag-control.pwn b/source/compiler/tests/switch-case-tag-control.pwn new file mode 100644 index 00000000..e4c88855 --- /dev/null +++ b/source/compiler/tests/switch-case-tag-control.pwn @@ -0,0 +1,19 @@ +#include + +main() +{ + new x = 0; + switch (x) + { + case 0: {} // no tag (ok) + case true: {} // bool (should work since "bool" is a weak tag) + case 2.0: {} // Float: (tag mismatch; "Float" is a strong tag) + } + new Float:f = 0.0; + switch (f) + { + case 0.0: {} // Float (ok) + case true: {} // bool (tag mismatch) + case 2: {} // no tag (tag mismatch) + } +} From e4b2a87bac3d0ff808211f0d12d6ea79d5786e03 Mon Sep 17 00:00:00 2001 From: Stanislav Gromov Date: Sun, 15 Mar 2020 17:28:20 +0700 Subject: [PATCH 3/3] Also check the tag for range end values --- source/compiler/sc1.c | 3 ++- source/compiler/tests/switch-case-tag-control.meta | 1 + source/compiler/tests/switch-case-tag-control.pwn | 7 +++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 5e319c77..f19bdf51 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -5900,9 +5900,10 @@ static void doswitch(void) caselist.first=newval; if (matchtoken(tDBLDOT)) { cell end; - constexpr(&end,NULL,NULL); + constexpr(&end,&csetag,NULL); if (end<=val) error(50); /* invalid range */ + check_tagmismatch(swtag,csetag,TRUE,-1); while (++val<=end) { casecount++; /* find the new insertion point */ diff --git a/source/compiler/tests/switch-case-tag-control.meta b/source/compiler/tests/switch-case-tag-control.meta index 8d84b11d..a4e5f222 100644 --- a/source/compiler/tests/switch-case-tag-control.meta +++ b/source/compiler/tests/switch-case-tag-control.meta @@ -4,5 +4,6 @@ switch-case-tag-control.pwn(10) : warning 213: tag mismatch: expected tag none ("_"), but found "Float" switch-case-tag-control.pwn(16) : warning 213: tag mismatch: expected tag "Float", but found "bool" switch-case-tag-control.pwn(17) : warning 213: tag mismatch: expected tag "Float", but found none ("_") +switch-case-tag-control.pwn(24) : warning 213: tag mismatch: expected tag none ("_"), but found "Tag" """ } diff --git a/source/compiler/tests/switch-case-tag-control.pwn b/source/compiler/tests/switch-case-tag-control.pwn index e4c88855..5c0cf0e3 100644 --- a/source/compiler/tests/switch-case-tag-control.pwn +++ b/source/compiler/tests/switch-case-tag-control.pwn @@ -16,4 +16,11 @@ main() case true: {} // bool (tag mismatch) case 2: {} // no tag (tag mismatch) } + const Tag:THREE = Tag:3; + switch (x) + { + case -2 .. -1: {} // no tag (ok) + case 0 .. true: {} // bool (should work since "bool" is a weak tag) + case 2 .. THREE: {} // Tag: (tag mismatch; "Tag" is a strong tag) + } }