From: Robert Pengelly Date: Thu, 20 Aug 2026 12:38:04 +0000 (+0100) Subject: Fixed define warning and started warning levels X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=refs%2Fheads%2Fmaster;p=scc.git Fixed define warning and started warning levels --- diff --git a/amd64.c b/amd64.c index 8844343..bc25c09 100644 --- a/amd64.c +++ b/amd64.c @@ -1158,7 +1158,9 @@ static void ensure_global_function_symbol (const char *name, const char *line_st return; } - report_line_at (get_filename (), lineno, REPORT_WARNING, line_start, name_caret, "implicit declaration of function '%s'", name); + if (state->warn & WARN_OLD_STYLE) { + report_line_at (get_filename (), lineno, REPORT_WARNING, line_start, name_caret, "implicit declaration of function '%s'", name); + } if (add_global_symbol (name, GLOBAL_SYMBOL_FUNCTION, 1, line_start, name_caret, lineno)) { @@ -37158,9 +37160,17 @@ static void parse_statement (void) { } if (current_function_is_void && has_value) { - report_line_at (get_filename (), ret_line, REPORT_WARNING, ret_start, ret_caret, "return with a value in void function"); + + if (state->warn & WARN_NO_RETURN) { + report_line_at (get_filename (), ret_line, REPORT_WARNING, ret_start, ret_caret, "return with a value in void function"); + } + } else if (!current_function_is_void && !has_value) { - report_line_at (get_filename (), ret_line, REPORT_WARNING, ret_start, ret_caret, "return with no value in non-void function"); + + if (state->warn & WARN_NO_RETURN) { + report_line_at (get_filename (), ret_line, REPORT_WARNING, ret_start, ret_caret, "return with no value in non-void function"); + } + } if (state->ofp) { @@ -37696,7 +37706,11 @@ static void parse_function_body (const char *name, int storage_class, int is_inl check_goto_labels (); if (!current_function_is_void && !current_function_has_return_statement) { - report_line_at (function_filename_copy ? function_filename_copy : get_filename (), function_line, REPORT_WARNING, function_start, function_caret, "control reaches end of non-void function"); + + if (state->warn & WARN_NO_RETURN) { + report_line_at (function_filename_copy ? function_filename_copy : get_filename (), function_line, REPORT_WARNING, function_start, function_caret, "control reaches end of non-void function"); + } + } pending_return_jump = 0; diff --git a/cc.h b/cc.h index 6aaf209..997bbda 100755 --- a/cc.h +++ b/cc.h @@ -10,6 +10,22 @@ #include "list.h" #include "vector.h" +#define WARN_ERROR (1U << 0) +#define WARN_NO_RETURN (1U << 1) +#define WARN_SIGNEDNESS (1U << 2) +#define WARN_CONVERSION (1U << 3) +#define WARN_DUP_DEFINE (1U << 4) +#define WARN_UNUSED (1U << 5) +#define WARN_SHADOW (1U << 6) +#define WARN_UNREACHABLE (1U << 7) +#define WARN_FALLTHROUGH (1U << 8) +#define WARN_OLD_STYLE (1U << 9) +#define WARN_INITIALIZER (1U << 10) + +#define WARN_DEFAULT (WARN_DUP_DEFINE | WARN_UNREACHABLE) +#define WARN_ALL (WARN_DEFAULT | WARN_NO_RETURN | WARN_SIGNEDNESS | WARN_UNUSED | WARN_FALLTHROUGH | WARN_INITIALIZER) +#define WARN_EXTRA (WARN_ALL | WARN_CONVERSION | WARN_SHADOW | WARN_OLD_STYLE) + struct cc_state { const char *ifile, *ofile; @@ -28,6 +44,7 @@ struct cc_state { int bits, std; int long64; int syntax; + int warn; unsigned long max_errors; long version; diff --git a/i386.c b/i386.c index 04da160..dd41fe8 100644 --- a/i386.c +++ b/i386.c @@ -972,7 +972,9 @@ static void ensure_global_function_symbol (const char *name, const char *line_st return; } - report_line_at (get_filename (), lineno, REPORT_WARNING, line_start, name_caret, "implicit declaration of function '%s'", name); + if (state->warn & WARN_OLD_STYLE) { + report_line_at (get_filename (), lineno, REPORT_WARNING, line_start, name_caret, "implicit declaration of function '%s'", name); + } if (add_global_symbol (name, GLOBAL_SYMBOL_FUNCTION, 1, line_start, name_caret, lineno)) { @@ -34528,9 +34530,17 @@ static void parse_statement (void) { } if (current_function_is_void && has_value) { - report_line_at (get_filename (), ret_line, REPORT_WARNING, ret_start, ret_caret, "return with a value in void function"); + + if (state->warn & WARN_NO_RETURN) { + report_line_at (get_filename (), ret_line, REPORT_WARNING, ret_start, ret_caret, "return with a value in void function"); + } + } else if (!current_function_is_void && !has_value) { - report_line_at (get_filename (), ret_line, REPORT_WARNING, ret_start, ret_caret, "return with no value in non-void function"); + + if (state->warn & WARN_NO_RETURN) { + report_line_at (get_filename (), ret_line, REPORT_WARNING, ret_start, ret_caret, "return with no value in non-void function"); + } + } if (state->ofp) { @@ -35055,7 +35065,11 @@ static void parse_function_body (const char *name, int storage_class, int is_inl check_goto_labels (); if (!current_function_is_void && !current_function_has_return_statement) { - report_line_at (function_filename_copy ? function_filename_copy : get_filename (), function_line, REPORT_WARNING, function_start, function_caret, "control reaches end of non-void function"); + + if (state->warn & WARN_NO_RETURN) { + report_line_at (function_filename_copy ? function_filename_copy : get_filename (), function_line, REPORT_WARNING, function_start, function_caret, "control reaches end of non-void function"); + } + } pending_return_jump = 0; diff --git a/int64.c b/int64.c index f9a46bd..eb3233e 100644 --- a/int64.c +++ b/int64.c @@ -4,6 +4,7 @@ #include #include +#include "cc.h" #include "int64.h" #include "report.h" @@ -284,7 +285,7 @@ void mask64 (int64_s *a, int bits) { if (bits <= 0) { - if (a->high != 0 || a->low != 0) { + if ((state->warn & WARN_CONVERSION) && (a->high != 0 || a->low != 0)) { report_at (get_filename(), get_line_number(), REPORT_WARNING, "implicit truncation of 0x%08lX%08lX to 0x00000000", a->high, a->low); } @@ -302,7 +303,7 @@ void mask64 (int64_s *a, int bits) { new_low = a->low & low_mask; new_high = 0; - if (a->high != 0 || (a->low & ~low_mask) != 0) { + if ((state->warn & WARN_CONVERSION) && (a->high != 0 || (a->low & ~low_mask) != 0)) { report_at (get_filename(), get_line_number(), REPORT_WARNING, "implicit truncation of 0x%08lX%08lX to 0x%08lX", a->high, a->low, new_low); } @@ -312,7 +313,7 @@ void mask64 (int64_s *a, int bits) { new_low = a->low; new_high = 0; - if (a->high != 0) { + if ((state->warn & WARN_CONVERSION) && a->high != 0) { report_at (get_filename(), get_line_number(), REPORT_WARNING, "implicit truncation of 0x%08lX%08lX to 0x%08lX", a->high, a->low, new_low); } @@ -323,7 +324,7 @@ void mask64 (int64_s *a, int bits) { new_low = a->low; new_high = a->high & high_mask; - if ((a->high & ~high_mask) != 0) { + if ((state->warn & WARN_CONVERSION) && (a->high & ~high_mask) != 0) { report_at (get_filename(), get_line_number(), REPORT_WARNING, "implicit truncation of 0x%08lX%08lX to 0x%08lX%08lX", a->high, a->low, new_high, new_low); } diff --git a/lib.c b/lib.c index 3d7c051..ad9ce7e 100755 --- a/lib.c +++ b/lib.c @@ -49,6 +49,7 @@ struct cc_option { #define CC_OPTION_STD 17 #define CC_OPTION_TRANDITIONAL_LINEMARKERS 18 #define CC_OPTION_UNDEF 19 +#define CC_OPTION_WARN 20 static struct cc_option opts[] = { @@ -67,6 +68,7 @@ static struct cc_option opts[] = { { "-E", CC_OPTION_PREPOCESS, CC_OPTION_NO_ARG }, { "-S", CC_OPTION_COMPILE, CC_OPTION_NO_ARG }, + { "-W", CC_OPTION_WARN, CC_OPTION_HAS_ARG }, { "-fno-leading-underscore", CC_OPTION_NO_LEADING_UNDERSCORE, CC_OPTION_NO_ARG }, { "-fleading-underscore", CC_OPTION_LEADING_UNDERSCORE, CC_OPTION_NO_ARG }, @@ -278,6 +280,7 @@ void parse_args (int argc, char **argv, int optind) { } + state->warn = WARN_DEFAULT; state->bits = 32; while (optind < argc) { @@ -542,6 +545,34 @@ void parse_args (int argc, char **argv, int optind) { } + case CC_OPTION_WARN: { + + if (strcmp (optarg, "all") == 0) { + + state->warn |= WARN_ALL; + break; + + } + + if (strcmp (optarg, "extra") == 0) { + + state->warn |= WARN_EXTRA; + break; + + } + + if (strcmp (optarg, "error") == 0) { + + state->warn |= WARN_ERROR; + break; + + } + + report_at (program_name, 0, REPORT_ERROR, "unrecognised -W argument"); + exit (EXIT_FAILURE); + + } + default: { report_at (program_name, 0, REPORT_ERROR, "unsupported option '%s'", r); diff --git a/macro.c b/macro.c index 4aa45fa..ea2addf 100755 --- a/macro.c +++ b/macro.c @@ -34,7 +34,7 @@ struct macro *get_macro (struct hashtab_name *key) { void add_macro (char *start, char **pp, int report_line) { - char *sname, *caret = *pp, *arg; + char *sname, *caret = *pp, *arg, *old_value = 0; unsigned int len; struct hashtab_name *key; @@ -90,14 +90,10 @@ void add_macro (char *start, char **pp, int report_line) { if ((key = find_macro (sname))) { - if (report_line) { - report_line_at (get_filename (), get_line_number (), REPORT_WARNING, start, caret, "\"%s\" redefined", sname); - } else { - report_at (get_filename (), get_line_number (), REPORT_WARNING, "\"%s\" redefined", sname); - } - if ((m = hashtab_get (&hashtab_macros, key))) { + old_value = xstrdup (m->value); + while ((arg = vec_pop (&m->args))) { free (arg); } @@ -238,15 +234,29 @@ void add_macro (char *start, char **pp, int report_line) { } - *pp = skip_whitespace (*pp); - - m->value = xstrdup (*pp); + m->value = xstrdup (*pp = skip_whitespace (*pp)); len = strlen (m->value); if (is_end_of_line[(int) m->value[len - 1]]) { m->value[len - 1] = '\0'; } + if (old_value) { + + if (strcmp (m->value, old_value) && state->warn & WARN_DUP_DEFINE) { + + if (report_line) { + report_line_at (get_filename (), get_line_number (), REPORT_WARNING, start, caret, "\"%s\" redefined", sname); + } else { + report_at (get_filename (), get_line_number (), REPORT_WARNING, "\"%s\" redefined", sname); + } + + } + + free (old_value); + + } + hashtab_put (&hashtab_macros, key, m); if (!m->is_variadic) { diff --git a/report.c b/report.c index 72ca4d1..950a061 100755 --- a/report.c +++ b/report.c @@ -64,6 +64,10 @@ extern void print_include_stack (void); static void output_message (const char *filename, unsigned long lineno, unsigned long idx, int type, const char *fmt, va_list ap) { + if (type == REPORT_WARNING && state && (state->warn & WARN_ERROR)) { + type = REPORT_ERROR; + } + if (has_include_stack ()) { print_include_stack (); }