added -funsigned-char, -fsigned-char and -Wimplicit-function-declaration
This commit is contained in:
21
tcc-doc.texi
21
tcc-doc.texi
@ -199,6 +199,20 @@ also be defined: @option{-DF(a)=a+1}
|
|||||||
Undefine preprocessor symbol @samp{sym}.
|
Undefine preprocessor symbol @samp{sym}.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
Compilation flags:
|
||||||
|
|
||||||
|
Note: each of the following warning options has a negative form beginning with
|
||||||
|
@option{-fno-}.
|
||||||
|
|
||||||
|
@table @option
|
||||||
|
@item -funsigned-char
|
||||||
|
Let the @code{char} type be unsigned.
|
||||||
|
|
||||||
|
@item -fsigned-char
|
||||||
|
Let the @code{char} type be signed.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
Warning options:
|
Warning options:
|
||||||
|
|
||||||
@table @option
|
@table @option
|
||||||
@ -211,11 +225,14 @@ Note: each of the following warning options has a negative form beginning with
|
|||||||
@option{-Wno-}.
|
@option{-Wno-}.
|
||||||
|
|
||||||
@table @option
|
@table @option
|
||||||
|
@item -Wimplicit-function-declaration
|
||||||
|
Warn about implicit function declaration.
|
||||||
|
|
||||||
@item -Wunsupported
|
@item -Wunsupported
|
||||||
Warn about unsupported GCC features that are ignored by TCC.
|
Warn about unsupported GCC features that are ignored by TCC.
|
||||||
|
|
||||||
@item -Wwrite-strings
|
@item -Wwrite-strings
|
||||||
Make string constants being of type @code{const char *} intead of @code{char
|
Make string constants be of type @code{const char *} instead of @code{char
|
||||||
*}.
|
*}.
|
||||||
|
|
||||||
@item -Werror
|
@item -Werror
|
||||||
@ -223,7 +240,7 @@ Abort compilation if warnings are issued.
|
|||||||
|
|
||||||
@item -Wall
|
@item -Wall
|
||||||
Activate all warnings, except @option{-Werror}, @option{-Wunusupported} and
|
Activate all warnings, except @option{-Werror}, @option{-Wunusupported} and
|
||||||
@option{-Wwrite-strings} (currently not useful).
|
@option{-Wwrite-strings}.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|||||||
109
tcc.c
109
tcc.c
@ -407,11 +407,15 @@ struct TCCState {
|
|||||||
/* if true, only link in referenced objects from archive */
|
/* if true, only link in referenced objects from archive */
|
||||||
int alacarte_link;
|
int alacarte_link;
|
||||||
|
|
||||||
|
/* C language options */
|
||||||
|
int char_is_unsigned;
|
||||||
|
|
||||||
/* warning switches */
|
/* warning switches */
|
||||||
int warn_write_strings;
|
int warn_write_strings;
|
||||||
int warn_unsupported;
|
int warn_unsupported;
|
||||||
int warn_error;
|
int warn_error;
|
||||||
int warn_none;
|
int warn_none;
|
||||||
|
int warn_implicit_function_declaration;
|
||||||
|
|
||||||
/* error handling */
|
/* error handling */
|
||||||
void *error_opaque;
|
void *error_opaque;
|
||||||
@ -6415,10 +6419,10 @@ static int parse_btype(CType *type, AttributeDef *ad)
|
|||||||
the_end:
|
the_end:
|
||||||
if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
|
if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
|
||||||
error("signed and unsigned modifier");
|
error("signed and unsigned modifier");
|
||||||
#ifdef CHAR_IS_UNSIGNED
|
if (tcc_state->char_is_unsigned) {
|
||||||
if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
|
if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
|
||||||
t |= VT_UNSIGNED;
|
t |= VT_UNSIGNED;
|
||||||
#endif
|
}
|
||||||
t &= ~VT_SIGNED;
|
t &= ~VT_SIGNED;
|
||||||
|
|
||||||
/* long is never used as type */
|
/* long is never used as type */
|
||||||
@ -6951,6 +6955,9 @@ static void unary(void)
|
|||||||
error("'%s' undeclared", get_tok_str(t, NULL));
|
error("'%s' undeclared", get_tok_str(t, NULL));
|
||||||
/* 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 (tcc_state->warn_implicit_function_declaration)
|
||||||
|
warning("implicit declaration of function '%s'",
|
||||||
|
get_tok_str(t, NULL));
|
||||||
s = external_global_sym(t, &func_old_type, 0);
|
s = external_global_sym(t, &func_old_type, 0);
|
||||||
}
|
}
|
||||||
vset(&s->type, s->r, s->c);
|
vset(&s->type, s->r, s->c);
|
||||||
@ -9286,9 +9293,6 @@ TCCState *tcc_new(void)
|
|||||||
tcc_define_symbol(s, "arm", NULL);
|
tcc_define_symbol(s, "arm", NULL);
|
||||||
tcc_define_symbol(s, "__APCS_32__", NULL);
|
tcc_define_symbol(s, "__APCS_32__", NULL);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CHAR_IS_UNSIGNED
|
|
||||||
tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
|
|
||||||
#endif
|
|
||||||
#if defined(linux)
|
#if defined(linux)
|
||||||
tcc_define_symbol(s, "__linux__", NULL);
|
tcc_define_symbol(s, "__linux__", NULL);
|
||||||
tcc_define_symbol(s, "linux", NULL);
|
tcc_define_symbol(s, "linux", NULL);
|
||||||
@ -9325,6 +9329,10 @@ TCCState *tcc_new(void)
|
|||||||
".dynstrtab",
|
".dynstrtab",
|
||||||
".dynhashtab", SHF_PRIVATE);
|
".dynhashtab", SHF_PRIVATE);
|
||||||
s->alacarte_link = 1;
|
s->alacarte_link = 1;
|
||||||
|
|
||||||
|
#ifdef CHAR_IS_UNSIGNED
|
||||||
|
s->char_is_unsigned = 1;
|
||||||
|
#endif
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9585,6 +9593,10 @@ int tcc_set_output_type(TCCState *s, int output_type)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (s->char_is_unsigned) {
|
||||||
|
tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* add debug sections */
|
/* add debug sections */
|
||||||
if (do_debug) {
|
if (do_debug) {
|
||||||
/* stab symbols */
|
/* stab symbols */
|
||||||
@ -9608,39 +9620,75 @@ int tcc_set_output_type(TCCState *s, int output_type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define WD_ALL 0x0001 /* warning is activated when using -Wall */
|
#define WD_ALL 0x0001 /* warning is activated when using -Wall */
|
||||||
|
#define FD_INVERT 0x0002 /* invert value before storing */
|
||||||
|
|
||||||
typedef struct WarningDef {
|
typedef struct FlagDef {
|
||||||
int offset;
|
uint16_t offset;
|
||||||
int flags;
|
uint16_t flags;
|
||||||
const char *name;
|
const char *name;
|
||||||
} WarningDef;
|
} FlagDef;
|
||||||
|
|
||||||
static const WarningDef warning_defs[] = {
|
static const FlagDef warning_defs[] = {
|
||||||
{ offsetof(TCCState, warn_unsupported), 0, "unsupported" },
|
{ offsetof(TCCState, warn_unsupported), 0, "unsupported" },
|
||||||
{ offsetof(TCCState, warn_write_strings), 0, "write-strings" },
|
{ offsetof(TCCState, warn_write_strings), 0, "write-strings" },
|
||||||
{ offsetof(TCCState, warn_error), 0, "error" },
|
{ offsetof(TCCState, warn_error), 0, "error" },
|
||||||
|
{ offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
|
||||||
|
"implicit-function-declaration" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
|
||||||
|
const char *name, int value)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const FlagDef *p;
|
||||||
|
const char *r;
|
||||||
|
|
||||||
|
r = name;
|
||||||
|
if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') {
|
||||||
|
r += 3;
|
||||||
|
value = !value;
|
||||||
|
}
|
||||||
|
for(i = 0, p = flags; i < nb_flags; i++, p++) {
|
||||||
|
if (!strcmp(r, p->name))
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
found:
|
||||||
|
if (p->flags & FD_INVERT)
|
||||||
|
value = !value;
|
||||||
|
*(int *)((uint8_t *)s + p->offset) = value;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* set/reset a warning */
|
/* set/reset a warning */
|
||||||
int tcc_set_warning(TCCState *s, const char *warning_name, int value)
|
int tcc_set_warning(TCCState *s, const char *warning_name, int value)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const WarningDef *p;
|
const FlagDef *p;
|
||||||
|
|
||||||
if (!strcmp(warning_name, "all")) {
|
if (!strcmp(warning_name, "all")) {
|
||||||
for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) {
|
for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) {
|
||||||
if (p->flags & WD_ALL)
|
if (p->flags & WD_ALL)
|
||||||
*(int *)((uint8_t *)s + p->offset) = 1;
|
*(int *)((uint8_t *)s + p->offset) = 1;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) {
|
|
||||||
if (!strcmp(warning_name, p->name))
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
found:
|
|
||||||
*(int *)((uint8_t *)s + p->offset) = value;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
return set_flag(s, warning_defs, countof(warning_defs),
|
||||||
|
warning_name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const FlagDef flag_defs[] = {
|
||||||
|
{ offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
|
||||||
|
{ offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* set/reset a flag */
|
||||||
|
int tcc_set_flag(TCCState *s, const char *flag_name, int value)
|
||||||
|
{
|
||||||
|
return set_flag(s, flag_defs, countof(flag_defs),
|
||||||
|
flag_name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(LIBTCC)
|
#if !defined(LIBTCC)
|
||||||
@ -9688,7 +9736,8 @@ void help(void)
|
|||||||
" -Bdir set tcc internal library path\n"
|
" -Bdir set tcc internal library path\n"
|
||||||
" -bench output compilation statistics\n"
|
" -bench output compilation statistics\n"
|
||||||
" -run run compiled source\n"
|
" -run run compiled source\n"
|
||||||
" -Wwarning set or reset (with 'no-' prefix) 'warning'\n"
|
" -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n"
|
||||||
|
" -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n"
|
||||||
" -w disable all warnings\n"
|
" -w disable all warnings\n"
|
||||||
"Preprocessor options:\n"
|
"Preprocessor options:\n"
|
||||||
" -Idir add include path 'dir'\n"
|
" -Idir add include path 'dir'\n"
|
||||||
@ -9968,18 +10017,14 @@ int parse_args(TCCState *s, int argc, char **argv)
|
|||||||
case TCC_OPTION_v:
|
case TCC_OPTION_v:
|
||||||
printf("tcc version %s\n", TCC_VERSION);
|
printf("tcc version %s\n", TCC_VERSION);
|
||||||
exit(0);
|
exit(0);
|
||||||
case TCC_OPTION_W:
|
case TCC_OPTION_f:
|
||||||
{
|
if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported)
|
||||||
const char *p = optarg;
|
goto unsupported_option;
|
||||||
int value;
|
break;
|
||||||
value = 1;
|
case TCC_OPTION_W:
|
||||||
if (p[0] == 'n' && p[1] == 'o' && p[2] == '-') {
|
if (tcc_set_warning(s, optarg, 1) < 0 &&
|
||||||
p += 2;
|
s->warn_unsupported)
|
||||||
value = 0;
|
|
||||||
}
|
|
||||||
if (tcc_set_warning(s, p, value) < 0 && s->warn_unsupported)
|
|
||||||
goto unsupported_option;
|
goto unsupported_option;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case TCC_OPTION_w:
|
case TCC_OPTION_w:
|
||||||
s->warn_none = 1;
|
s->warn_none = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user