Skip to content

Commit fbf9071

Browse files
committed
Merge remote-tracking branch 'remotes/DanielCortez/__pragma-warning' into dev
2 parents aa8a3de + 1d881b2 commit fbf9071

File tree

6 files changed

+98
-28
lines changed

6 files changed

+98
-28
lines changed

source/compiler/sc.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,12 @@ typedef enum s_optmark {
539539

540540
#define MAX_INSTR_LEN 30
541541

542+
typedef enum s_warnmode {
543+
warnDISABLE,
544+
warnENABLE,
545+
warnTOGGLE
546+
} warnmode;
547+
542548
#define eotNUMBER 0
543549
#define eotFUNCTION 1
544550
#define eotLABEL 2
@@ -607,7 +613,7 @@ enum { /* attribute flags for "__pragma" */
607613
int pc_compile(int argc, char **argv);
608614
int pc_addconstant(char *name,cell value,int tag);
609615
int pc_addtag(char *name);
610-
int pc_enablewarning(int number,int enable);
616+
int pc_enablewarning(int number,warnmode enable);
611617
int pc_pushwarnings();
612618
int pc_popwarnings();
613619
void pc_seterrorwarnings(int enable);
@@ -698,6 +704,7 @@ SC_FUNC stkitem popstk(void);
698704
SC_FUNC void clearstk(void);
699705
SC_FUNC int plungequalifiedfile(char *name); /* explicit path included */
700706
SC_FUNC int plungefile(char *name,int try_currentpath,int try_includepaths); /* search through "include" paths */
707+
SC_FUNC int number(cell *val,const unsigned char *curptr);
701708
SC_FUNC void preprocess(void);
702709
SC_FUNC void lexinit(void);
703710
SC_FUNC int lex(cell *lexvalue,char **lexsym);

source/compiler/sc1.c

+44-10
Original file line numberDiff line numberDiff line change
@@ -1213,11 +1213,11 @@ static void parseoptions(int argc,char **argv,char *oname,char *ename,char *pnam
12131213
case 'w':
12141214
i=(int)strtol(option_value(ptr),(char **)&ptr,10);
12151215
if (*ptr=='-')
1216-
pc_enablewarning(i,0);
1216+
pc_enablewarning(i,warnDISABLE);
12171217
else if (*ptr=='+')
1218-
pc_enablewarning(i,1);
1218+
pc_enablewarning(i,warnENABLE);
12191219
else if (*ptr=='\0')
1220-
pc_enablewarning(i,2);
1220+
pc_enablewarning(i,warnTOGGLE);
12211221
break;
12221222
case 'X':
12231223
if (*(ptr+1)=='D') {
@@ -8165,7 +8165,6 @@ static void dopragma(void)
81658165
int tok;
81668166
int bck_litidx,bck_packstr;
81678167
int i;
8168-
int hasparams;
81698168
cell val;
81708169
char *str;
81718170

@@ -8200,7 +8199,7 @@ static void dopragma(void)
82008199
assert(litidx>bck_litidx);
82018200

82028201
/* the user shouldn't prepend "!" to the option string */
8203-
if (litq[val]<=UNPACKEDMAX) {
8202+
if (litq[val]<=UNPACKEDMAX && litq[val]!=0) {
82048203
error(1,sc_tokens[tSTRING-tFIRST],"!");
82058204
goto next;
82068205
} /* if */
@@ -8230,11 +8229,13 @@ static void dopragma(void)
82308229

82318230
/* split the option name from parameters */
82328231
str=(char*)&litq[val];
8233-
for (i=0; str[i]!='\0' && str[i]!=' '; i++) {}
8234-
hasparams=(str[i]!='\0');
8235-
str[i]='\0';
8236-
if (hasparams)
8237-
while (str[++i]==' ') {}
8232+
for (i=0; str[i]!='\0' && str[i]!=' '; i++)
8233+
/* nothing */;
8234+
if (str[i]!='\0') {
8235+
str[i]='\0';
8236+
while (str[++i]==' ')
8237+
/* nothing */;
8238+
} /* if */
82388239

82398240
/* check the option name, set the corresponding attribute flag
82408241
* and parse the argument(s), if needed */
@@ -8246,15 +8247,48 @@ static void dopragma(void)
82468247
pc_attributes |= (1U << attrDEPRECATED);
82478248
} else if (!strcmp(str,"unused")) {
82488249
pc_attributes |= (1U << attrUNUSED);
8250+
if (str[i]!='\0') goto unknown_pragma;
82498251
} else if (!strcmp(str,"unread")) {
82508252
pc_attributes |= (1U << attrUNREAD);
8253+
if (str[i]!='\0') goto unknown_pragma;
82518254
} else if (!strcmp(str,"unwritten")) {
82528255
pc_attributes |= (1U << attrUNWRITTEN);
8256+
if (str[i]!='\0') goto unknown_pragma;
82538257
} else if (!strcmp(str,"nodestruct")) {
82548258
pc_attributes |= (1U << attrNODESTRUCT);
8259+
if (str[i]!='\0') goto unknown_pragma;
82558260
} else if (!strcmp(str,"naked")) {
82568261
pc_attributes |= (1U << attrNAKED);
8262+
if (str[i]!='\0') goto unknown_pragma;
8263+
} else if (!strcmp(str,"warning")) {
8264+
str += i;
8265+
while (*str==' ') str++;
8266+
for (i=0; str[i]!='\0' && str[i]!=' '; i++)
8267+
/* nothing */;
8268+
if (str[i]!='\0') {
8269+
str[i]='\0';
8270+
while (str[++i]==' ')
8271+
/* nothing */;
8272+
} /* if */
8273+
if (strcmp(str,"enable")==0 || strcmp(str,"disable")==0) {
8274+
int len=number(&val,&str[i]);
8275+
if (len==0)
8276+
goto unknown_pragma;
8277+
pc_enablewarning((int)val,(str[0]=='e') ? warnENABLE : warnDISABLE);
8278+
/* warn if there are extra characters after the warning number */
8279+
for (i += len; str[i]==' '; i++)
8280+
/* nothing */;
8281+
if (str[i]!='\0')
8282+
goto unknown_pragma;
8283+
} else if (strcmp(str,"push")==0 && str[i]=='\0') {
8284+
pc_pushwarnings();
8285+
} else if (strcmp(str,"pop")==0 && str[i]=='\0') {
8286+
pc_popwarnings();
8287+
} else {
8288+
goto unknown_pragma;
8289+
} /* if */
82578290
} else {
8291+
unknown_pragma:
82588292
error(207); /* unknown #pragma */
82598293
} /* if */
82608294

source/compiler/sc2.c

+5-11
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ static int ftoi(cell *val,const unsigned char *curptr)
843843
* for at "hier2()" (in fact, it is viewed as an operator, not as a
844844
* sign) and the + is invalid (as in K&R C, and unlike ANSI C).
845845
*/
846-
static int number(cell *val,const unsigned char *curptr)
846+
SC_FUNC int number(cell *val,const unsigned char *curptr)
847847
{
848848
int i;
849849
cell value;
@@ -1305,29 +1305,23 @@ static int command(void)
13051305
} else if (strcmp(str,"warning")==0) {
13061306
int ok=lex(&val,&str)==tSYMBOL;
13071307
if (ok) {
1308-
if (strcmp(str,"enable")==0) {
1308+
if (strcmp(str,"enable")==0 || strcmp(str,"disable")==0) {
13091309
cell val;
13101310
do {
13111311
preproc_expr(&val,NULL);
1312-
pc_enablewarning(val,1);
1313-
} while (*lptr!='\0');
1314-
} else if (strcmp(str,"disable")==0) {
1315-
cell val;
1316-
do {
1317-
preproc_expr(&val,NULL);
1318-
pc_enablewarning(val,0);
1312+
pc_enablewarning(val,(str[0]=='e') ? warnENABLE : warnDISABLE);
13191313
} while (*lptr!='\0');
13201314
} else if (strcmp(str,"push")==0) {
13211315
pc_pushwarnings();
13221316
} else if (strcmp(str,"pop")==0) {
13231317
pc_popwarnings();
13241318
} else {
13251319
ok=FALSE;
1326-
}
1320+
} /* if */
13271321
}
13281322
if (!ok) {
13291323
error(207); /* unknown #pragma */
1330-
}
1324+
} /* if */
13311325
} else if (strcmp(str,"compat")==0) {
13321326
cell val;
13331327
symbol *sym;

source/compiler/sc5.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ SC_FUNC void errorset(int code,int line)
385385
* o 1 for enable
386386
* o 2 for toggle
387387
*/
388-
int pc_enablewarning(int number,int enable)
388+
int pc_enablewarning(int number,warnmode enable)
389389
{
390390
int index;
391391
unsigned char mask;
@@ -399,13 +399,13 @@ int pc_enablewarning(int number,int enable)
399399
index=number/8;
400400
mask=(unsigned char)(1 << (number%8));
401401
switch (enable) {
402-
case 0:
402+
case warnDISABLE:
403403
warnstack.disable[index] |= mask;
404404
break;
405-
case 1:
405+
case warnENABLE:
406406
warnstack.disable[index] &= (unsigned char)~mask;
407407
break;
408-
case 2:
408+
case warnTOGGLE:
409409
warnstack.disable[index] ^= mask;
410410
break;
411411
} /* switch */

source/compiler/tests/__pragma.meta

+8-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,15 @@ __pragma.pwn(6) : error 001: expected token: "-identifier-", but found "const"
55
__pragma.pwn(10) : error 001: expected token: "-identifier-", but found "__pragma"
66
__pragma.pwn(36) : warning 234: function is deprecated (symbol "Func") - use OtherFunc() instead
77
__pragma.pwn(40) : warning 234: function is deprecated (symbol "NakedFunc") - use NakedFunc2() instead
8+
__pragma.pwn(43) : warning 207: unknown #pragma
9+
__pragma.pwn(44) : warning 207: unknown #pragma
10+
__pragma.pwn(48) : warning 207: unknown #pragma
11+
__pragma.pwn(62) : warning 200: symbol "long_name2_zzzzzzzz_zzzzzzzzz_z" is truncated to 31 characters
12+
__pragma.pwn(66) : warning 207: unknown #pragma
13+
__pragma.pwn(67) : warning 207: unknown #pragma
14+
__pragma.pwn(68) : warning 207: unknown #pragma
815
__pragma.pwn(33) : warning 203: symbol is never used: "f"
916
__pragma.pwn(29) : warning 204: symbol is assigned a value that is never used: "e"
10-
__pragma.pwn(29 -- 42) : warning 203: symbol is never used: "operator~(Tag:)"
17+
__pragma.pwn(29 -- 70) : warning 203: symbol is never used: "operator~(Tag:)"
1118
"""
1219
}

source/compiler/tests/__pragma.pwn

+29-1
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,33 @@ main()
3737

3838
// NakedFunc() and NakedFunc2() are marked as "naked", so there should be
3939
// no warnings about them having to return a value.
40-
return NakedFunc(), NakedFunc2();
40+
new __pragma("unused") retval = (NakedFunc(), NakedFunc2());
41+
42+
// Make sure the compiler doesn't crash on an empty `__pragma`.
43+
__pragma(""); // warning 207: unknown #pragma
44+
__pragma(" "); // warning 207: unknown #pragma
45+
46+
// `#pragma` warns about extra characters after the option name,
47+
// so `__pragma` should do the same.
48+
__pragma("unused b"); // warning 207: unknown #pragma
49+
// But it shouldn't warn if there are only trailing whitespaces after the name.
50+
__pragma("naked ");
51+
52+
// Warning 200 is going to be temporarily disabled, so the compiler
53+
// shouldn't warn about the first variable having too long name.
54+
// Also the parameter strings contain excess whitespaces, the compiler
55+
// should ignore them.
56+
__pragma("warning push ", "warning disable 200 ");
57+
new
58+
long_name_zzzzzzzzz_zzzzzzzzz_zzzzzzzzz_ __pragma("unused"),
59+
// `__pragma("warning")` takes effect immediately, so the compiler
60+
// should warn that the name of the next variable is too long.
61+
// warning 200: symbol "long_name2_zzzzzzzz_zzzzzzzzz_z" is truncated to 31 characters
62+
__pragma("warning enable 200 ", "unused") long_name2_zzzzzzzz_zzzzzzzzz_zzzzzzzzz_ __pragma("unused");
63+
__pragma("warning pop ");
64+
65+
// Warn if the parameter of "warning disable" is not a number.
66+
__pragma("warning enable "); // warning 207: unknown #pragma
67+
__pragma("warning enable a "); // warning 207: unknown #pragma
68+
__pragma("warning enable - "); // warning 207: unknown #pragma
4169
}

0 commit comments

Comments
 (0)