History

-W[no-]error...: features by shrinkage

136 insertions(+), 226 deletions(-), less 90 lines (except tests) only one set_flag() function required * can now turn off specific errors: -Werror -Wno-error=option * new interface: tcc_warning_c(warn_option)("format", args...); * new warning: -Wdiscarded-qualifiers (on by default) * new variable 'warn_all' for conditional warnings with -Wall see also the tests

grischka committed 5 years ago

Commit 4b2c6cf1 parent 931a1469 files · +167 −226Browse files

Unified · Split

9 files
  1. libtcc.c +83 −135
  2. tcc-doc.texi +4 −7
  3. tcc.c +7 −6
  4. tcc.h +17 −27
  5. tccasm.c +5 −17
  6. tccgen.c +16 −30
  7. tccpp.c +4 −4
  8. tests/tests2/60_errors_and_warnings.c +17 −0
  9. tests/tests2/60_errors_and_warnings.expect +14 −0
libtcc.c+83−135
@@ -510,10 +510,6 @@ static void strcat_printf(char *buf, int buf_size, const char *fmt, ...) · 509 unmodified lines
510510 va_end(ap);
511511 }
512512
513−#define ERROR_WARN 0
514−#define ERROR_NOABORT 1
515−#define ERROR_ERROR 2
516−
517513 PUB_FUNC void tcc_enter_state(TCCState *s1)
518514 {
519515 WAIT_SEM();
@@ -526,6 +522,10 @@ PUB_FUNC void tcc_exit_state(void) · 6 unmodified lines
526522 POST_SEM();
527523 }
528524
525+#define ERROR_WARN 0
526+#define ERROR_NOABORT 1
527+#define ERROR_ERROR 2
528+
529529 static void error1(int mode, const char *fmt, va_list ap)
530530 {
531531 char buf[2048];
@@ -537,15 +537,26 @@ static void error1(int mode, const char *fmt, va_list ap) · 5 unmodified lines
537537 /* can happen only if called from tcc_malloc(): 'out of memory' */
538538 goto no_file;
539539
540− if (s1 && !s1->error_set_jmp_enabled)
540+ if (!s1->error_set_jmp_enabled)
541541 /* tcc_state just was set by tcc_enter_state() */
542542 tcc_exit_state();
543543
544544 if (mode == ERROR_WARN) {
545− if (s1->warn_mask & WARN_DISABLED)
546− return;
547− if (s1->warn_mask & WARN_ERROR_MASK) /* XXX individual ignorance */
545+ if (s1->warn_error)
548546 mode = ERROR_ERROR;
547+ if (s1->warn_num) {
548+ /* handle tcc_warning_c(warn_option)(fmt, ...) */
549+ int wopt = *(&s1->warn_none + s1->warn_num);
550+ s1->warn_num = 0;
551+ if (0 == (wopt & WARN_ON))
552+ return;
553+ if (wopt & WARN_ERR)
554+ mode = ERROR_ERROR;
555+ if (wopt & WARN_NOE)
556+ mode = ERROR_WARN;
557+ }
558+ if (s1->warn_none)
559+ return;
549560 }
550561
551562 f = NULL;
@@ -786,7 +797,8 @@ LIBTCCAPI TCCState *tcc_new(void) · 234 unmodified lines
786797 s->nocommon = 1;
787798 s->dollars_in_identifiers = 1; /*on by default like in gcc/clang*/
788799 s->cversion = 199901; /* default unless -std=c11 is supplied */
789− s->warn_mask |= WARN_IMPLICIT_FUNCTION_DECLARATION;
800+ s->warn_implicit_function_declaration = 1;
801+ s->warn_discarded_qualifiers = 1;
790802 s->ms_extensions = 1;
791803
792804 #ifdef CHAR_IS_UNSIGNED
@@ -1230,122 +1242,8 @@ LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path) · 437 unmodified lines
12301242 s->tcc_lib_path = tcc_strdup(path);
12311243 }
12321244
1233−#define WD_ALL (1u<<0) /* warning is activated when using -Wall */
1234−#define WD_ERROR (1u<<1) /* can be used with -W[no-]error=X */
1235−#define FD_INVERT (1u<<2) /* invert value before storing */
1236−
1237−typedef struct FlagDef {
1238− uint16_t offset;
1239− uint16_t flags;
1240− const char *name;
1241−} FlagDef;
1242−
1243−static int no_flag(const char **pp)
1244−{
1245− const char *p = *pp;
1246− if (*p != 'n' || *++p != 'o' || *++p != '-')
1247− return 0;
1248− *pp = p + 1;
1249− return 1;
1250−}
1251−
1252−ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, const char *name)
1253−{
1254− int value, ret;
1255− const FlagDef *p;
1256− const char *r;
1257−
1258− value = 1;
1259− r = name;
1260− if (no_flag(&r))
1261− value = 0;
1262−
1263− for (ret = -1, p = flags; p->name; ++p) {
1264− if (ret) {
1265− if (strcmp(r, p->name))
1266− continue;
1267− } else {
1268− if (0 == (p->flags & WD_ALL))
1269− continue;
1270− }
1271− if (p->offset) {
1272− *((unsigned char *)s + p->offset) =
1273− p->flags & FD_INVERT ? !value : value;
1274− if (ret)
1275− return 0;
1276− } else {
1277− ret = 0;
1278− }
1279− }
1280− return ret;
1281−}
1282−
1283−ST_FUNC int set_W_flag(TCCState *s, const char *optarg)
1284−{
1285− static struct a_W_flag{
1286− uint32_t wbit;
1287− uint32_t flags;
1288− char const *name;
1289− } const opts[] = {
1290− {WARN_ALL, 0, "all"},
1291− {WARN_ERROR | (WARN_ERROR << WARN_ERROR_SHIFT), 0, "error"},
1292− {WARN_UNSUPPORTED, WD_ERROR, "unsupported"},
1293− {WARN_GCC_COMPAT, WD_ERROR, "gcc-compat"},
1294− {WARN_WRITE_STRINGS, WD_ERROR | WD_ALL, "write-strings"},
1295− {WARN_IMPLICIT_FUNCTION_DECLARATION, WD_ERROR | WD_ALL,
1296− "implicit-function-declaration"}
1297− }, *p;
1298−
1299− int ret;
1300− unsigned char mode;
1301− const char *r, *sub;
1302−
1303− mode = 1;
1304− r = optarg;
1305− if (no_flag(&r))
1306− mode = 0;
1307−
1308− if ((sub = strchr(r, '=')) != NULL) {
1309− if (strncmp(r, "error", (uintptr_t)(sub - r)))
1310− return -1;
1311− r = ++sub;
1312− mode |= 2;
1313− }
1314−
1315− for (ret = -1, p = opts; p < &opts[countof(opts)]; ++p) {
1316− if (ret) {
1317− if (strcmp(r, p->name))
1318− continue;
1319− if ((mode & 2) && !(p->flags & WD_ERROR))
1320− break;
1321− } else {
1322− if (0 == (p->flags & WD_ALL))
1323− continue;
1324− }
1325−
1326− if (p->wbit == WARN_ALL) {
1327− /* Start a loop over all the rest */
1328− ret = 0;
1329− continue;
1330− }
1331−
1332− if (mode & 1) {
1333− s->warn_mask |= p->wbit;
1334− if (mode & 2)
1335− s->warn_mask |= p->wbit << WARN_ERROR_SHIFT;
1336− } else {
1337− s->warn_mask &= ~(p->wbit << ((mode & 2) ? WARN_ERROR_SHIFT : 0));
1338− }
1339−
1340− /* Done if not in "all" mode */
1341− if (ret) {
1342− ret = 0;
1343− break;
1344− }
1345− }
1346−
1347− return ret;
1348−}
1245+/********************************************************/
1246+/* options parser */
13491247
13501248 static int strstart(const char *val, const char **str)
13511249 {
@@ -1388,7 +1286,7 @@ static int link_option(const char *str, const char *val, const char **ptr) · 36 unmodified lines
13881286 ret = 1;
13891287 if (q[0] == '?') {
13901288 ++q;
1391− if (no_flag(&p))
1289+ if (strstart("no-", &p))
13921290 ret = -1;
13931291 }
13941292
@@ -1536,10 +1434,8 @@ static int tcc_set_linker(TCCState *s, const char *option) · 141 unmodified lines
15361434 err:
15371435 tcc_error("unsupported linker option '%s'", option);
15381436 }
1539−
1540− if (ignoring && NEED_WARNING(s, UNSUPPORTED))
1541− tcc_warning("unsupported linker option '%s'", option);
1542−
1437+ if (ignoring)
1438+ tcc_warning_c(warn_unsupported)("unsupported linker option '%s'", option);
15431439 option = skip_linker_arg(&p);
15441440 }
15451441 return 1;
@@ -1682,6 +1578,25 @@ static const TCCOption tcc_options[] = { · 136 unmodified lines
16821578 { NULL, 0, 0 },
16831579 };
16841580
1581+typedef struct FlagDef {
1582+ uint16_t offset;
1583+ uint16_t flags;
1584+ const char *name;
1585+} FlagDef;
1586+
1587+#define WD_ALL 0x0001 /* warning is activated when using -Wall */
1588+#define FD_INVERT 0x0002 /* invert value before storing */
1589+
1590+static const FlagDef options_W[] = {
1591+ { offsetof(TCCState, warn_all), WD_ALL, "all" },
1592+ { offsetof(TCCState, warn_error), 0, "error" },
1593+ { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
1594+ { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
1595+ { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL, "implicit-function-declaration" },
1596+ { offsetof(TCCState, warn_discarded_qualifiers), WD_ALL, "discarded-qualifiers" },
1597+ { 0, 0, NULL }
1598+};
1599+
16851600 static const FlagDef options_f[] = {
16861601 { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
16871602 { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
@@ -1701,6 +1616,40 @@ static const FlagDef options_m[] = { · 13 unmodified lines
17011616 { 0, 0, NULL }
17021617 };
17031618
1619+static int set_flag(TCCState *s, const FlagDef *flags, const char *name)
1620+{
1621+ int value, mask, ret;
1622+ const FlagDef *p;
1623+ const char *r;
1624+ unsigned char *f;
1625+
1626+ r = name, value = !strstart("no-", &r), mask = 0;
1627+
1628+ /* when called with options_W, look for -W[no-]error=<option> */
1629+ if ((flags->flags & WD_ALL) && strstart("error=", &r))
1630+ value = value ? WARN_ON|WARN_ERR : WARN_NOE, mask = WARN_ON;
1631+
1632+ for (ret = -1, p = flags; p->name; ++p) {
1633+ if (ret) {
1634+ if (strcmp(r, p->name))
1635+ continue;
1636+ } else {
1637+ if (0 == (p->flags & WD_ALL))
1638+ continue;
1639+ }
1640+
1641+ f = (unsigned char *)s + p->offset;
1642+ *f = (*f & mask) | (value ^ !!(p->flags & FD_INVERT));
1643+
1644+ if (ret) {
1645+ ret = 0;
1646+ if (strcmp(r, "all"))
1647+ break;
1648+ }
1649+ }
1650+ return ret;
1651+}
1652+
17041653 static void args_parser_add_file(TCCState *s, const char* filename, int filetype)
17051654 {
17061655 struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
@@ -1976,12 +1925,12 @@ reparse: · 269 unmodified lines
19761925 }
19771926 break;
19781927 case TCC_OPTION_W:
1979− s->warn_mask &= ~WARN_DISABLED;
1980− if (optarg[0] && set_W_flag(s, optarg) < 0)
1928+ s->warn_none = 0;
1929+ if (optarg[0] && set_flag(s, options_W, optarg) < 0)
19811930 goto unsupported_option;
19821931 break;
19831932 case TCC_OPTION_w:
1984− s->warn_mask |= WARN_DISABLED;
1933+ s->warn_none = 1;
19851934 break;
19861935 case TCC_OPTION_rdynamic:
19871936 s->rdynamic = 1;
@@ -2064,8 +2013,7 @@ reparse: · 76 unmodified lines
20642013 break;
20652014 default:
20662015 unsupported_option:
2067− if (NEED_WARNING(s, UNSUPPORTED))
2068− tcc_warning("unsupported option '%s'", r);
2016+ tcc_warning_c(warn_unsupported)("unsupported option '%s'", r);
20692017 break;
20702018 }
20712019 }
tcc-doc.texi+4−7
@@ -267,15 +267,12 @@ Make string constants be of type @code{const char *} instead of @code{char · 266 unmodified lines
267267 *}.
268268
269269 @item -Werror
270−Abort compilation if a warning is issued.
271−Can be given an option to enable the specified warning
272−and turn it into an error, for example @option{-Werror=unsupported}.
273−Enabling general abortion and disabling specifics is not supported.
274−Disabling specific abortions again does not disable the according warning.
270+Abort compilation if a warning is issued. Can be given an option to enable
271+the specified warning and turn it into an error, for example
272+@option{-Werror=unsupported}.
275273
276274 @item -Wall
277−Activate all warnings, except @option{-Werror}, @option{-Wunsupported} and
278−@option{-Wwrite-strings}.
275+Activate some useful warnings.
279276
280277 @end table
281278
tcc.c+7−6
@@ -36,7 +36,7 @@ static const char help[] = · 35 unmodified lines
3636 " -std=c99 Conform to the ISO 1999 C standard (default).\n"
3737 " -std=c11 Conform to the ISO 2011 C standard.\n"
3838 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see tcc -hh)\n"
39− " -w disable all warnings and their consequences\n"
39+ " -w disable all warnings\n"
4040 " --version -v show version\n"
4141 " -vv show search paths or loaded files\n"
4242 " -h -hh show this, show more help\n"
@@ -103,10 +103,11 @@ static const char help2[] = · 60 unmodified lines
103103 " --param -pedantic -pipe -s -traditional\n"
104104 "-W[no-]... warnings:\n"
105105 " all turn on some (*) warnings\n"
106− " error[=(X)] error out after first warning (for X)\n"
107− " unsupported warn for ignored options, pragmas,.. (X)\n"
108− " write-strings strings are const (*,X)\n"
109− " implicit-function-declaration warn for missing prototype (*,X)\n"
106+ " error[=warning] stop after warning (any or specified)\n"
107+ " write-strings strings are const\n"
108+ " unsupported warn about ignored options, pragmas, etc.\n"
109+ " implicit-function-declaration warn for missing prototype (*)\n"
110+ " discarded-qualifiers warn when const is dropped (*)\n"
110111 "-f[no-]... flags:\n"
111112 " unsigned-char default char is unsigned\n"
112113 " signed-char default char is signed\n"
@@ -317,7 +318,7 @@ redo: · 204 unmodified lines
317318 }
318319
319320 if (s->nb_files == 0)
320− tcc_error("no input files\n");
321+ tcc_error("no input files");
321322
322323 if (s->output_type == TCC_OUTPUT_PREPROCESS) {
323324 if (s->outfile && 0!=strcmp("-",s->outfile)) {
tcc.h+17−27
@@ -737,24 +737,6 @@ struct sym_attr { · 736 unmodified lines
737737 #endif
738738 };
739739
740−/* 32-bit bit carrier, split in two halves: lower=warn, upper=error */
741−enum warn_option {
742− WARN_NONE,
743− WARN_UNSUPPORTED = 1u<<0,
744− WARN_GCC_COMPAT = 1u<<1,
745− WARN_WRITE_STRINGS = 1u<<2,
746− WARN_IMPLICIT_FUNCTION_DECLARATION = 1u<<3,
747− /* _ERROR is in lower as "max", there is no warning for it */
748− WARN_ERROR = 1u<<4,
749− WARN_ALL = WARN_ERROR - 1,
750− /* Is neither in lower nor upper: disables warnings and errors (-w) */
751− WARN_DISABLED = WARN_ERROR << 1
752−};
753−enum {
754− WARN_ERROR_SHIFT = 16u,
755− WARN_ERROR_MASK = (/*WARN_ALL |*/ WARN_ERROR) << WARN_ERROR_SHIFT
756−};
757−
758740 struct TCCState {
759741 unsigned char verbose; /* if true, display some information during compilation */
760742 unsigned char nostdinc; /* if true, no standard headers are added */
@@ -785,13 +767,18 @@ struct TCCState { · 24 unmodified lines
785767 unsigned char dollars_in_identifiers; /* allows '$' char in identifiers */
786768 unsigned char ms_bitfields; /* if true, emulate MS algorithm for aligning bitfields */
787769
788− /* NEED_WARNING(SELF,X) used to drive W[[no-]error]=X */
789− uint32_t warn_mask;
790−#define NEED_WARNING(SELF,SWITCH) \
791− (((SELF)->warn_mask & \
792− (WARN_ ## SWITCH | (WARN_ ## SWITCH << WARN_ERROR_SHIFT))) \
793− ? (((SELF)->warn_mask & (WARN_ ## SWITCH << WARN_ERROR_SHIFT)) \
794− ? (SELF)->warn_mask |= (WARN_ERROR << WARN_ERROR_SHIFT), 1 : 1) : 0)
770+ /* warning switches */
771+ unsigned char warn_none;
772+ unsigned char warn_all;
773+ unsigned char warn_error;
774+ unsigned char warn_write_strings;
775+ unsigned char warn_unsupported;
776+ unsigned char warn_implicit_function_declaration;
777+ unsigned char warn_discarded_qualifiers;
778+ #define WARN_ON 1 /* warning is on (-Woption) */
779+ #define WARN_ERR 2 /* warning is an error (-Werror=option) */
780+ #define WARN_NOE 4 /* warning is not an error (-Wno-error=option) */
781+ unsigned char warn_num; /* temp var for tcc_warning_c() */
795782
796783 /* compile with debug symbol (and use them if error during execution) */
797784 unsigned char do_debug;
@@ -1890,6 +1877,11 @@ ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename) · 1092 unmodified lines
18901877 PUB_FUNC void tcc_enter_state(TCCState *s1);
18911878 PUB_FUNC void tcc_exit_state(void);
18921879
1880+/* conditional warning depending on switch */
1881+#define tcc_warning_c(sw) TCC_SET_STATE((\
1882+ tcc_state->warn_num = offsetof(TCCState, sw) \
1883+ - offsetof(TCCState, warn_none), _tcc_warning))
1884+
18931885 /********************************************************/
18941886 #endif /* _TCC_H */
18951887
@@ -1903,6 +1895,4 @@ PUB_FUNC void tcc_exit_state(void); · 7 unmodified lines
19031895 #else
19041896 # define TCC_STATE_VAR(sym) s1->sym
19051897 # define TCC_SET_STATE(fn) (tcc_enter_state(s1),fn)
1906−/* actually we could avoid the tcc_enter_state(s1) hack by using
1907− __VA_ARGS__ except that some compiler doesn't support it. */
19081898 #endif
tccasm.c+5−17
@@ -769,15 +769,11 @@ static void asm_parse_directive(TCCState *s1, int global) · 768 unmodified lines
769769
770770 filename[0] = '\0';
771771 next();
772−
773772 if (tok == TOK_STR)
774773 pstrcat(filename, sizeof(filename), tokc.str.data);
775774 else
776775 pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL));
777−
778− if (NEED_WARNING(s1, UNSUPPORTED))
779− tcc_warning("ignoring .file %s", filename);
780−
776+ tcc_warning_c(warn_unsupported)("ignoring .file %s", filename);
781777 next();
782778 }
783779 break;
@@ -787,15 +783,11 @@ static void asm_parse_directive(TCCState *s1, int global) · 3 unmodified lines
787783
788784 ident[0] = '\0';
789785 next();
790−
791786 if (tok == TOK_STR)
792787 pstrcat(ident, sizeof(ident), tokc.str.data);
793788 else
794789 pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL));
795−
796− if (NEED_WARNING(s1, UNSUPPORTED))
797− tcc_warning("ignoring .ident %s", ident);
798−
790+ tcc_warning_c(warn_unsupported)("ignoring .ident %s", ident);
799791 next();
800792 }
801793 break;
@@ -808,11 +800,8 @@ static void asm_parse_directive(TCCState *s1, int global) · 6 unmodified lines
808800 if (!sym) {
809801 tcc_error("label not found: %s", get_tok_str(tok, NULL));
810802 }
811−
812803 /* XXX .size name,label2-label1 */
813− if (NEED_WARNING(s1, UNSUPPORTED))
814− tcc_warning("ignoring .size %s,*", get_tok_str(tok, NULL));
815−
804+ tcc_warning_c(warn_unsupported)("ignoring .size %s,*", get_tok_str(tok, NULL));
816805 next();
817806 skip(',');
818807 while (tok != TOK_LINEFEED && tok != ';' && tok != CH_EOF) {
@@ -839,9 +828,8 @@ static void asm_parse_directive(TCCState *s1, int global) · 20 unmodified lines
839828
840829 if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
841830 sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
842− }
843− else if (NEED_WARNING(s1, UNSUPPORTED))
844− tcc_warning("change type of '%s' from 0x%x to '%s' ignored",
831+ } else
832+ tcc_warning_c(warn_unsupported)("change type of '%s' from 0x%x to '%s' ignored",
845833 get_tok_str(sym->v, NULL), sym->type.t, newtype);
846834
847835 next();
tccgen.c+16−30
@@ -4077,7 +4077,7 @@ static void verify_assign_cast(CType *dt) · 4076 unmodified lines
40774077 }
40784078 }
40794079 if (qualwarn)
4080− tcc_warning("assignment discards qualifiers from pointer target type");
4080+ tcc_warning_c(warn_discarded_qualifiers)("assignment discards qualifiers from pointer target type");
40814081 break;
40824082 case VT_BYTE:
40834083 case VT_SHORT:
@@ -4355,9 +4355,9 @@ redo: · 271 unmodified lines
43554355 skip('(');
43564356 s = sym_find(tok);
43574357 if (!s) {
4358− tcc_warning("implicit declaration of function '%s'",
4359− get_tok_str(tok, &tokc));
4360− s = external_global_sym(tok, &func_old_type);
4358+ tcc_warning_c(warn_implicit_function_declaration)(
4359+ "implicit declaration of function '%s'", get_tok_str(tok, &tokc));
4360+ s = external_global_sym(tok, &func_old_type);
43614361 } else if ((s->type.t & VT_BTYPE) != VT_FUNC)
43624362 tcc_error("'%s' is not declared as function", get_tok_str(tok, &tokc));
43634363 ad->cleanup_func = s;
@@ -4506,8 +4506,7 @@ redo: · 142 unmodified lines
45064506 ad->a.dllimport = 1;
45074507 break;
45084508 default:
4509− if (NEED_WARNING(tcc_state, UNSUPPORTED))
4510− tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
4509+ tcc_warning_c(warn_unsupported)("'%s' attribute ignored", get_tok_str(t, NULL));
45114510 /* skip parameters */
45124511 if (tok == '(') {
45134512 int parenthesis = 0;
@@ -5909,23 +5908,20 @@ ST_FUNC void unary(void) · 1395 unmodified lines
59095908 case TOK___FUNC__:
59105909 {
59115910 Section *sec;
5912− void *ptr;
59135911 int len;
59145912 /* special function name identifier */
59155913 len = strlen(funcname) + 1;
59165914 /* generate char[len] type */
5917− type.t = VT_BYTE;
5918− if (NEED_WARNING(tcc_state, WRITE_STRINGS))
5915+ type.t = char_type.t;
5916+ if (tcc_state->warn_write_strings & WARN_ON)
59195917 type.t |= VT_CONSTANT;
59205918 mk_pointer(&type);
59215919 type.t |= VT_ARRAY;
59225920 type.ref->c = len;
59235921 sec = rodata_section;
59245922 vpush_ref(&type, sec, sec->data_offset, len);
5925− if (!NODATA_WANTED) {
5926− ptr = section_ptr_add(sec, len);
5927− memcpy(ptr, funcname, len);
5928− }
5923+ if (!NODATA_WANTED)
5924+ memcpy(section_ptr_add(sec, len), funcname, len);
59295925 next();
59305926 }
59315927 break;
@@ -5938,11 +5934,9 @@ ST_FUNC void unary(void) · 6 unmodified lines
59385934 goto str_init;
59395935 case TOK_STR:
59405936 /* string parsing */
5941− t = VT_BYTE;
5942− if (tcc_state->char_is_unsigned)
5943− t = VT_BYTE | VT_UNSIGNED;
5937+ t = char_type.t;
59445938 str_init:
5945− if (NEED_WARNING(tcc_state, WRITE_STRINGS))
5939+ if (tcc_state->warn_write_strings & WARN_ON)
59465940 t |= VT_CONSTANT;
59475941 type.t = t;
59485942 mk_pointer(&type);
@@ -6378,14 +6372,8 @@ special_math_val: · 429 unmodified lines
63786372 tcc_error("'%s' undeclared", name);
63796373 /* for simple function calls, we tolerate undeclared
63806374 external reference to int() function */
6381− if (NEED_WARNING(tcc_state, IMPLICIT_FUNCTION_DECLARATION)
6382−#ifdef TCC_TARGET_PE
6383− /* must warn about using undeclared WINAPI functions
6384− (which usually start with uppercase letter) */
6385− || (name[0] >= 'A' && name[0] <= 'Z')
6386−#endif
6387− )
6388− tcc_warning("implicit declaration of function '%s'", name);
6375+ tcc_warning_c(warn_implicit_function_declaration)(
6376+ "implicit declaration of function '%s'", name);
63896377 s = external_global_sym(t, &func_old_type);
63906378 }
63916379
@@ -7650,12 +7638,10 @@ again: · 1258 unmodified lines
76507638
76517639 block_after_label:
76527640 vla_restore(cur_scope->vla.loc);
7653− /* we accept this, but it is a mistake */
7654− if (tok == '}') {
7655− tcc_warning("deprecated use of label at end of compound statement");
7656− } else {
7641+ if (tok != '}')
76577642 goto again;
7658− }
7643+ /* we accept this, but it is a mistake */
7644+ tcc_warning_c(warn_all)("deprecated use of label at end of compound statement");
76597645
76607646 } else {
76617647 /* expression case */
tccpp.c+4−4
@@ -1435,7 +1435,7 @@ ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep) · 1434 unmodified lines
14351435 for(s = *ptop; s != slast; s = s1) {
14361436 s1 = s->prev;
14371437 if (s->r == LABEL_DECLARED) {
1438− tcc_warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
1438+ tcc_warning_c(warn_all)("label '%s' declared but not used", get_tok_str(s->v, NULL));
14391439 } else if (s->r == LABEL_FORWARD) {
14401440 tcc_error("label '%s' used but not defined",
14411441 get_tok_str(s->v, NULL));
@@ -1770,8 +1770,8 @@ static void pragma_parse(TCCState *s1) · 328 unmodified lines
17701770 tcc_free(p);
17711771 }
17721772
1773− } else if (NEED_WARNING(s1, UNSUPPORTED))
1774− tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc));
1773+ } else
1774+ tcc_warning_c(warn_unsupported)("#pragma %s ignored", get_tok_str(tok, &tokc));
17751775 return;
17761776
17771777 pragma_err:
@@ -2293,7 +2293,7 @@ static void parse_string(const char *s, int len) · 515 unmodified lines
22932293 if (n < 1)
22942294 tcc_error("empty character constant");
22952295 if (n > 1)
2296− tcc_warning("multi-character character constant");
2296+ tcc_warning_c(warn_all)("multi-character character constant");
22972297 for (c = i = 0; i < n; ++i) {
22982298 if (is_long)
22992299 c = ((nwchar_t *)tokcstr.data)[i];
tests/tests2/60_errors_and_warnings.c+17−0
@@ -399,4 +399,21 @@ int array[] = { 1, 2, 3 }; · 398 unmodified lines
399399 void v() {}
400400 int f() { return v(); }
401401
402+#elif defined test_switch_W1 || defined test_switch_W2 \
403+ || defined test_switch_W3 || defined test_switch_W4
404+#if defined test_switch_W1
405+#pragma comment(option, "-Wall")
406+#elif defined test_switch_W2
407+#pragma comment(option, "-Wunsupported -Wno-implicit-function-declaration -Wstuff")
408+#elif defined test_switch_W3
409+#pragma comment(option, "-Wwrite-strings -Werror=discarded-qualifiers")
410+#elif defined test_switch_W4
411+#pragma comment(option, "-Wunsupported -Wno-error=implicit-function-declaration -Werror")
412+#endif
413+void func()
414+{
415+ char *ccp = "123";
416+ fink();
417+}
418+__attribute__((stuff)) int fink() {return 0;}
402419 #endif
tests/tests2/60_errors_and_warnings.expect+14−0
@@ -189,3 +189,17 @@ bar : 3 ; 3 · 188 unmodified lines
189189
190190 [test_cast_from_void]
191191 60_errors_and_warnings.c:400: error: cannot convert 'void' to 'int'
192+
193+[test_switch_W1]
194+60_errors_and_warnings.c:416: warning: implicit declaration of function 'fink'
195+
196+[test_switch_W2]
197+60_errors_and_warnings.c:407: warning: unsupported option '-Wstuff'
198+60_errors_and_warnings.c:418: warning: 'stuff' attribute ignored
199+
200+[test_switch_W3]
201+60_errors_and_warnings.c:415: error: assignment discards qualifiers from pointer target type
202+
203+[test_switch_W4]
204+60_errors_and_warnings.c:416: warning: implicit declaration of function 'fink'
205+60_errors_and_warnings.c:418: error: 'stuff' attribute ignored

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t