Skip to content

Commit 001f483

Browse files
committed
Merge remote-tracking branch 'remotes/Daniel-Cortez/warning-247' into dev
2 parents 74004e4 + bbcddab commit 001f483

File tree

6 files changed

+161
-23
lines changed

6 files changed

+161
-23
lines changed

source/compiler/sc3.c

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ static int dbltest(void (*oper)(),value *lval1,value *lval2);
6161
static int commutative(void (*oper)());
6262
static int constant(value *lval);
6363

64+
static const char str_w247unary[]="a \"bool:\" value";
65+
static const char str_w247binary[]="\"bool:\" values";
6466
static char lastsymbol[sNAMEMAX+1]; /* name of last function/variable */
6567
static int bitwise_opercount; /* count of bitwise operators in an expression */
6668
static int decl_heap=0;
@@ -78,15 +80,15 @@ static void (*op1[17])(void) = {
7880
os_le,os_ge,os_lt,os_gt, /* hier9, index 11 */
7981
ob_eq,ob_ne, /* hier10, index 15 */
8082
};
81-
/* These two functions are defined because the functions inc() and dec() in
82-
* SC4.C have a different prototype than the other code generation functions.
83+
/* These two macros are defined because the functions inc() and dec() in SC4.C
84+
* have a different prototype than the other code generation functions.
8385
* The arrays for user-defined functions use the function pointers for
8486
* identifying what kind of operation is requested; these functions must all
8587
* have the same prototype. As inc() and dec() are special cases already, it
86-
* is simplest to add two "do-nothing" functions.
88+
* is simplest to cast them into "void (*)(void)".
8789
*/
88-
static void user_inc(void) {}
89-
static void user_dec(void) {}
90+
#define user_inc ((void (*)(void))inc)
91+
#define user_dec ((void (*)(void))dec)
9092

9193
/*
9294
* Searches for a binary operator a list of operators. The list is stored in
@@ -646,9 +648,29 @@ static void plnge2(void (*oper)(void),
646648
lval1->ident=iEXPRESSION;
647649
lval1->constval=0;
648650
} else {
649-
if ((oper==ob_sal || oper==os_sar || oper==ou_sar)
650-
&& (lval2->ident==iCONSTEXPR && (lval2->constval<0 || lval2->constval>=PAWN_CELL_SIZE)))
651+
if (lval1->tag==BOOLTAG && lval2->tag==BOOLTAG
652+
&& oper!=ob_or && oper!=ob_xor && oper!=ob_and && oper!=ob_eq && oper!=ob_ne) {
653+
static const void (*opers[])(void) = {
654+
os_mult,os_div,os_mod,ob_add,ob_sub,ob_sal,
655+
os_sar,ou_sar,os_le,os_ge,os_lt,os_gt
656+
};
657+
static const char* opnames[] = {
658+
"*","/","%","+","-","<<",
659+
">>",">>>","<=",">=","<",">"
660+
};
661+
int i;
662+
assert_static(arraysize(opers)==arraysize(opnames)); /* make sure the array sizes match */
663+
assert_static(arraysize(op1)==17); /* in case a new operator is added into the compiler,
664+
* arrays "opers" and "opnames" might need to be updated */
665+
for (i=0; i<arraysize(opers); i++)
666+
if (oper==opers[i])
667+
break;
668+
assert(i<arraysize(opers));
669+
error(247,opnames[i],str_w247binary); /* use of operator on \"bool:\" values */
670+
} else if ((oper==ob_sal || oper==os_sar || oper==ou_sar)
671+
&& (lval2->ident==iCONSTEXPR && (lval2->constval<0 || lval2->constval>=PAWN_CELL_SIZE))) {
651672
error(241); /* negative or too big shift count */
673+
} /* if */
652674
if (lval1->ident==iCONSTEXPR && lval2->ident==iCONSTEXPR) {
653675
/* only constant expression if both constant */
654676
stgdel(lval_stgidx,lval_cidx); /* scratch generated code and calculate */
@@ -1283,8 +1305,11 @@ static int hier2(value *lval)
12831305
assert(lval->sym!=NULL);
12841306
if ((lval->sym->usage & uCONST)!=0)
12851307
return error(22); /* assignment to const argument */
1286-
if (!check_userop(user_inc,lval->tag,0,1,lval,&lval->tag))
1308+
if (!check_userop(user_inc,lval->tag,0,1,lval,&lval->tag)) {
1309+
if (lval->tag==BOOLTAG)
1310+
error(247,"++",str_w247unary); /* use of operator "++" on a "bool:" value */
12871311
inc(lval); /* increase variable first */
1312+
} /* if */
12881313
rvalue(lval); /* and read the result into PRI */
12891314
pc_sideeffect=TRUE;
12901315
return FALSE; /* result is no longer lvalue */
@@ -1294,8 +1319,11 @@ static int hier2(value *lval)
12941319
assert(lval->sym!=NULL);
12951320
if ((lval->sym->usage & uCONST)!=0)
12961321
return error(22); /* assignment to const argument */
1297-
if (!check_userop(user_dec,lval->tag,0,1,lval,&lval->tag))
1322+
if (!check_userop(user_dec,lval->tag,0,1,lval,&lval->tag)) {
1323+
if (lval->tag==BOOLTAG)
1324+
error(247,"--",str_w247unary); /* use of operator "--" on a "bool:" value */
12981325
dec(lval); /* decrease variable first */
1326+
} /* if */
12991327
rvalue(lval); /* and read the result into PRI */
13001328
pc_sideeffect=TRUE;
13011329
return FALSE; /* result is no longer lvalue */
@@ -1307,7 +1335,7 @@ static int hier2(value *lval)
13071335
if (lval->ident==iVARIABLE || lval->ident==iARRAYCELL)
13081336
lval->ident=iEXPRESSION;
13091337
if (lval->tag==BOOLTAG)
1310-
error(makelong(247,3),"!"); /* use of operator "~" on a "bool:" value always results in "true" */
1338+
error(makelong(247,3),"~",str_w247unary,"!"); /* use of operator "~" on a "bool:" value; did you mean to use operator "!"? */
13111339
return FALSE;
13121340
case '!': /* ! (logical negate) */
13131341
if (hier2(lval))
@@ -1352,6 +1380,8 @@ static int hier2(value *lval)
13521380
lval->constval=-lval->constval;
13531381
if (lval->ident==iVARIABLE || lval->ident==iARRAYCELL)
13541382
lval->ident=iEXPRESSION;
1383+
if (lval->tag==BOOLTAG)
1384+
error(makelong(247,3),"-",str_w247unary,"!"); /* use of operator "-" on a "bool:" value; did you mean to use operator "!"? */
13551385
} /* if */
13561386
return FALSE;
13571387
case tLABEL: /* tagname override */
@@ -1676,8 +1706,11 @@ static int hier2(value *lval)
16761706
rvalue(lval); /* read current value into PRI */
16771707
if (saveresult)
16781708
swap1(); /* save PRI on the stack, restore address in PRI */
1679-
if (!check_userop(user_inc,lval->tag,0,1,lval,&lval->tag))
1709+
if (!check_userop(user_inc,lval->tag,0,1,lval,&lval->tag)) {
1710+
if (lval->tag==BOOLTAG)
1711+
error(247,"++",str_w247unary); /* use of operator "++" on a "bool:" value */
16801712
inc(lval); /* increase variable afterwards */
1713+
} /* if */
16811714
if (saveresult)
16821715
popreg(sPRI); /* restore PRI (result of rvalue()) */
16831716
pc_sideeffect=TRUE;
@@ -1694,8 +1727,11 @@ static int hier2(value *lval)
16941727
rvalue(lval); /* read current value into PRI */
16951728
if (saveresult)
16961729
swap1(); /* save PRI on the stack, restore address in PRI */
1697-
if (!check_userop(user_dec,lval->tag,0,1,lval,&lval->tag))
1730+
if (!check_userop(user_dec,lval->tag,0,1,lval,&lval->tag)) {
1731+
if (lval->tag==BOOLTAG)
1732+
error(247,"--",str_w247unary); /* use of operator "--" on a "bool:" value */
16981733
dec(lval); /* decrease variable afterwards */
1734+
} /* if */
16991735
if (saveresult)
17001736
popreg(sPRI); /* restore PRI (result of rvalue()) */
17011737
pc_sideeffect=TRUE;

source/compiler/sc5.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,14 @@ static char *warnmsg[] = {
205205
/*244*/ "enum element \"%s\" not handled in switch\n",
206206
/*245*/ "enum increment \"%s %d\" has no effect on zero value (symbol \"%s\")\n",
207207
/*246*/ "multiplication overflow in enum element declaration (symbol \"%s\")\n",
208-
/*247*/ "use of operator \"~\" on a \"bool:\" value always results in \"true\"\n",
208+
/*247*/ "use of operator \"%s\" on %s\n",
209209
/*248*/ "possible misuse of comma operator\n"
210210
};
211211

212212
static char *noticemsg[] = {
213213
/*001*/ "; did you mean \"%s\"?\n",
214214
/*002*/ "; state variable out of scope\n",
215-
/*003*/ "; did you mean operator \"%s\"?\n"
215+
/*003*/ "; did you mean to use operator \"%s\"?\n"
216216
};
217217

218218
#define NUM_WARNINGS arraysize(warnmsg)
Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
11
{
22
'test_type': 'output_check',
33
'errors': """
4-
warning_247.pwn(9) : warning 247: use of operator "~" on a "bool:" value always results in "true"; did you mean operator "!"?
5-
warning_247.pwn(11) : warning 247: use of operator "~" on a "bool:" value always results in "true"; did you mean operator "!"?
4+
warning_247.pwn(35) : warning 247: use of operator "<=" on "bool:" values
5+
warning_247.pwn(36) : warning 247: use of operator ">=" on "bool:" values
6+
warning_247.pwn(37) : warning 247: use of operator "<" on "bool:" values
7+
warning_247.pwn(38) : warning 247: use of operator ">" on "bool:" values
8+
warning_247.pwn(39) : warning 247: use of operator "~" on a "bool:" value; did you mean to use operator "!"?
9+
warning_247.pwn(40) : warning 247: use of operator "-" on a "bool:" value; did you mean to use operator "!"?
10+
warning_247.pwn(41) : warning 247: use of operator "++" on a "bool:" value
11+
warning_247.pwn(42) : warning 247: use of operator "++" on a "bool:" value
12+
warning_247.pwn(43) : warning 247: use of operator "--" on a "bool:" value
13+
warning_247.pwn(44) : warning 247: use of operator "--" on a "bool:" value
14+
warning_247.pwn(45) : warning 247: use of operator "*" on "bool:" values
15+
warning_247.pwn(46) : warning 247: use of operator "/" on "bool:" values
16+
warning_247.pwn(47) : warning 247: use of operator "%" on "bool:" values
17+
warning_247.pwn(48) : warning 247: use of operator "+" on "bool:" values
18+
warning_247.pwn(49) : warning 247: use of operator "-" on "bool:" values
19+
warning_247.pwn(50) : warning 247: use of operator "<<" on "bool:" values
20+
warning_247.pwn(51) : warning 247: use of operator ">>" on "bool:" values
21+
warning_247.pwn(52) : warning 247: use of operator ">>>" on "bool:" values
22+
warning_247.pwn(55) : warning 247: use of operator "~" on a "bool:" value; did you mean to use operator "!"?
623
"""
724
}

source/compiler/tests/warning_247.pwn

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,56 @@
11
main()
22
{
3-
new a = 0, bool:b = false, c;
3+
new bool:a = true, bool:b = false;
4+
new u1 = 1, u2 = 0;
5+
6+
if (u1) {}
7+
if (!u1) {}
8+
if (~u1) {}
9+
if (-u1) {}
10+
if (++u1) {}
11+
if (u1++) {}
12+
if (--u1) {}
13+
if (u1--) {}
14+
if (u1 || u2) {}
15+
if (u1 ^ u2) {}
16+
if (u1 && u2) {}
17+
if (u1 == u2) {}
18+
if (u1 != u2) {}
19+
if (u1 * u2) {}
20+
if (u1 / u2) {}
21+
if (u1 % u2) {}
22+
if (u1 + u2) {}
23+
if (u1 - u2) {}
24+
if (u1 << u2) {}
25+
if (u1 >> u2) {}
26+
if (u1 >>> u2) {}
27+
428
if (a) {}
5-
if (b) {}
629
if (!a) {}
7-
if (!b) {}
8-
if (~a) {} // bitwise inversion on an untagged value is OK
9-
if (~b) {} // warning 247: use of operator "~" on a "bool:" value always results in "true"; did you mean operator "!"?
10-
if (~(a & c)) {} // bitwise AND, the result is not forced to be "bool:"-tagged
11-
if (~(a && c)) {} // warning 247: use of operator "~" on a "bool:" value always results in "true"; did you mean operator "!"?
30+
if (a || b) {}
31+
if (a ^ b) {}
32+
if (a && b) {}
33+
if (a == b) {}
34+
if (a != b) {}
35+
if (a <= b) {} // warning 247: use of operator "<=" on "bool:" values
36+
if (a >= b) {} // warning 247: use of operator ">=" on "bool:" values
37+
if (a < b) {} // warning 247: use of operator "<" on "bool:" values
38+
if (a > b) {} // warning 247: use of operator ">" on "bool:" values
39+
if (~a) {} // warning 247: use of operator "~" on a "bool:" value; did you mean to use operator "!"?
40+
if (-a) {} // warning 247: use of operator "-" on a "bool:" value; did you mean to use operator "!"?
41+
if (++a) {} // warning 247: use of operator "++" on a "bool:" value
42+
if (a++) {} // warning 247: use of operator "++" on a "bool:" value
43+
if (--a) {} // warning 247: use of operator "--" on a "bool:" value
44+
if (a--) {} // warning 247: use of operator "--" on a "bool:" value
45+
if (a * b) {} // warning 247: use of operator "*" on "bool:" values
46+
if (a / b) {} // warning 247: use of operator "/" on "bool:" values
47+
if (a % b) {} // warning 247: use of operator "%" on "bool:" values
48+
if (a + b) {} // warning 247: use of operator "+" on "bool:" values
49+
if (a - b) {} // warning 247: use of operator "-" on "bool:" values
50+
if (a << b) {} // warning 247: use of operator "<<" on "bool:" values
51+
if (a >> b) {} // warning 247: use of operator ">>" on "bool:" values
52+
if (a >>> b) {}// warning 247: use of operator ">>>" on "bool:" values
53+
54+
if (~(u1 & u2)) {} // bitwise AND, the result is not forced to be "bool:"-tagged
55+
if (~(u1 && u2)) {} // warning 247: use of operator "~" on a "bool:" value; did you mean operator "!"?
1256
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
'test_type': 'output_check',
3+
'errors': """
4+
"""
5+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// This test makes sure overloaded operators for tag `bool:` don't trigger
2+
// warning 247. The code in 'main()' is copied from file "warning_247.pwn",
3+
// but with the lines that test operators `<<`, `>>`, `>>>` and `~` removed,
4+
// as shift operators can't be overloaded and `~` is reserved for destructors.
5+
6+
bool:operator -(bool:oper) return oper;
7+
bool:operator ++(bool:oper) return oper;
8+
bool:operator --(bool:oper) return oper;
9+
bool:operator *(bool:oper1, bool:oper2) return oper1,oper2;
10+
bool:operator /(bool:oper1, bool:oper2) return oper1,oper2;
11+
bool:operator %(bool:oper1, bool:oper2) return oper1,oper2;
12+
bool:operator +(bool:oper1, bool:oper2) return oper1,oper2;
13+
bool:operator -(bool:oper1, bool:oper2) return oper1,oper2;
14+
bool:operator <=(bool:oper1, bool:oper2) return oper1,oper2;
15+
bool:operator >=(bool:oper1, bool:oper2) return oper1,oper2;
16+
bool:operator <(bool:oper1, bool:oper2) return oper1,oper2;
17+
bool:operator >(bool:oper1, bool:oper2) return oper1,oper2;
18+
19+
main()
20+
{
21+
new bool:a = true, bool:b = false;
22+
if (a <= b) {}
23+
if (a >= b) {}
24+
if (a < b) {}
25+
if (a > b) {}
26+
if (-a) {}
27+
if (++a) {}
28+
if (a++) {}
29+
if (--a) {}
30+
if (a--) {}
31+
if (a * b) {}
32+
if (a / b) {}
33+
if (a % b) {}
34+
if (a + b) {}
35+
if (a - b) {}
36+
}

0 commit comments

Comments
 (0)