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
510 va_end(ap);510 va_end(ap);
511}511}
512 512
513#define ERROR_WARN 0
514#define ERROR_NOABORT 1
515#define ERROR_ERROR 2
516
517PUB_FUNC void tcc_enter_state(TCCState *s1)513PUB_FUNC void tcc_enter_state(TCCState *s1)
518{514{
519 WAIT_SEM();515 WAIT_SEM();
@@ -526,6 +522,10 @@ PUB_FUNC void tcc_exit_state(void) · 6 unmodified lines
526 POST_SEM();522 POST_SEM();
527}523}
528 524
525#define ERROR_WARN 0
526#define ERROR_NOABORT 1
527#define ERROR_ERROR 2
528
529static void error1(int mode, const char *fmt, va_list ap)529static void error1(int mode, const char *fmt, va_list ap)
530{530{
531 char buf[2048];531 char buf[2048];
@@ -537,15 +537,26 @@ static void error1(int mode, const char *fmt, va_list ap) · 5 unmodified lines
537 /* can happen only if called from tcc_malloc(): 'out of memory' */537 /* can happen only if called from tcc_malloc(): 'out of memory' */
538 goto no_file;538 goto no_file;
539 539
540 if (s1 && !s1->error_set_jmp_enabled)540 if (!s1->error_set_jmp_enabled)
541 /* tcc_state just was set by tcc_enter_state() */541 /* tcc_state just was set by tcc_enter_state() */
542 tcc_exit_state();542 tcc_exit_state();
543 543
544 if (mode == ERROR_WARN) {544 if (mode == ERROR_WARN) {
545 if (s1->warn_mask & WARN_DISABLED)545 if (s1->warn_error)
546 return;
547 if (s1->warn_mask & WARN_ERROR_MASK) /* XXX individual ignorance */
548 mode = ERROR_ERROR;546 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;
549 }560 }
550 561
551 f = NULL;562 f = NULL;
@@ -786,7 +797,8 @@ LIBTCCAPI TCCState *tcc_new(void) · 234 unmodified lines
786 s->nocommon = 1;797 s->nocommon = 1;
787 s->dollars_in_identifiers = 1; /*on by default like in gcc/clang*/798 s->dollars_in_identifiers = 1; /*on by default like in gcc/clang*/
788 s->cversion = 199901; /* default unless -std=c11 is supplied */799 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;
790 s->ms_extensions = 1;802 s->ms_extensions = 1;
791 803
792#ifdef CHAR_IS_UNSIGNED804#ifdef CHAR_IS_UNSIGNED
@@ -1230,122 +1242,8 @@ LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path) · 437 unmodified lines
1230 s->tcc_lib_path = tcc_strdup(path);1242 s->tcc_lib_path = tcc_strdup(path);
1231}1243}
1232 1244
1233#define WD_ALL (1u<<0) /* warning is activated when using -Wall */1245/********************************************************/
1234#define WD_ERROR (1u<<1) /* can be used with -W[no-]error=X */1246/* options parser */
1235#define FD_INVERT (1u<<2) /* invert value before storing */
1236
1237typedef struct FlagDef {
1238 uint16_t offset;
1239 uint16_t flags;
1240 const char *name;
1241} FlagDef;
1242
1243static 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
1252ST_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
1283ST_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}
1349 1247
1350static int strstart(const char *val, const char **str)1248static int strstart(const char *val, const char **str)
1351{1249{
@@ -1388,7 +1286,7 @@ static int link_option(const char *str, const char *val, const char **ptr) · 36 unmodified lines
1388 ret = 1;1286 ret = 1;
1389 if (q[0] == '?') {1287 if (q[0] == '?') {
1390 ++q;1288 ++q;
1391 if (no_flag(&p))1289 if (strstart("no-", &p))
1392 ret = -1;1290 ret = -1;
1393 }1291 }
1394 1292
@@ -1536,10 +1434,8 @@ static int tcc_set_linker(TCCState *s, const char *option) · 141 unmodified lines
1536 err:1434 err:
1537 tcc_error("unsupported linker option '%s'", option);1435 tcc_error("unsupported linker option '%s'", option);
1538 }1436 }
1539 1437 if (ignoring)
1540 if (ignoring && NEED_WARNING(s, UNSUPPORTED))1438 tcc_warning_c(warn_unsupported)("unsupported linker option '%s'", option);
1541 tcc_warning("unsupported linker option '%s'", option);
1542
1543 option = skip_linker_arg(&p);1439 option = skip_linker_arg(&p);
1544 }1440 }
1545 return 1;1441 return 1;
@@ -1682,6 +1578,25 @@ static const TCCOption tcc_options[] = { · 136 unmodified lines
1682 { NULL, 0, 0 },1578 { NULL, 0, 0 },
1683};1579};
1684 1580
1581typedef 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
1590static 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
1685static const FlagDef options_f[] = {1600static const FlagDef options_f[] = {
1686 { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },1601 { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
1687 { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },1602 { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
@@ -1701,6 +1616,40 @@ static const FlagDef options_m[] = { · 13 unmodified lines
1701 { 0, 0, NULL }1616 { 0, 0, NULL }
1702};1617};
1703 1618
1619static 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
1704static void args_parser_add_file(TCCState *s, const char* filename, int filetype)1653static void args_parser_add_file(TCCState *s, const char* filename, int filetype)
1705{1654{
1706 struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));1655 struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
@@ -1976,12 +1925,12 @@ reparse: · 269 unmodified lines
1976 }1925 }
1977 break;1926 break;
1978 case TCC_OPTION_W:1927 case TCC_OPTION_W:
1979 s->warn_mask &= ~WARN_DISABLED;1928 s->warn_none = 0;
1980 if (optarg[0] && set_W_flag(s, optarg) < 0)1929 if (optarg[0] && set_flag(s, options_W, optarg) < 0)
1981 goto unsupported_option;1930 goto unsupported_option;
1982 break;1931 break;
1983 case TCC_OPTION_w:1932 case TCC_OPTION_w:
1984 s->warn_mask |= WARN_DISABLED;1933 s->warn_none = 1;
1985 break;1934 break;
1986 case TCC_OPTION_rdynamic:1935 case TCC_OPTION_rdynamic:
1987 s->rdynamic = 1;1936 s->rdynamic = 1;
@@ -2064,8 +2013,7 @@ reparse: · 76 unmodified lines
2064 break;2013 break;
2065 default:2014 default:
2066unsupported_option:2015unsupported_option:
2067 if (NEED_WARNING(s, UNSUPPORTED))2016 tcc_warning_c(warn_unsupported)("unsupported option '%s'", r);
2068 tcc_warning("unsupported option '%s'", r);
2069 break;2017 break;
2070 }2018 }
2071 }2019 }
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
267*}.267*}.
268 268
269@item -Werror269@item -Werror
270Abort compilation if a warning is issued.270Abort compilation if a warning is issued. Can be given an option to enable
271Can be given an option to enable the specified warning271the specified warning and turn it into an error, for example
272and turn it into an error, for example @option{-Werror=unsupported}.272@option{-Werror=unsupported}.
273Enabling general abortion and disabling specifics is not supported.
274Disabling specific abortions again does not disable the according warning.
275 273
276@item -Wall 274@item -Wall
277Activate all warnings, except @option{-Werror}, @option{-Wunsupported} and275Activate some useful warnings.
278@option{-Wwrite-strings}.
279 276
280@end table277@end table
281 278
tcc.c+7−6
@@ -36,7 +36,7 @@ static const char help[] = · 35 unmodified lines
36 " -std=c99 Conform to the ISO 1999 C standard (default).\n"36 " -std=c99 Conform to the ISO 1999 C standard (default).\n"
37 " -std=c11 Conform to the ISO 2011 C standard.\n"37 " -std=c11 Conform to the ISO 2011 C standard.\n"
38 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see tcc -hh)\n"38 " -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"
40 " --version -v show version\n"40 " --version -v show version\n"
41 " -vv show search paths or loaded files\n"41 " -vv show search paths or loaded files\n"
42 " -h -hh show this, show more help\n"42 " -h -hh show this, show more help\n"
@@ -103,10 +103,11 @@ static const char help2[] = · 60 unmodified lines
103 " --param -pedantic -pipe -s -traditional\n"103 " --param -pedantic -pipe -s -traditional\n"
104 "-W[no-]... warnings:\n"104 "-W[no-]... warnings:\n"
105 " all turn on some (*) warnings\n"105 " all turn on some (*) warnings\n"
106 " error[=(X)] error out after first warning (for X)\n"106 " error[=warning] stop after warning (any or specified)\n"
107 " unsupported warn for ignored options, pragmas,.. (X)\n"107 " write-strings strings are const\n"
108 " write-strings strings are const (*,X)\n"108 " unsupported warn about ignored options, pragmas, etc.\n"
109 " implicit-function-declaration warn for missing prototype (*,X)\n"109 " implicit-function-declaration warn for missing prototype (*)\n"
110 " discarded-qualifiers warn when const is dropped (*)\n"
110 "-f[no-]... flags:\n"111 "-f[no-]... flags:\n"
111 " unsigned-char default char is unsigned\n"112 " unsigned-char default char is unsigned\n"
112 " signed-char default char is signed\n"113 " signed-char default char is signed\n"
@@ -317,7 +318,7 @@ redo: · 204 unmodified lines
317 }318 }
318 319
319 if (s->nb_files == 0)320 if (s->nb_files == 0)
320 tcc_error("no input files\n");321 tcc_error("no input files");
321 322
322 if (s->output_type == TCC_OUTPUT_PREPROCESS) {323 if (s->output_type == TCC_OUTPUT_PREPROCESS) {
323 if (s->outfile && 0!=strcmp("-",s->outfile)) {324 if (s->outfile && 0!=strcmp("-",s->outfile)) {
tcc.h+17−27
@@ -737,24 +737,6 @@ struct sym_attr { · 736 unmodified lines
737#endif737#endif
738};738};
739 739
740/* 32-bit bit carrier, split in two halves: lower=warn, upper=error */
741enum 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};
753enum {
754 WARN_ERROR_SHIFT = 16u,
755 WARN_ERROR_MASK = (/*WARN_ALL |*/ WARN_ERROR) << WARN_ERROR_SHIFT
756};
757
758struct TCCState {740struct TCCState {
759 unsigned char verbose; /* if true, display some information during compilation */741 unsigned char verbose; /* if true, display some information during compilation */
760 unsigned char nostdinc; /* if true, no standard headers are added */742 unsigned char nostdinc; /* if true, no standard headers are added */
@@ -785,13 +767,18 @@ struct TCCState { · 24 unmodified lines
785 unsigned char dollars_in_identifiers; /* allows '$' char in identifiers */767 unsigned char dollars_in_identifiers; /* allows '$' char in identifiers */
786 unsigned char ms_bitfields; /* if true, emulate MS algorithm for aligning bitfields */768 unsigned char ms_bitfields; /* if true, emulate MS algorithm for aligning bitfields */
787 769
788 /* NEED_WARNING(SELF,X) used to drive W[[no-]error]=X */770 /* warning switches */
789 uint32_t warn_mask;771 unsigned char warn_none;
790#define NEED_WARNING(SELF,SWITCH) \772 unsigned char warn_all;
791 (((SELF)->warn_mask & \773 unsigned char warn_error;
792 (WARN_ ## SWITCH | (WARN_ ## SWITCH << WARN_ERROR_SHIFT))) \774 unsigned char warn_write_strings;
793 ? (((SELF)->warn_mask & (WARN_ ## SWITCH << WARN_ERROR_SHIFT)) \775 unsigned char warn_unsupported;
794 ? (SELF)->warn_mask |= (WARN_ERROR << WARN_ERROR_SHIFT), 1 : 1) : 0)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() */
795 782
796 /* compile with debug symbol (and use them if error during execution) */783 /* compile with debug symbol (and use them if error during execution) */
797 unsigned char do_debug;784 unsigned char do_debug;
@@ -1890,6 +1877,11 @@ ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename) · 1092 unmodified lines
1890PUB_FUNC void tcc_enter_state(TCCState *s1);1877PUB_FUNC void tcc_enter_state(TCCState *s1);
1891PUB_FUNC void tcc_exit_state(void);1878PUB_FUNC void tcc_exit_state(void);
1892 1879
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
1893/********************************************************/1885/********************************************************/
1894#endif /* _TCC_H */1886#endif /* _TCC_H */
1895 1887
@@ -1903,6 +1895,4 @@ PUB_FUNC void tcc_exit_state(void); · 7 unmodified lines
1903#else1895#else
1904# define TCC_STATE_VAR(sym) s1->sym1896# define TCC_STATE_VAR(sym) s1->sym
1905# define TCC_SET_STATE(fn) (tcc_enter_state(s1),fn)1897# 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. */
1908#endif1898#endif
tccasm.c+5−17
@@ -769,15 +769,11 @@ static void asm_parse_directive(TCCState *s1, int global) · 768 unmodified lines
769 769
770 filename[0] = '\0';770 filename[0] = '\0';
771 next();771 next();
772
773 if (tok == TOK_STR)772 if (tok == TOK_STR)
774 pstrcat(filename, sizeof(filename), tokc.str.data);773 pstrcat(filename, sizeof(filename), tokc.str.data);
775 else774 else
776 pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL));775 pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL));
777 776 tcc_warning_c(warn_unsupported)("ignoring .file %s", filename);
778 if (NEED_WARNING(s1, UNSUPPORTED))
779 tcc_warning("ignoring .file %s", filename);
780
781 next();777 next();
782 }778 }
783 break;779 break;
@@ -787,15 +783,11 @@ static void asm_parse_directive(TCCState *s1, int global) · 3 unmodified lines
787 783
788 ident[0] = '\0';784 ident[0] = '\0';
789 next();785 next();
790
791 if (tok == TOK_STR)786 if (tok == TOK_STR)
792 pstrcat(ident, sizeof(ident), tokc.str.data);787 pstrcat(ident, sizeof(ident), tokc.str.data);
793 else788 else
794 pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL));789 pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL));
795 790 tcc_warning_c(warn_unsupported)("ignoring .ident %s", ident);
796 if (NEED_WARNING(s1, UNSUPPORTED))
797 tcc_warning("ignoring .ident %s", ident);
798
799 next();791 next();
800 }792 }
801 break;793 break;
@@ -808,11 +800,8 @@ static void asm_parse_directive(TCCState *s1, int global) · 6 unmodified lines
808 if (!sym) {800 if (!sym) {
809 tcc_error("label not found: %s", get_tok_str(tok, NULL));801 tcc_error("label not found: %s", get_tok_str(tok, NULL));
810 }802 }
811
812 /* XXX .size name,label2-label1 */803 /* XXX .size name,label2-label1 */
813 if (NEED_WARNING(s1, UNSUPPORTED))804 tcc_warning_c(warn_unsupported)("ignoring .size %s,*", get_tok_str(tok, NULL));
814 tcc_warning("ignoring .size %s,*", get_tok_str(tok, NULL));
815
816 next();805 next();
817 skip(',');806 skip(',');
818 while (tok != TOK_LINEFEED && tok != ';' && tok != CH_EOF) {807 while (tok != TOK_LINEFEED && tok != ';' && tok != CH_EOF) {
@@ -839,9 +828,8 @@ static void asm_parse_directive(TCCState *s1, int global) · 20 unmodified lines
839 828
840 if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {829 if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
841 sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;830 sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
842 }831 } else
843 else if (NEED_WARNING(s1, UNSUPPORTED))832 tcc_warning_c(warn_unsupported)("change type of '%s' from 0x%x to '%s' ignored",
844 tcc_warning("change type of '%s' from 0x%x to '%s' ignored",
845 get_tok_str(sym->v, NULL), sym->type.t, newtype);833 get_tok_str(sym->v, NULL), sym->type.t, newtype);
846 834
847 next();835 next();
tccgen.c+16−30
@@ -4077,7 +4077,7 @@ static void verify_assign_cast(CType *dt) · 4076 unmodified lines
4077 }4077 }
4078 }4078 }
4079 if (qualwarn)4079 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");
4081 break;4081 break;
4082 case VT_BYTE:4082 case VT_BYTE:
4083 case VT_SHORT:4083 case VT_SHORT:
@@ -4355,9 +4355,9 @@ redo: · 271 unmodified lines
4355 skip('(');4355 skip('(');
4356 s = sym_find(tok);4356 s = sym_find(tok);
4357 if (!s) {4357 if (!s) {
4358 tcc_warning("implicit declaration of function '%s'",4358 tcc_warning_c(warn_implicit_function_declaration)(
4359 get_tok_str(tok, &tokc));4359 "implicit declaration of function '%s'", get_tok_str(tok, &tokc));
4360 s = external_global_sym(tok, &func_old_type);4360 s = external_global_sym(tok, &func_old_type);
4361 } else if ((s->type.t & VT_BTYPE) != VT_FUNC)4361 } else if ((s->type.t & VT_BTYPE) != VT_FUNC)
4362 tcc_error("'%s' is not declared as function", get_tok_str(tok, &tokc));4362 tcc_error("'%s' is not declared as function", get_tok_str(tok, &tokc));
4363 ad->cleanup_func = s;4363 ad->cleanup_func = s;
@@ -4506,8 +4506,7 @@ redo: · 142 unmodified lines
4506 ad->a.dllimport = 1;4506 ad->a.dllimport = 1;
4507 break;4507 break;
4508 default:4508 default:
4509 if (NEED_WARNING(tcc_state, UNSUPPORTED))4509 tcc_warning_c(warn_unsupported)("'%s' attribute ignored", get_tok_str(t, NULL));
4510 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
4511 /* skip parameters */4510 /* skip parameters */
4512 if (tok == '(') {4511 if (tok == '(') {
4513 int parenthesis = 0;4512 int parenthesis = 0;
@@ -5909,23 +5908,20 @@ ST_FUNC void unary(void) · 1395 unmodified lines
5909 case TOK___FUNC__:5908 case TOK___FUNC__:
5910 {5909 {
5911 Section *sec;5910 Section *sec;
5912 void *ptr;
5913 int len;5911 int len;
5914 /* special function name identifier */5912 /* special function name identifier */
5915 len = strlen(funcname) + 1;5913 len = strlen(funcname) + 1;
5916 /* generate char[len] type */5914 /* generate char[len] type */
5917 type.t = VT_BYTE;5915 type.t = char_type.t;
5918 if (NEED_WARNING(tcc_state, WRITE_STRINGS))5916 if (tcc_state->warn_write_strings & WARN_ON)
5919 type.t |= VT_CONSTANT;5917 type.t |= VT_CONSTANT;
5920 mk_pointer(&type);5918 mk_pointer(&type);
5921 type.t |= VT_ARRAY;5919 type.t |= VT_ARRAY;
5922 type.ref->c = len;5920 type.ref->c = len;
5923 sec = rodata_section;5921 sec = rodata_section;
5924 vpush_ref(&type, sec, sec->data_offset, len);5922 vpush_ref(&type, sec, sec->data_offset, len);
5925 if (!NODATA_WANTED) {5923 if (!NODATA_WANTED)
5926 ptr = section_ptr_add(sec, len);5924 memcpy(section_ptr_add(sec, len), funcname, len);
5927 memcpy(ptr, funcname, len);
5928 }
5929 next();5925 next();
5930 }5926 }
5931 break;5927 break;
@@ -5938,11 +5934,9 @@ ST_FUNC void unary(void) · 6 unmodified lines
5938 goto str_init;5934 goto str_init;
5939 case TOK_STR:5935 case TOK_STR:
5940 /* string parsing */5936 /* string parsing */
5941 t = VT_BYTE;5937 t = char_type.t;
5942 if (tcc_state->char_is_unsigned)
5943 t = VT_BYTE | VT_UNSIGNED;
5944 str_init:5938 str_init:
5945 if (NEED_WARNING(tcc_state, WRITE_STRINGS))5939 if (tcc_state->warn_write_strings & WARN_ON)
5946 t |= VT_CONSTANT;5940 t |= VT_CONSTANT;
5947 type.t = t;5941 type.t = t;
5948 mk_pointer(&type);5942 mk_pointer(&type);
@@ -6378,14 +6372,8 @@ special_math_val: · 429 unmodified lines
6378 tcc_error("'%s' undeclared", name);6372 tcc_error("'%s' undeclared", name);
6379 /* for simple function calls, we tolerate undeclared6373 /* for simple function calls, we tolerate undeclared
6380 external reference to int() function */6374 external reference to int() function */
6381 if (NEED_WARNING(tcc_state, IMPLICIT_FUNCTION_DECLARATION)6375 tcc_warning_c(warn_implicit_function_declaration)(
6382#ifdef TCC_TARGET_PE6376 "implicit declaration of function '%s'", name);
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);
6389 s = external_global_sym(t, &func_old_type);6377 s = external_global_sym(t, &func_old_type);
6390 }6378 }
6391 6379
@@ -7650,12 +7638,10 @@ again: · 1258 unmodified lines
7650 7638
7651 block_after_label:7639 block_after_label:
7652 vla_restore(cur_scope->vla.loc);7640 vla_restore(cur_scope->vla.loc);
7653 /* we accept this, but it is a mistake */7641 if (tok != '}')
7654 if (tok == '}') {
7655 tcc_warning("deprecated use of label at end of compound statement");
7656 } else {
7657 goto again;7642 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");
7659 7645
7660 } else {7646 } else {
7661 /* expression case */7647 /* expression case */
tccpp.c+4−4
@@ -1435,7 +1435,7 @@ ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep) · 1434 unmodified lines
1435 for(s = *ptop; s != slast; s = s1) {1435 for(s = *ptop; s != slast; s = s1) {
1436 s1 = s->prev;1436 s1 = s->prev;
1437 if (s->r == LABEL_DECLARED) {1437 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));
1439 } else if (s->r == LABEL_FORWARD) {1439 } else if (s->r == LABEL_FORWARD) {
1440 tcc_error("label '%s' used but not defined",1440 tcc_error("label '%s' used but not defined",
1441 get_tok_str(s->v, NULL));1441 get_tok_str(s->v, NULL));
@@ -1770,8 +1770,8 @@ static void pragma_parse(TCCState *s1) · 328 unmodified lines
1770 tcc_free(p);1770 tcc_free(p);
1771 }1771 }
1772 1772
1773 } else if (NEED_WARNING(s1, UNSUPPORTED))1773 } else
1774 tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc));1774 tcc_warning_c(warn_unsupported)("#pragma %s ignored", get_tok_str(tok, &tokc));
1775 return;1775 return;
1776 1776
1777pragma_err:1777pragma_err:
@@ -2293,7 +2293,7 @@ static void parse_string(const char *s, int len) · 515 unmodified lines
2293 if (n < 1)2293 if (n < 1)
2294 tcc_error("empty character constant");2294 tcc_error("empty character constant");
2295 if (n > 1)2295 if (n > 1)
2296 tcc_warning("multi-character character constant");2296 tcc_warning_c(warn_all)("multi-character character constant");
2297 for (c = i = 0; i < n; ++i) {2297 for (c = i = 0; i < n; ++i) {
2298 if (is_long)2298 if (is_long)
2299 c = ((nwchar_t *)tokcstr.data)[i];2299 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
399void v() {}399void v() {}
400int f() { return v(); }400int f() { return v(); }
401 401
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
413void func()
414{
415 char *ccp = "123";
416 fink();
417}
418__attribute__((stuff)) int fink() {return 0;}
402#endif419#endif
tests/tests2/60_errors_and_warnings.expect+14−0
@@ -189,3 +189,17 @@ bar : 3 ; 3 · 188 unmodified lines
189 189
190[test_cast_from_void]190[test_cast_from_void]
19160_errors_and_warnings.c:400: error: cannot convert 'void' to 'int'19160_errors_and_warnings.c:400: error: cannot convert 'void' to 'int'
192
193[test_switch_W1]
19460_errors_and_warnings.c:416: warning: implicit declaration of function 'fink'
195
196[test_switch_W2]
19760_errors_and_warnings.c:407: warning: unsupported option '-Wstuff'
19860_errors_and_warnings.c:418: warning: 'stuff' attribute ignored
199
200[test_switch_W3]
20160_errors_and_warnings.c:415: error: assignment discards qualifiers from pointer target type
202
203[test_switch_W4]
20460_errors_and_warnings.c:416: warning: implicit declaration of function 'fink'
20560_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