Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check switch/case values for tag mismatch #475

Merged
merged 3 commits into from Mar 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 6 additions & 3 deletions source/compiler/sc1.c
Expand Up @@ -5828,14 +5828,15 @@ 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 */
constvalue *cse,*csp,*newval;
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).
Expand Down Expand Up @@ -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.
Expand All @@ -5898,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 */
Expand Down
9 changes: 9 additions & 0 deletions source/compiler/tests/switch-case-tag-control.meta
@@ -0,0 +1,9 @@
{
'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 ("_")
switch-case-tag-control.pwn(24) : warning 213: tag mismatch: expected tag none ("_"), but found "Tag"
"""
}
26 changes: 26 additions & 0 deletions source/compiler/tests/switch-case-tag-control.pwn
@@ -0,0 +1,26 @@
#include <float>

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)
}
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)
}
}