added -funsigned-char, -fsigned-char and -Wimplicit-function-declaration

This commit is contained in:
bellard
2003-10-17 20:43:47 +00:00
parent 7a5123a770
commit 114883e078
2 changed files with 98 additions and 36 deletions

View File

@ -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
View File

@ -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;