Unified · Split
| @@ -1230,8 +1230,9 @@ LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path) · 1229 unmodified lines | |||
| 1230 | s->tcc_lib_path = tcc_strdup(path); | 1230 | s->tcc_lib_path = tcc_strdup(path); |
| 1231 | } | 1231 | } |
| 1232 | 1232 | ||
| 1233 | #define WD_ALL 0x0001 /* warning is activated when using -Wall */ | 1233 | #define WD_ALL (1u<<0) /* warning is activated when using -Wall */ |
| 1234 | #define FD_INVERT 0x0002 /* invert value before storing */ | 1234 | #define WD_ERROR (1u<<1) /* can be used with -W[no-]error=X */ |
| 1235 | #define FD_INVERT (1u<<2) /* invert value before storing */ | ||
| 1235 | 1236 | ||
| 1236 | typedef struct FlagDef { | 1237 | typedef struct FlagDef { |
| 1237 | uint16_t offset; | 1238 | uint16_t offset; |
| @@ -1279,6 +1280,49 @@ ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, const char *name) · 41 unmodified lines | |||
| 1279 | return ret; | 1280 | return ret; |
| 1280 | } | 1281 | } |
| 1281 | 1282 | ||
| 1283 | ST_FUNC int set_W_flag(TCCState *s, const FlagDef *flags, const char *optarg) | ||
| 1284 | { | ||
| 1285 | int value, ret; | ||
| 1286 | const FlagDef *p; | ||
| 1287 | const char *r, *sub; | ||
| 1288 | |||
| 1289 | value = 1; | ||
| 1290 | r = optarg; | ||
| 1291 | if (no_flag(&r)) | ||
| 1292 | value = 0; | ||
| 1293 | |||
| 1294 | if ((sub = strchr(r, '=')) != NULL) { | ||
| 1295 | if (strncmp(r, "error", (uintptr_t)(sub - r))) | ||
| 1296 | return -1; | ||
| 1297 | r = ++sub; | ||
| 1298 | if (value) | ||
| 1299 | value = 1 | 2; | ||
| 1300 | } | ||
| 1301 | |||
| 1302 | /* .offset for "all" is 0 */ | ||
| 1303 | for (ret = -1, p = flags; p->name; ++p) { | ||
| 1304 | if (ret) { | ||
| 1305 | if (strcmp(r, p->name)) | ||
| 1306 | continue; | ||
| 1307 | if (sub != NULL && !(p->flags & WD_ERROR)) | ||
| 1308 | break; | ||
| 1309 | } else { | ||
| 1310 | if (0 == (p->flags & WD_ALL)) | ||
| 1311 | continue; | ||
| 1312 | } | ||
| 1313 | if (p->offset) { | ||
| 1314 | *((unsigned char *)s + p->offset) = value; | ||
| 1315 | if (ret) { | ||
| 1316 | ret = 0; | ||
| 1317 | break; | ||
| 1318 | } | ||
| 1319 | } else { | ||
| 1320 | ret = 0; | ||
| 1321 | } | ||
| 1322 | } | ||
| 1323 | return ret; | ||
| 1324 | } | ||
| 1325 | |||
| 1282 | static int strstart(const char *val, const char **str) | 1326 | static int strstart(const char *val, const char **str) |
| 1283 | { | 1327 | { |
| 1284 | const char *p, *q; | 1328 | const char *p, *q; |
| @@ -1469,7 +1513,7 @@ static int tcc_set_linker(TCCState *s, const char *option) · 184 unmodified lines | |||
| 1469 | tcc_error("unsupported linker option '%s'", option); | 1513 | tcc_error("unsupported linker option '%s'", option); |
| 1470 | } | 1514 | } |
| 1471 | 1515 | ||
| 1472 | if (ignoring && s->warn_unsupported) | 1516 | if (ignoring && NEED_WARNING(s, unsupported)) |
| 1473 | tcc_warning("unsupported linker option '%s'", option); | 1517 | tcc_warning("unsupported linker option '%s'", option); |
| 1474 | 1518 | ||
| 1475 | option = skip_linker_arg(&p); | 1519 | option = skip_linker_arg(&p); |
| @@ -1616,12 +1660,13 @@ static const TCCOption tcc_options[] = { · 140 unmodified lines | |||
| 1616 | 1660 | ||
| 1617 | static const FlagDef options_W[] = { | 1661 | static const FlagDef options_W[] = { |
| 1618 | { 0, 0, "all" }, | 1662 | { 0, 0, "all" }, |
| 1619 | { offsetof(TCCState, warn_unsupported), 0, "unsupported" }, | ||
| 1620 | { offsetof(TCCState, warn_write_strings), WD_ALL, "write-strings" }, | ||
| 1621 | { offsetof(TCCState, warn_error), 0, "error" }, | 1663 | { offsetof(TCCState, warn_error), 0, "error" }, |
| 1622 | { offsetof(TCCState, warn_gcc_compat), 0, "gcc-compat" }, | 1664 | { offsetof(TCCState, warn_unsupported), WD_ERROR, "unsupported" }, |
| 1623 | { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL, | 1665 | { offsetof(TCCState, warn_gcc_compat), WD_ERROR, "gcc-compat" }, |
| 1624 | "implicit-function-declaration" }, | 1666 | { offsetof(TCCState, warn_write_strings), WD_ERROR | WD_ALL, |
| 1667 | "write-strings" }, | ||
| 1668 | { offsetof(TCCState, warn_implicit_function_declaration), | ||
| 1669 | WD_ERROR | WD_ALL, "implicit-function-declaration" }, | ||
| 1625 | { 0, 0, NULL } | 1670 | { 0, 0, NULL } |
| 1626 | }; | 1671 | }; |
| 1627 | 1672 | ||
| @@ -1920,7 +1965,7 @@ reparse: · 292 unmodified lines | |||
| 1920 | break; | 1965 | break; |
| 1921 | case TCC_OPTION_W: | 1966 | case TCC_OPTION_W: |
| 1922 | s->warn_none = 0; | 1967 | s->warn_none = 0; |
| 1923 | if (optarg[0] && set_flag(s, options_W, optarg) < 0) | 1968 | if (optarg[0] && set_W_flag(s, options_W, optarg) < 0) |
| 1924 | goto unsupported_option; | 1969 | goto unsupported_option; |
| 1925 | break; | 1970 | break; |
| 1926 | case TCC_OPTION_w: | 1971 | case TCC_OPTION_w: |
| @@ -2007,7 +2052,7 @@ reparse: · 80 unmodified lines | |||
| 2007 | break; | 2052 | break; |
| 2008 | default: | 2053 | default: |
| 2009 | unsupported_option: | 2054 | unsupported_option: |
| 2010 | if (s->warn_unsupported) | 2055 | if (NEED_WARNING(s, unsupported)) |
| 2011 | tcc_warning("unsupported option '%s'", r); | 2056 | tcc_warning("unsupported option '%s'", r); |
| 2012 | break; | 2057 | break; |
| 2013 | } | 2058 | } |
| @@ -267,10 +267,13 @@ Make string constants be of type @code{const char *} instead of @code{char · 266 unmodified lines | |||
| 267 | *}. | 267 | *}. |
| 268 | 268 | ||
| 269 | @item -Werror | 269 | @item -Werror |
| 270 | Abort compilation if warnings are issued. | 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.) | ||
| 271 | 274 | ||
| 272 | @item -Wall | 275 | @item -Wall |
| 273 | Activate all warnings, except @option{-Werror}, @option{-Wunusupported} and | 276 | Activate all warnings, except @option{-Werror}, @option{-Wunsupported} and |
| 274 | @option{-Wwrite-strings}. | 277 | @option{-Wwrite-strings}. |
| 275 | 278 | ||
| 276 | @end table | 279 | @end table |
| @@ -767,13 +767,17 @@ struct TCCState { · 766 unmodified lines | |||
| 767 | unsigned char dollars_in_identifiers; /* allows '$' char in identifiers */ | 767 | unsigned char dollars_in_identifiers; /* allows '$' char in identifiers */ |
| 768 | 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 */ |
| 769 | 769 | ||
| 770 | /* warning switches */ | 770 | /* warning switches; but for first two, W[no-]error=X is supported */ |
| 771 | unsigned char warn_write_strings; | 771 | /* XXX TCC_IS_WARN_OR_ERR(X,Y) used to drive W[[no-]error]=X */ |
| 772 | unsigned char warn_unsupported; | ||
| 773 | unsigned char warn_error; | ||
| 774 | unsigned char warn_none; | 772 | unsigned char warn_none; |
| 775 | unsigned char warn_implicit_function_declaration; | 773 | unsigned char warn_error; |
| 774 | unsigned char warn_unsupported; | ||
| 776 | unsigned char warn_gcc_compat; | 775 | unsigned char warn_gcc_compat; |
| 776 | unsigned char warn_write_strings; | ||
| 777 | unsigned char warn_implicit_function_declaration; | ||
| 778 | #define NEED_WARNING(SELF,SWITCH) \ | ||
| 779 | ((SELF)->warn_ ## SWITCH \ | ||
| 780 | ? (((SELF)->warn_ ## SWITCH & 2) ? (SELF)->warn_error = 1 : 1) : 0) | ||
| 777 | 781 | ||
| 778 | /* compile with debug symbol (and use them if error during execution) */ | 782 | /* compile with debug symbol (and use them if error during execution) */ |
| 779 | unsigned char do_debug; | 783 | unsigned char do_debug; |
| @@ -775,7 +775,7 @@ static void asm_parse_directive(TCCState *s1, int global) · 774 unmodified lines | |||
| 775 | else | 775 | else |
| 776 | pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL)); | 776 | pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL)); |
| 777 | 777 | ||
| 778 | if (s1->warn_unsupported) | 778 | if (NEED_WARNING(s1, unsupported)) |
| 779 | tcc_warning("ignoring .file %s", filename); | 779 | tcc_warning("ignoring .file %s", filename); |
| 780 | 780 | ||
| 781 | next(); | 781 | next(); |
| @@ -793,7 +793,7 @@ static void asm_parse_directive(TCCState *s1, int global) · 11 unmodified lines | |||
| 793 | else | 793 | else |
| 794 | pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL)); | 794 | pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL)); |
| 795 | 795 | ||
| 796 | if (s1->warn_unsupported) | 796 | if (NEED_WARNING(s1, unsupported)) |
| 797 | tcc_warning("ignoring .ident %s", ident); | 797 | tcc_warning("ignoring .ident %s", ident); |
| 798 | 798 | ||
| 799 | next(); | 799 | next(); |
| @@ -810,7 +810,7 @@ static void asm_parse_directive(TCCState *s1, int global) · 10 unmodified lines | |||
| 810 | } | 810 | } |
| 811 | 811 | ||
| 812 | /* XXX .size name,label2-label1 */ | 812 | /* XXX .size name,label2-label1 */ |
| 813 | if (s1->warn_unsupported) | 813 | if (NEED_WARNING(s1, unsupported)) |
| 814 | tcc_warning("ignoring .size %s,*", get_tok_str(tok, NULL)); | 814 | tcc_warning("ignoring .size %s,*", get_tok_str(tok, NULL)); |
| 815 | 815 | ||
| 816 | next(); | 816 | next(); |
| @@ -840,7 +840,7 @@ static void asm_parse_directive(TCCState *s1, int global) · 23 unmodified lines | |||
| 840 | if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) { | 840 | if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) { |
| 841 | sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC; | 841 | sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC; |
| 842 | } | 842 | } |
| 843 | else if (s1->warn_unsupported) | 843 | else if (NEED_WARNING(s1, unsupported)) |
| 844 | tcc_warning("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); | 845 | get_tok_str(sym->v, NULL), sym->type.t, newtype); |
| 846 | 846 | ||
| @@ -4506,7 +4506,7 @@ redo: · 4505 unmodified lines | |||
| 4506 | ad->a.dllimport = 1; | 4506 | ad->a.dllimport = 1; |
| 4507 | break; | 4507 | break; |
| 4508 | default: | 4508 | default: |
| 4509 | if (tcc_state->warn_unsupported) | 4509 | if (NEED_WARNING(tcc_state, unsupported)) |
| 4510 | tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL)); | 4510 | tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL)); |
| 4511 | /* skip parameters */ | 4511 | /* skip parameters */ |
| 4512 | if (tok == '(') { | 4512 | if (tok == '(') { |
| @@ -5915,7 +5915,7 @@ ST_FUNC void unary(void) · 1402 unmodified lines | |||
| 5915 | len = strlen(funcname) + 1; | 5915 | len = strlen(funcname) + 1; |
| 5916 | /* generate char[len] type */ | 5916 | /* generate char[len] type */ |
| 5917 | type.t = VT_BYTE; | 5917 | type.t = VT_BYTE; |
| 5918 | if (tcc_state->warn_write_strings) | 5918 | if (NEED_WARNING(tcc_state, write_strings)) |
| 5919 | type.t |= VT_CONSTANT; | 5919 | type.t |= VT_CONSTANT; |
| 5920 | mk_pointer(&type); | 5920 | mk_pointer(&type); |
| 5921 | type.t |= VT_ARRAY; | 5921 | type.t |= VT_ARRAY; |
| @@ -5942,7 +5942,7 @@ ST_FUNC void unary(void) · 20 unmodified lines | |||
| 5942 | if (tcc_state->char_is_unsigned) | 5942 | if (tcc_state->char_is_unsigned) |
| 5943 | t = VT_BYTE | VT_UNSIGNED; | 5943 | t = VT_BYTE | VT_UNSIGNED; |
| 5944 | str_init: | 5944 | str_init: |
| 5945 | if (tcc_state->warn_write_strings) | 5945 | if (NEED_WARNING(tcc_state, write_strings)) |
| 5946 | t |= VT_CONSTANT; | 5946 | t |= VT_CONSTANT; |
| 5947 | type.t = t; | 5947 | type.t = t; |
| 5948 | mk_pointer(&type); | 5948 | mk_pointer(&type); |
| @@ -6378,9 +6378,9 @@ special_math_val: · 429 unmodified lines | |||
| 6378 | tcc_error("'%s' undeclared", name); | 6378 | tcc_error("'%s' undeclared", name); |
| 6379 | /* for simple function calls, we tolerate undeclared | 6379 | /* for simple function calls, we tolerate undeclared |
| 6380 | external reference to int() function */ | 6380 | external reference to int() function */ |
| 6381 | if (tcc_state->warn_implicit_function_declaration | 6381 | if (NEED_WARNING(tcc_state, implicit_function_declaration) |
| 6382 | #ifdef TCC_TARGET_PE | 6382 | #ifdef TCC_TARGET_PE |
| 6383 | /* people must be warned about using undeclared WINAPI functions | 6383 | /* must warn about using undeclared WINAPI functions |
| 6384 | (which usually start with uppercase letter) */ | 6384 | (which usually start with uppercase letter) */ |
| 6385 | || (name[0] >= 'A' && name[0] <= 'Z') | 6385 | || (name[0] >= 'A' && name[0] <= 'Z') |
| 6386 | #endif | 6386 | #endif |
| @@ -1770,9 +1770,8 @@ static void pragma_parse(TCCState *s1) · 1769 unmodified lines | |||
| 1770 | tcc_free(p); | 1770 | tcc_free(p); |
| 1771 | } | 1771 | } |
| 1772 | 1772 | ||
| 1773 | } else if (s1->warn_unsupported) { | 1773 | } else if (NEED_WARNING(s1, unsupported)) |
| 1774 | tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc)); | 1774 | tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc)); |
| 1775 | } | ||
| 1776 | return; | 1775 | return; |
| 1777 | 1776 | ||
| 1778 | pragma_err: | 1777 | pragma_err: |