From: Steffen Nurpmeso <steffen@sdaoden.eu>
Date: Mon, 26 Jul 2021 16:18:45 +0200
Subject: [PATCH] (Complicated,ugly) -Werror=(need unrolled code) support
---
libtcc.c | 24 +++++++++++++++++++++++-
tcc.h | 2 ++
tccgen.c | 15 ++++++++++++---
3 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/libtcc.c b/libtcc.c
index 2002dd56c9..eb38f339a4 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -1647,6 +1647,14 @@ static const FlagDef options_W[] = {
{ 0, 0, NULL }
};
+/* XXX ideally .warn* would be flags, 1=only warn, 2=warn and out? */
+static const FlagDef options_Werror[] = {
+ { offsetof(TCCState, warn_write_strings_error), WD_ALL, "write-strings" },
+ { offsetof(TCCState, warn_implicit_function_declaration_error), WD_ALL,
+ "implicit-function-declaration" },
+ { 0, 0, NULL }
+};
+
static const FlagDef options_f[] = {
{ offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
{ offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
@@ -1938,8 +1946,22 @@ reparse:
break;
case TCC_OPTION_W:
s->warn_none = 0;
- if (optarg[0] && set_flag(s, options_W, optarg) < 0)
+ if (optarg[0] && set_flag(s, options_W, optarg) < 0) {
+ char *sub;
+ int subt = 0;
+
+ /* XXX -W[no-]error= handling ugly; -W+: enum,flag carrier? */
+ if ((sub = strchr(optarg, '=')) != NULL &&
+ (!strncmp(optarg, "error", (uintptr_t)(sub-optarg)) ||
+ (subt = 1, !strncmp(optarg, "no-error",
+ (uintptr_t)(sub - optarg)))) &&
+ set_flag(s, options_Werror, ++sub) == 0) {
+ if (subt != 1)
+ set_flag(s, options_W, sub);
+ break;
+ }
goto unsupported_option;
+ }
break;
case TCC_OPTION_w:
s->warn_none = 1;
diff --git a/tcc.h b/tcc.h
index cc8a2f82b5..3bb75215e9 100644
--- a/tcc.h
+++ b/tcc.h
@@ -775,10 +775,12 @@ struct TCCState {
/* warning switches */
unsigned char warn_write_strings;
+ unsigned char warn_write_strings_error;
unsigned char warn_unsupported;
unsigned char warn_error;
unsigned char warn_none;
unsigned char warn_implicit_function_declaration;
+ unsigned char warn_implicit_function_declaration_error;
unsigned char warn_gcc_compat;
/* compile with debug symbol (and use them if error during execution) */
diff --git a/tccgen.c b/tccgen.c
index 833b70431a..4fd30476a4 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -5915,8 +5915,11 @@ ST_FUNC void unary(void)
len = strlen(funcname) + 1;
/* generate char[len] type */
type.t = VT_BYTE;
- if (tcc_state->warn_write_strings)
+ if (tcc_state->warn_write_strings) {
+ if (tcc_state->warn_write_strings_error)
+ tcc_state->warn_error = 1;
type.t |= VT_CONSTANT;
+ }
mk_pointer(&type);
type.t |= VT_ARRAY;
type.ref->c = len;
@@ -5942,8 +5945,11 @@ 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 (tcc_state->warn_write_strings) {
+ if (tcc_state->warn_write_strings_error)
+ tcc_state->warn_error = 1;
t |= VT_CONSTANT;
+ }
type.t = t;
mk_pointer(&type);
type.t |= VT_ARRAY;
@@ -6384,8 +6390,11 @@ special_math_val:
(which usually start with uppercase letter) */
|| (name[0] >= 'A' && name[0] <= 'Z')
#endif
- )
+ ) {
+ if (tcc_state->warn_implicit_function_declaration_error)
+ tcc_state->warn_error = 1;
tcc_warning("implicit declaration of function '%s'", name);
+ }
s = external_global_sym(t, &func_old_type);
}