mirror of
https://github.com/mirror/tinycc.git
synced 2025-04-01 12:30:08 +08:00
-W[no-]error=X: gcc compat: when disabling X again, do not unset the warning
This commit is contained in:
parent
b1d9de6794
commit
0c16762418
78
libtcc.c
78
libtcc.c
@ -786,7 +786,7 @@ LIBTCCAPI TCCState *tcc_new(void)
|
|||||||
s->nocommon = 1;
|
s->nocommon = 1;
|
||||||
s->dollars_in_identifiers = 1; /*on by default like in gcc/clang*/
|
s->dollars_in_identifiers = 1; /*on by default like in gcc/clang*/
|
||||||
s->cversion = 199901; /* default unless -std=c11 is supplied */
|
s->cversion = 199901; /* default unless -std=c11 is supplied */
|
||||||
s->warn_implicit_function_declaration = 1;
|
s->warn_mask |= WARN_IMPLICIT_FUNCTION_DECLARATION;
|
||||||
s->ms_extensions = 1;
|
s->ms_extensions = 1;
|
||||||
|
|
||||||
#ifdef CHAR_IS_UNSIGNED
|
#ifdef CHAR_IS_UNSIGNED
|
||||||
@ -1280,46 +1280,70 @@ ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, const char *name)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_FUNC int set_W_flag(TCCState *s, const FlagDef *flags, const char *optarg)
|
ST_FUNC int set_W_flag(TCCState *s, const char *optarg)
|
||||||
{
|
{
|
||||||
int value, ret;
|
static struct a_W_flag{
|
||||||
const FlagDef *p;
|
uint32_t wbit;
|
||||||
|
uint32_t flags;
|
||||||
|
char const *name;
|
||||||
|
} const opts[] = {
|
||||||
|
{WARN_ALL, 0, "all"},
|
||||||
|
{WARN_ERROR, 0, "error"},
|
||||||
|
{WARN_UNSUPPORTED, WD_ERROR, "unsupported"},
|
||||||
|
{WARN_GCC_COMPAT, WD_ERROR, "gcc-compat"},
|
||||||
|
{WARN_WRITE_STRINGS, WD_ERROR | WD_ALL, "write-strings"},
|
||||||
|
{WARN_IMPLICIT_FUNCTION_DECLARATION, WD_ERROR | WD_ALL,
|
||||||
|
"implicit-function-declaration"}
|
||||||
|
}, *p;
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
unsigned char mode;
|
||||||
const char *r, *sub;
|
const char *r, *sub;
|
||||||
|
|
||||||
value = 1;
|
mode = 1;
|
||||||
r = optarg;
|
r = optarg;
|
||||||
if (no_flag(&r))
|
if (no_flag(&r))
|
||||||
value = 0;
|
mode = 0;
|
||||||
|
|
||||||
if ((sub = strchr(r, '=')) != NULL) {
|
if ((sub = strchr(r, '=')) != NULL) {
|
||||||
if (strncmp(r, "error", (uintptr_t)(sub - r)))
|
if (strncmp(r, "error", (uintptr_t)(sub - r)))
|
||||||
return -1;
|
return -1;
|
||||||
r = ++sub;
|
r = ++sub;
|
||||||
if (value)
|
mode |= 2;
|
||||||
value = 1 | 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .offset for "all" is 0 */
|
for (ret = -1, p = opts; p < &opts[countof(opts)]; ++p) {
|
||||||
for (ret = -1, p = flags; p->name; ++p) {
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (strcmp(r, p->name))
|
if (strcmp(r, p->name))
|
||||||
continue;
|
continue;
|
||||||
if (sub != NULL && !(p->flags & WD_ERROR))
|
if ((mode & 2) && !(p->flags & WD_ERROR))
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (0 == (p->flags & WD_ALL))
|
if (0 == (p->flags & WD_ALL))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (p->offset) {
|
|
||||||
*((unsigned char *)s + p->offset) = value;
|
if (p->wbit == WARN_ALL) {
|
||||||
if (ret) {
|
/* Start a loop over all the rest */
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode & 1) {
|
||||||
|
s->warn_mask |= p->wbit;
|
||||||
|
if (mode & 2)
|
||||||
|
s->warn_mask |= p->wbit << WARN_ERROR_SHIFT;
|
||||||
|
} else {
|
||||||
|
s->warn_mask &= ~(p->wbit << ((mode & 2) ? WARN_ERROR_SHIFT : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Done if not in "all" mode */
|
||||||
|
if (ret) {
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1513,7 +1537,7 @@ static int tcc_set_linker(TCCState *s, const char *option)
|
|||||||
tcc_error("unsupported linker option '%s'", option);
|
tcc_error("unsupported linker option '%s'", option);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ignoring && NEED_WARNING(s, unsupported))
|
if (ignoring && NEED_WARNING(s, UNSUPPORTED))
|
||||||
tcc_warning("unsupported linker option '%s'", option);
|
tcc_warning("unsupported linker option '%s'", option);
|
||||||
|
|
||||||
option = skip_linker_arg(&p);
|
option = skip_linker_arg(&p);
|
||||||
@ -1658,18 +1682,6 @@ static const TCCOption tcc_options[] = {
|
|||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const FlagDef options_W[] = {
|
|
||||||
{ 0, 0, "all" },
|
|
||||||
{ offsetof(TCCState, warn_error), 0, "error" },
|
|
||||||
{ 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 }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const FlagDef options_f[] = {
|
static const FlagDef options_f[] = {
|
||||||
{ offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
|
{ offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
|
||||||
{ offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
|
{ offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
|
||||||
@ -1965,7 +1977,7 @@ reparse:
|
|||||||
break;
|
break;
|
||||||
case TCC_OPTION_W:
|
case TCC_OPTION_W:
|
||||||
s->warn_none = 0;
|
s->warn_none = 0;
|
||||||
if (optarg[0] && set_W_flag(s, options_W, optarg) < 0)
|
if (optarg[0] && set_W_flag(s, optarg) < 0)
|
||||||
goto unsupported_option;
|
goto unsupported_option;
|
||||||
break;
|
break;
|
||||||
case TCC_OPTION_w:
|
case TCC_OPTION_w:
|
||||||
@ -2052,7 +2064,7 @@ reparse:
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
unsupported_option:
|
unsupported_option:
|
||||||
if (NEED_WARNING(s, unsupported))
|
if (NEED_WARNING(s, UNSUPPORTED))
|
||||||
tcc_warning("unsupported option '%s'", r);
|
tcc_warning("unsupported option '%s'", r);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,8 @@ Make string constants be of type @code{const char *} instead of @code{char
|
|||||||
Abort compilation if a warning is issued.
|
Abort compilation if a warning is issued.
|
||||||
Can be given an option to enable the specified warning
|
Can be given an option to enable the specified warning
|
||||||
and turn it into an error, for example @option{-Werror=unsupported}.
|
and turn it into an error, for example @option{-Werror=unsupported}.
|
||||||
(Enabling general abortion and disabling specifics is not supported.)
|
Enabling general abortion and disabling specifics is not supported.
|
||||||
|
Disabling specific abortions again does not disable the according warning.
|
||||||
|
|
||||||
@item -Wall
|
@item -Wall
|
||||||
Activate all warnings, except @option{-Werror}, @option{-Wunsupported} and
|
Activate all warnings, except @option{-Werror}, @option{-Wunsupported} and
|
||||||
|
26
tcc.h
26
tcc.h
@ -737,6 +737,18 @@ struct sym_attr {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* 32-bit bit carrier, split in two halves: lower=warn, upper=error */
|
||||||
|
enum warn_option {
|
||||||
|
WARN_NONE,
|
||||||
|
WARN_UNSUPPORTED = 1u<<0,
|
||||||
|
WARN_GCC_COMPAT = 1u<<1,
|
||||||
|
WARN_WRITE_STRINGS = 1u<<2,
|
||||||
|
WARN_IMPLICIT_FUNCTION_DECLARATION = 1u<<3,
|
||||||
|
WARN_ERROR = 1u<<4,
|
||||||
|
WARN_ALL = WARN_ERROR - 1
|
||||||
|
};
|
||||||
|
enum {WARN_ERROR_SHIFT = 16u};
|
||||||
|
|
||||||
struct TCCState {
|
struct TCCState {
|
||||||
unsigned char verbose; /* if true, display some information during compilation */
|
unsigned char verbose; /* if true, display some information during compilation */
|
||||||
unsigned char nostdinc; /* if true, no standard headers are added */
|
unsigned char nostdinc; /* if true, no standard headers are added */
|
||||||
@ -767,17 +779,15 @@ struct TCCState {
|
|||||||
unsigned char dollars_in_identifiers; /* allows '$' char in identifiers */
|
unsigned char dollars_in_identifiers; /* allows '$' char in identifiers */
|
||||||
unsigned char ms_bitfields; /* if true, emulate MS algorithm for aligning bitfields */
|
unsigned char ms_bitfields; /* if true, emulate MS algorithm for aligning bitfields */
|
||||||
|
|
||||||
/* 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_none;
|
||||||
unsigned char warn_error;
|
unsigned char warn_error;
|
||||||
unsigned char warn_unsupported;
|
/* NEED_WARNING(SELF,X) used to drive W[[no-]error]=X */
|
||||||
unsigned char warn_gcc_compat;
|
uint32_t warn_mask;
|
||||||
unsigned char warn_write_strings;
|
|
||||||
unsigned char warn_implicit_function_declaration;
|
|
||||||
#define NEED_WARNING(SELF,SWITCH) \
|
#define NEED_WARNING(SELF,SWITCH) \
|
||||||
((SELF)->warn_ ## SWITCH \
|
(((SELF)->warn_mask & \
|
||||||
? (((SELF)->warn_ ## SWITCH & 2) ? (SELF)->warn_error = 1 : 1) : 0)
|
(WARN_ ## SWITCH | (WARN_ ## SWITCH << WARN_ERROR_SHIFT))) \
|
||||||
|
? (((SELF)->warn_mask & (WARN_ ## SWITCH << WARN_ERROR_SHIFT)) \
|
||||||
|
? (SELF)->warn_error = 1 : 1) : 0)
|
||||||
|
|
||||||
/* compile with debug symbol (and use them if error during execution) */
|
/* compile with debug symbol (and use them if error during execution) */
|
||||||
unsigned char do_debug;
|
unsigned char do_debug;
|
||||||
|
8
tccasm.c
8
tccasm.c
@ -775,7 +775,7 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||||||
else
|
else
|
||||||
pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL));
|
pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL));
|
||||||
|
|
||||||
if (NEED_WARNING(s1, unsupported))
|
if (NEED_WARNING(s1, UNSUPPORTED))
|
||||||
tcc_warning("ignoring .file %s", filename);
|
tcc_warning("ignoring .file %s", filename);
|
||||||
|
|
||||||
next();
|
next();
|
||||||
@ -793,7 +793,7 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||||||
else
|
else
|
||||||
pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL));
|
pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL));
|
||||||
|
|
||||||
if (NEED_WARNING(s1, unsupported))
|
if (NEED_WARNING(s1, UNSUPPORTED))
|
||||||
tcc_warning("ignoring .ident %s", ident);
|
tcc_warning("ignoring .ident %s", ident);
|
||||||
|
|
||||||
next();
|
next();
|
||||||
@ -810,7 +810,7 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* XXX .size name,label2-label1 */
|
/* XXX .size name,label2-label1 */
|
||||||
if (NEED_WARNING(s1, unsupported))
|
if (NEED_WARNING(s1, UNSUPPORTED))
|
||||||
tcc_warning("ignoring .size %s,*", get_tok_str(tok, NULL));
|
tcc_warning("ignoring .size %s,*", get_tok_str(tok, NULL));
|
||||||
|
|
||||||
next();
|
next();
|
||||||
@ -840,7 +840,7 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||||||
if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
|
if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
|
||||||
sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
|
sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
|
||||||
}
|
}
|
||||||
else if (NEED_WARNING(s1, unsupported))
|
else if (NEED_WARNING(s1, UNSUPPORTED))
|
||||||
tcc_warning("change type of '%s' from 0x%x to '%s' ignored",
|
tcc_warning("change type of '%s' from 0x%x to '%s' ignored",
|
||||||
get_tok_str(sym->v, NULL), sym->type.t, newtype);
|
get_tok_str(sym->v, NULL), sym->type.t, newtype);
|
||||||
|
|
||||||
|
8
tccgen.c
8
tccgen.c
@ -4506,7 +4506,7 @@ redo:
|
|||||||
ad->a.dllimport = 1;
|
ad->a.dllimport = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (NEED_WARNING(tcc_state, unsupported))
|
if (NEED_WARNING(tcc_state, UNSUPPORTED))
|
||||||
tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
|
tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
|
||||||
/* skip parameters */
|
/* skip parameters */
|
||||||
if (tok == '(') {
|
if (tok == '(') {
|
||||||
@ -5915,7 +5915,7 @@ ST_FUNC void unary(void)
|
|||||||
len = strlen(funcname) + 1;
|
len = strlen(funcname) + 1;
|
||||||
/* generate char[len] type */
|
/* generate char[len] type */
|
||||||
type.t = VT_BYTE;
|
type.t = VT_BYTE;
|
||||||
if (NEED_WARNING(tcc_state, write_strings))
|
if (NEED_WARNING(tcc_state, WRITE_STRINGS))
|
||||||
type.t |= VT_CONSTANT;
|
type.t |= VT_CONSTANT;
|
||||||
mk_pointer(&type);
|
mk_pointer(&type);
|
||||||
type.t |= VT_ARRAY;
|
type.t |= VT_ARRAY;
|
||||||
@ -5942,7 +5942,7 @@ ST_FUNC void unary(void)
|
|||||||
if (tcc_state->char_is_unsigned)
|
if (tcc_state->char_is_unsigned)
|
||||||
t = VT_BYTE | VT_UNSIGNED;
|
t = VT_BYTE | VT_UNSIGNED;
|
||||||
str_init:
|
str_init:
|
||||||
if (NEED_WARNING(tcc_state, write_strings))
|
if (NEED_WARNING(tcc_state, WRITE_STRINGS))
|
||||||
t |= VT_CONSTANT;
|
t |= VT_CONSTANT;
|
||||||
type.t = t;
|
type.t = t;
|
||||||
mk_pointer(&type);
|
mk_pointer(&type);
|
||||||
@ -6378,7 +6378,7 @@ special_math_val:
|
|||||||
tcc_error("'%s' undeclared", name);
|
tcc_error("'%s' undeclared", name);
|
||||||
/* for simple function calls, we tolerate undeclared
|
/* for simple function calls, we tolerate undeclared
|
||||||
external reference to int() function */
|
external reference to int() function */
|
||||||
if (NEED_WARNING(tcc_state, implicit_function_declaration)
|
if (NEED_WARNING(tcc_state, IMPLICIT_FUNCTION_DECLARATION)
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
/* must warn about using undeclared WINAPI functions
|
/* must warn about using undeclared WINAPI functions
|
||||||
(which usually start with uppercase letter) */
|
(which usually start with uppercase letter) */
|
||||||
|
2
tccpp.c
2
tccpp.c
@ -1770,7 +1770,7 @@ static void pragma_parse(TCCState *s1)
|
|||||||
tcc_free(p);
|
tcc_free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (NEED_WARNING(s1, unsupported))
|
} else if (NEED_WARNING(s1, UNSUPPORTED))
|
||||||
tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc));
|
tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user