From a8a5c074709158e43c4bd8ed2b284be203a4eb1f Mon Sep 17 00:00:00 2001 From: Robert Pengelly Date: Sun, 23 Aug 2026 12:43:06 +0100 Subject: [PATCH] Added fallthrough warnings --- amd64.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- i386.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- token.c | 3 +-- 3 files changed, 142 insertions(+), 4 deletions(-) diff --git a/amd64.c b/amd64.c index a455731..8c03d73 100644 --- a/amd64.c +++ b/amd64.c @@ -96,6 +96,14 @@ static void clear_rhs_last_pointer_info (void) { } +#define MAX_FALLTHROUGH_SWITCH_DEPTH 32 + +static int fallthrough_switch_depth = 0; +static int fallthrough_case_active[MAX_FALLTHROUGH_SWITCH_DEPTH]; +static int fallthrough_case_has_statement[MAX_FALLTHROUGH_SWITCH_DEPTH]; + +static int fallthrough_case_ends_control_flow[MAX_FALLTHROUGH_SWITCH_DEPTH]; + static int current_function_has_return_statement = 0; static int statement_ends_control_flow = 0; @@ -9304,6 +9312,13 @@ static void parse_block (void) { ensure_block_stack_allocated (block_stack_start, &block_stack_bytes, &block_stack_emitted); } + if (fallthrough_switch_depth > 0 && fallthrough_case_active[fallthrough_switch_depth - 1]) { + + fallthrough_case_has_statement[fallthrough_switch_depth - 1] = 1; + fallthrough_case_ends_control_flow[fallthrough_switch_depth - 1] = 0; + + } + continue; } @@ -9370,7 +9385,19 @@ static void parse_block (void) { } - parse_statement (); + { + + enum token_kind statement_kind = tok.kind; + parse_statement (); + + if (fallthrough_switch_depth > 0 && statement_kind != TOK_CASE && statement_kind != TOK_DEFAULT && fallthrough_case_active[fallthrough_switch_depth - 1]) { + + fallthrough_case_has_statement[fallthrough_switch_depth - 1] = 1; + fallthrough_case_ends_control_flow[fallthrough_switch_depth - 1] = statement_ends_control_flow; + + } + + } if (statement_ends_control_flow) { block_ends_control_flow = 1; @@ -27096,6 +27123,7 @@ static void parse_switch_statement (void) { long old_break_cleanup_base; long old_continue_cleanup_base; + int fallthrough_tracking_pushed = 0; int saved_ends_control_flow; FILE *saved_ofp; @@ -27141,9 +27169,23 @@ static void parse_switch_statement (void) { } + if (fallthrough_switch_depth < MAX_FALLTHROUGH_SWITCH_DEPTH) { + + fallthrough_case_active[fallthrough_switch_depth] = 0; + fallthrough_case_has_statement[fallthrough_switch_depth] = 0; + fallthrough_case_ends_control_flow[fallthrough_switch_depth] = 0; + fallthrough_switch_depth++; + fallthrough_tracking_pushed = 1; + + } + parse_statement (); saved_ends_control_flow = statement_ends_control_flow; + if (fallthrough_tracking_pushed) { + fallthrough_switch_depth--; + } + if (body_tmp) { body_text = read_tmp_file_text (body_tmp); @@ -37984,6 +38026,20 @@ static void parse_statement (void) { const char *case_start = tok.start; const char *case_caret = tok.caret; + if (fallthrough_switch_depth > 0) { + + int fall_index = fallthrough_switch_depth - 1; + + if ((state->warn & WARN_FALLTHROUGH) && fallthrough_case_active[fall_index] && fallthrough_case_has_statement[fall_index] && !fallthrough_case_ends_control_flow[fall_index]) { + report_line_at (get_filename (), case_line, REPORT_WARNING, case_start, case_caret, "this case may be reached by fallthrough"); + } + + fallthrough_case_active[fall_index] = 1; + fallthrough_case_has_statement[fall_index] = 0; + fallthrough_case_ends_control_flow[fall_index] = 0; + + } + get_token (); value = const_from_current_case_expr (); @@ -38007,6 +38063,20 @@ static void parse_statement (void) { const char *default_start = tok.start; const char *default_caret = tok.caret; + if (fallthrough_switch_depth > 0) { + + int fall_index = fallthrough_switch_depth - 1; + + if ((state->warn & WARN_FALLTHROUGH) && fallthrough_case_active[fall_index] && fallthrough_case_has_statement[fall_index] && !fallthrough_case_ends_control_flow[fall_index]) { + report_line_at (get_filename (), default_line, REPORT_WARNING, default_start, default_caret, "this case may be reached by fallthrough"); + } + + fallthrough_case_active[fall_index] = 1; + fallthrough_case_has_statement[fall_index] = 0; + fallthrough_case_ends_control_flow[fall_index] = 0; + + } + get_token (); set_switch_default_label (default_line, default_start, default_caret); diff --git a/i386.c b/i386.c index 096d5e6..b5f8d8e 100644 --- a/i386.c +++ b/i386.c @@ -69,6 +69,13 @@ static void clear_rhs_last_pointer_info (void) { } +#define MAX_FALLTHROUGH_SWITCH_DEPTH 32 + +static int fallthrough_switch_depth = 0; +static int fallthrough_case_active[MAX_FALLTHROUGH_SWITCH_DEPTH]; +static int fallthrough_case_has_statement[MAX_FALLTHROUGH_SWITCH_DEPTH]; +static int fallthrough_case_ends_control_flow[MAX_FALLTHROUGH_SWITCH_DEPTH]; + static int current_function_has_return_statement = 0; static int statement_ends_control_flow = 0; @@ -8545,6 +8552,13 @@ static void parse_block (void) { ensure_block_stack_allocated (block_stack_start, &block_stack_bytes, &block_stack_emitted); } + if (fallthrough_switch_depth > 0 && fallthrough_case_active[fallthrough_switch_depth - 1]) { + + fallthrough_case_has_statement[fallthrough_switch_depth - 1] = 1; + fallthrough_case_ends_control_flow[fallthrough_switch_depth - 1] = 0; + + } + continue; } @@ -8611,7 +8625,19 @@ static void parse_block (void) { } - parse_statement (); + { + + enum token_kind statement_kind = tok.kind; + parse_statement (); + + if (fallthrough_switch_depth > 0 && statement_kind != TOK_CASE && statement_kind != TOK_DEFAULT && fallthrough_case_active[fallthrough_switch_depth - 1]) { + + fallthrough_case_has_statement[fallthrough_switch_depth - 1] = 1; + fallthrough_case_ends_control_flow[fallthrough_switch_depth - 1] = statement_ends_control_flow; + + } + + } if (statement_ends_control_flow) { block_ends_control_flow = 1; @@ -24222,6 +24248,7 @@ static void parse_switch_statement (void) { long old_break_cleanup_base; long old_continue_cleanup_base; + int fallthrough_tracking_pushed = 0; int saved_ends_control_flow; FILE *saved_ofp; @@ -24267,9 +24294,23 @@ static void parse_switch_statement (void) { } + if (fallthrough_switch_depth < MAX_FALLTHROUGH_SWITCH_DEPTH) { + + fallthrough_case_active[fallthrough_switch_depth] = 0; + fallthrough_case_has_statement[fallthrough_switch_depth] = 0; + fallthrough_case_ends_control_flow[fallthrough_switch_depth] = 0; + fallthrough_switch_depth++; + fallthrough_tracking_pushed = 1; + + } + parse_statement (); saved_ends_control_flow = statement_ends_control_flow; + if (fallthrough_tracking_pushed) { + fallthrough_switch_depth--; + } + if (body_tmp) { body_text = read_tmp_file_text (body_tmp); @@ -35432,6 +35473,20 @@ static void parse_statement (void) { const char *case_start = tok.start; const char *case_caret = tok.caret; + if (fallthrough_switch_depth > 0) { + + int fall_index = fallthrough_switch_depth - 1; + + if ((state->warn & WARN_FALLTHROUGH) && fallthrough_case_active[fall_index] && fallthrough_case_has_statement[fall_index] && !fallthrough_case_ends_control_flow[fall_index]) { + report_line_at (get_filename (), case_line, REPORT_WARNING, case_start, case_caret, "this case may be reached by fallthrough"); + } + + fallthrough_case_active[fall_index] = 1; + fallthrough_case_has_statement[fall_index] = 0; + fallthrough_case_ends_control_flow[fall_index] = 0; + + } + get_token (); value = const_from_current_case_expr (); @@ -35455,6 +35510,20 @@ static void parse_statement (void) { const char *default_start = tok.start; const char *default_caret = tok.caret; + if (fallthrough_switch_depth > 0) { + + int fall_index = fallthrough_switch_depth - 1; + + if ((state->warn & WARN_FALLTHROUGH) && fallthrough_case_active[fall_index] && fallthrough_case_has_statement[fall_index] && !fallthrough_case_ends_control_flow[fall_index]) { + report_line_at (get_filename (), default_line, REPORT_WARNING, default_start, default_caret, "this case may be reached by fallthrough"); + } + + fallthrough_case_active[fall_index] = 1; + fallthrough_case_has_statement[fall_index] = 0; + fallthrough_case_ends_control_flow[fall_index] = 0; + + } + get_token (); set_switch_default_label (default_line, default_start, default_caret); diff --git a/token.c b/token.c index e5f01a1..aa0ca17 100755 --- a/token.c +++ b/token.c @@ -2087,10 +2087,9 @@ void get_token (void) { if (!get_line ()) { - free ((char *) get_filename ()); - if ((history = vec_pop (&vec_history))) { + free ((char *) get_filename ()); state->ifp = history->ifp; new_line_number = history->new_line_number; -- 2.34.1