Add -W[no-]error=OPTION specific abortions
This commit is contained in:
parent
eadcee6501
commit
a7a13896b3
6 changed files with 79 additions and 28 deletions
65
libtcc.c
65
libtcc.c
|
@ -1230,8 +1230,9 @@ LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path)
|
|||
s->tcc_lib_path = tcc_strdup(path);
|
||||
}
|
||||
|
||||
#define WD_ALL 0x0001 /* warning is activated when using -Wall */
|
||||
#define FD_INVERT 0x0002 /* invert value before storing */
|
||||
#define WD_ALL (1u<<0) /* warning is activated when using -Wall */
|
||||
#define WD_ERROR (1u<<1) /* can be used with -W[no-]error=X */
|
||||
#define FD_INVERT (1u<<2) /* invert value before storing */
|
||||
|
||||
typedef struct FlagDef {
|
||||
uint16_t offset;
|
||||
|
@ -1279,6 +1280,49 @@ ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, const char *name)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ST_FUNC int set_W_flag(TCCState *s, const FlagDef *flags, const char *optarg)
|
||||
{
|
||||
int value, ret;
|
||||
const FlagDef *p;
|
||||
const char *r, *sub;
|
||||
|
||||
value = 1;
|
||||
r = optarg;
|
||||
if (no_flag(&r))
|
||||
value = 0;
|
||||
|
||||
if ((sub = strchr(r, '=')) != NULL) {
|
||||
if (strncmp(r, "error", (uintptr_t)(sub - r)))
|
||||
return -1;
|
||||
r = ++sub;
|
||||
if (value)
|
||||
value = 1 | 2;
|
||||
}
|
||||
|
||||
/* .offset for "all" is 0 */
|
||||
for (ret = -1, p = flags; p->name; ++p) {
|
||||
if (ret) {
|
||||
if (strcmp(r, p->name))
|
||||
continue;
|
||||
if (sub != NULL && !(p->flags & WD_ERROR))
|
||||
break;
|
||||
} else {
|
||||
if (0 == (p->flags & WD_ALL))
|
||||
continue;
|
||||
}
|
||||
if (p->offset) {
|
||||
*((unsigned char *)s + p->offset) = value;
|
||||
if (ret) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int strstart(const char *val, const char **str)
|
||||
{
|
||||
const char *p, *q;
|
||||
|
@ -1469,7 +1513,7 @@ static int tcc_set_linker(TCCState *s, const char *option)
|
|||
tcc_error("unsupported linker option '%s'", option);
|
||||
}
|
||||
|
||||
if (ignoring && s->warn_unsupported)
|
||||
if (ignoring && NEED_WARNING(s, unsupported))
|
||||
tcc_warning("unsupported linker option '%s'", option);
|
||||
|
||||
option = skip_linker_arg(&p);
|
||||
|
@ -1616,12 +1660,13 @@ static const TCCOption tcc_options[] = {
|
|||
|
||||
static const FlagDef options_W[] = {
|
||||
{ 0, 0, "all" },
|
||||
{ offsetof(TCCState, warn_unsupported), 0, "unsupported" },
|
||||
{ offsetof(TCCState, warn_write_strings), WD_ALL, "write-strings" },
|
||||
{ offsetof(TCCState, warn_error), 0, "error" },
|
||||
{ offsetof(TCCState, warn_gcc_compat), 0, "gcc-compat" },
|
||||
{ offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
|
||||
"implicit-function-declaration" },
|
||||
{ offsetof(TCCState, warn_unsupported), WD_ERROR, "unsupported" },
|
||||
{ offsetof(TCCState, warn_gcc_compat), WD_ERROR, "gcc-compat" },
|
||||
{ offsetof(TCCState, warn_write_strings), WD_ERROR | WD_ALL,
|
||||
"write-strings" },
|
||||
{ offsetof(TCCState, warn_implicit_function_declaration),
|
||||
WD_ERROR | WD_ALL, "implicit-function-declaration" },
|
||||
{ 0, 0, NULL }
|
||||
};
|
||||
|
||||
|
@ -1920,7 +1965,7 @@ reparse:
|
|||
break;
|
||||
case TCC_OPTION_W:
|
||||
s->warn_none = 0;
|
||||
if (optarg[0] && set_flag(s, options_W, optarg) < 0)
|
||||
if (optarg[0] && set_W_flag(s, options_W, optarg) < 0)
|
||||
goto unsupported_option;
|
||||
break;
|
||||
case TCC_OPTION_w:
|
||||
|
@ -2007,7 +2052,7 @@ reparse:
|
|||
break;
|
||||
default:
|
||||
unsupported_option:
|
||||
if (s->warn_unsupported)
|
||||
if (NEED_WARNING(s, unsupported))
|
||||
tcc_warning("unsupported option '%s'", r);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -267,10 +267,13 @@ Make string constants be of type @code{const char *} instead of @code{char
|
|||
*}.
|
||||
|
||||
@item -Werror
|
||||
Abort compilation if warnings are issued.
|
||||
Abort compilation if a warning is issued.
|
||||
Can be given an option to enable the specified warning
|
||||
and turn it into an error, for example @option{-Werror=unsupported}.
|
||||
(Enabling general abortion and disabling specifics is not supported.)
|
||||
|
||||
@item -Wall
|
||||
Activate all warnings, except @option{-Werror}, @option{-Wunusupported} and
|
||||
Activate all warnings, except @option{-Werror}, @option{-Wunsupported} and
|
||||
@option{-Wwrite-strings}.
|
||||
|
||||
@end table
|
||||
|
|
14
tcc.h
14
tcc.h
|
@ -767,13 +767,17 @@ struct TCCState {
|
|||
unsigned char dollars_in_identifiers; /* allows '$' char in identifiers */
|
||||
unsigned char ms_bitfields; /* if true, emulate MS algorithm for aligning bitfields */
|
||||
|
||||
/* warning switches */
|
||||
unsigned char warn_write_strings;
|
||||
unsigned char warn_unsupported;
|
||||
unsigned char warn_error;
|
||||
/* warning switches; but for first two, W[no-]error=X is supported */
|
||||
/* XXX TCC_IS_WARN_OR_ERR(X,Y) used to drive W[[no-]error]=X */
|
||||
unsigned char warn_none;
|
||||
unsigned char warn_implicit_function_declaration;
|
||||
unsigned char warn_error;
|
||||
unsigned char warn_unsupported;
|
||||
unsigned char warn_gcc_compat;
|
||||
unsigned char warn_write_strings;
|
||||
unsigned char warn_implicit_function_declaration;
|
||||
#define NEED_WARNING(SELF,SWITCH) \
|
||||
((SELF)->warn_ ## SWITCH \
|
||||
? (((SELF)->warn_ ## SWITCH & 2) ? (SELF)->warn_error = 1 : 1) : 0)
|
||||
|
||||
/* compile with debug symbol (and use them if error during execution) */
|
||||
unsigned char do_debug;
|
||||
|
|
8
tccasm.c
8
tccasm.c
|
@ -775,7 +775,7 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
else
|
||||
pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL));
|
||||
|
||||
if (s1->warn_unsupported)
|
||||
if (NEED_WARNING(s1, unsupported))
|
||||
tcc_warning("ignoring .file %s", filename);
|
||||
|
||||
next();
|
||||
|
@ -793,7 +793,7 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
else
|
||||
pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL));
|
||||
|
||||
if (s1->warn_unsupported)
|
||||
if (NEED_WARNING(s1, unsupported))
|
||||
tcc_warning("ignoring .ident %s", ident);
|
||||
|
||||
next();
|
||||
|
@ -810,7 +810,7 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
}
|
||||
|
||||
/* XXX .size name,label2-label1 */
|
||||
if (s1->warn_unsupported)
|
||||
if (NEED_WARNING(s1, unsupported))
|
||||
tcc_warning("ignoring .size %s,*", get_tok_str(tok, NULL));
|
||||
|
||||
next();
|
||||
|
@ -840,7 +840,7 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
|
||||
sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
|
||||
}
|
||||
else if (s1->warn_unsupported)
|
||||
else if (NEED_WARNING(s1, unsupported))
|
||||
tcc_warning("change type of '%s' from 0x%x to '%s' ignored",
|
||||
get_tok_str(sym->v, NULL), sym->type.t, newtype);
|
||||
|
||||
|
|
10
tccgen.c
10
tccgen.c
|
@ -4506,7 +4506,7 @@ redo:
|
|||
ad->a.dllimport = 1;
|
||||
break;
|
||||
default:
|
||||
if (tcc_state->warn_unsupported)
|
||||
if (NEED_WARNING(tcc_state, unsupported))
|
||||
tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
|
||||
/* skip parameters */
|
||||
if (tok == '(') {
|
||||
|
@ -5915,7 +5915,7 @@ ST_FUNC void unary(void)
|
|||
len = strlen(funcname) + 1;
|
||||
/* generate char[len] type */
|
||||
type.t = VT_BYTE;
|
||||
if (tcc_state->warn_write_strings)
|
||||
if (NEED_WARNING(tcc_state, write_strings))
|
||||
type.t |= VT_CONSTANT;
|
||||
mk_pointer(&type);
|
||||
type.t |= VT_ARRAY;
|
||||
|
@ -5942,7 +5942,7 @@ ST_FUNC void unary(void)
|
|||
if (tcc_state->char_is_unsigned)
|
||||
t = VT_BYTE | VT_UNSIGNED;
|
||||
str_init:
|
||||
if (tcc_state->warn_write_strings)
|
||||
if (NEED_WARNING(tcc_state, write_strings))
|
||||
t |= VT_CONSTANT;
|
||||
type.t = t;
|
||||
mk_pointer(&type);
|
||||
|
@ -6378,9 +6378,9 @@ special_math_val:
|
|||
tcc_error("'%s' undeclared", name);
|
||||
/* for simple function calls, we tolerate undeclared
|
||||
external reference to int() function */
|
||||
if (tcc_state->warn_implicit_function_declaration
|
||||
if (NEED_WARNING(tcc_state, implicit_function_declaration)
|
||||
#ifdef TCC_TARGET_PE
|
||||
/* people must be warned about using undeclared WINAPI functions
|
||||
/* must warn about using undeclared WINAPI functions
|
||||
(which usually start with uppercase letter) */
|
||||
|| (name[0] >= 'A' && name[0] <= 'Z')
|
||||
#endif
|
||||
|
|
3
tccpp.c
3
tccpp.c
|
@ -1770,9 +1770,8 @@ static void pragma_parse(TCCState *s1)
|
|||
tcc_free(p);
|
||||
}
|
||||
|
||||
} else if (s1->warn_unsupported) {
|
||||
} else if (NEED_WARNING(s1, unsupported))
|
||||
tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc));
|
||||
}
|
||||
return;
|
||||
|
||||
pragma_err:
|
||||
|
|
Loading…
Reference in a new issue