From e1efe14d654d41f173deba5f0a425c94e6b2cff4 Mon Sep 17 00:00:00 2001 From: Robert Pengelly Date: Sun, 23 Aug 2026 12:53:21 +0100 Subject: [PATCH] Added initializer warnings --- amd64.c | 30 ++++++++++++++++++++++++++++-- i386.c | 30 ++++++++++++++++++++++++++++-- lib.c | 7 ++++--- 3 files changed, 60 insertions(+), 7 deletions(-) diff --git a/amd64.c b/amd64.c index 8c03d73..8294301 100644 --- a/amd64.c +++ b/amd64.c @@ -8490,12 +8490,16 @@ static void parse_local_aggregate_initializer_group (struct local_init *inits, i } -static void parse_local_aggregate_initializer_values (struct local_init *inits, int *init_count, int max_inits, long base_offset, const int *fields, int field_count) { +static int parse_local_aggregate_initializer_values (struct local_init *inits, int *init_count, int max_inits, long base_offset, const int *fields, int field_count) { + int initial_init_count = *init_count; + int provided_init_count; + int field_index = 0; long field_offset = 0; parse_local_aggregate_initializer_group (inits, init_count, max_inits, base_offset, fields, field_count, &field_index, &field_offset); + provided_init_count = *init_count - initial_init_count; while (field_index < field_count) { @@ -8513,6 +8517,8 @@ static void parse_local_aggregate_initializer_values (struct local_init *inits, field_index++; } + + return provided_init_count; } @@ -9131,7 +9137,16 @@ static void parse_block (void) { } } else if (object_is_auto && !declarator_is_pointer && (parsed_type_is_aggregate || declarator_has_array) && tok.kind == TOK_LBRACE) { - parse_local_aggregate_initializer_values (inits, &init_count, MAX_LOCAL_INITS, object_offset, object_fields, object_field_count); + + int first_init_index = init_count; + int provided_init_count = parse_local_aggregate_initializer_values (inits, &init_count, MAX_LOCAL_INITS, object_offset, object_fields, object_field_count); + int expected_init_count = aggregate_initializer_value_field_count (parsed_field_sizes, parsed_field_count); + int zero_initializer = provided_init_count == 1 && first_init_index < init_count && inits[first_init_index].kind == LOCAL_INIT_CONST && !inits[first_init_index].symbol && inits[first_init_index].value.low == 0 && inits[first_init_index].value.high == 0; + + if ((state->warn & WARN_INITIALIZER) && parsed_type_is_aggregate && !declarator_has_array && !zero_initializer && provided_init_count > 0 && provided_init_count < expected_init_count) { + report_line_at (get_filename (), name_line, REPORT_WARNING, name_start, name_caret, "missing initializer values for '%s'", name ? name : ""); + } + } else if (object_is_auto && auto_initializer_needs_runtime_now ()) { long needed_stack_bytes = align_up_long (current_local_stack_size - block_stack_start, 4); @@ -40091,6 +40106,17 @@ static void parse_external_after_type (void) { } + if ((state->warn & WARN_INITIALIZER) && parsed_type_is_aggregate && !decl_has_array && init_value_count > 0) { + + int expected_init_count = aggregate_initializer_value_field_count (parsed_field_sizes, parsed_field_count); + int zero_initializer = init_value_count == 1 && !init_symbols[0] && init_values[0].low == 0 && init_values[0].high == 0; + + if (!zero_initializer && init_value_count < expected_init_count) { + report_line_at (get_filename (), name_line, REPORT_WARNING, name_start, name_caret, "missing initializer values for '%s'", name ? name : ""); + } + + } + if (init_value_count > MAX_GLOBAL_INIT_FIELDS) { report_line_at (get_filename (), name_line, REPORT_ERROR, name_start, name_caret, "too many initializer values for '%s'", name ? name : ""); diff --git a/i386.c b/i386.c index b5f8d8e..9e7f6c1 100644 --- a/i386.c +++ b/i386.c @@ -7783,12 +7783,16 @@ static void parse_local_aggregate_initializer_group (struct local_init *inits, i } -static void parse_local_aggregate_initializer_values (struct local_init *inits, int *init_count, int max_inits, long base_offset, const int *fields, int field_count) { +static int parse_local_aggregate_initializer_values (struct local_init *inits, int *init_count, int max_inits, long base_offset, const int *fields, int field_count) { + int initial_init_count = *init_count; + int provided_init_count; + int field_index = 0; long field_offset = 0; parse_local_aggregate_initializer_group (inits, init_count, max_inits, base_offset, fields, field_count, &field_index, &field_offset); + provided_init_count = *init_count - initial_init_count; while (field_index < field_count) { @@ -7806,6 +7810,8 @@ static void parse_local_aggregate_initializer_values (struct local_init *inits, field_index++; } + + return provided_init_count; } @@ -8368,7 +8374,16 @@ static void parse_block (void) { } } else if (object_is_auto && !declarator_is_pointer && (parsed_type_is_aggregate || declarator_has_array) && tok.kind == TOK_LBRACE) { - parse_local_aggregate_initializer_values (inits, &init_count, MAX_LOCAL_INITS, object_offset, object_fields, object_field_count); + + int first_init_index = init_count; + int provided_init_count = parse_local_aggregate_initializer_values (inits, &init_count, MAX_LOCAL_INITS, object_offset, object_fields, object_field_count); + int expected_init_count = aggregate_initializer_value_field_count (parsed_field_sizes, parsed_field_count); + int zero_initializer = provided_init_count == 1 && first_init_index < init_count && inits[first_init_index].kind == LOCAL_INIT_CONST && !inits[first_init_index].symbol && inits[first_init_index].value.low == 0 && inits[first_init_index].value.high == 0; + + if ((state->warn & WARN_INITIALIZER) && parsed_type_is_aggregate && !declarator_has_array && !zero_initializer && provided_init_count > 0 && provided_init_count < expected_init_count) { + report_line_at (get_filename (), name_line, REPORT_WARNING, name_start, name_caret, "missing initializer values for '%s'", name ? name : ""); + } + } else if (object_is_auto && auto_initializer_needs_runtime_now ()) { long needed_stack_bytes = align_up_long (current_local_stack_size - block_stack_start, 4); @@ -37424,6 +37439,17 @@ static void parse_external_after_type (void) { } + if ((state->warn & WARN_INITIALIZER) && parsed_type_is_aggregate && !decl_has_array && init_value_count > 0) { + + int expected_init_count = aggregate_initializer_value_field_count (parsed_field_sizes, parsed_field_count); + int zero_initializer = init_value_count == 1 && !init_symbols[0] && init_values[0].low == 0 && init_values[0].high == 0; + + if (!zero_initializer && init_value_count < expected_init_count) { + report_line_at (get_filename (), name_line, REPORT_WARNING, name_start, name_caret, "missing initializer values for '%s'", name ? name : ""); + } + + } + if (init_value_count > MAX_GLOBAL_INIT_FIELDS) { report_line_at (get_filename (), name_line, REPORT_ERROR, name_start, name_caret, "too many initializer values for '%s'", name ? name : ""); diff --git a/lib.c b/lib.c index 7e79daf..3077aaa 100755 --- a/lib.c +++ b/lib.c @@ -141,9 +141,10 @@ static void print_usage (void) { fprintf (stderr, " -P Don't print linemarkers.\n"); fprintf (stderr, " -o OBJFILE Name the object-file output OBJFILE.\n"); fprintf (stderr, "\n"); - fprintf (stderr, " -Wall Enable most warning messages.\n"); - fprintf (stderr, " -Werror Treat all warnings as errors.\n"); - fprintf (stderr, " -Wextra Print extra (possibly unwanted) warnings.\n"); + fprintf (stderr, " -Wall Enable most warning messages.\n"); + fprintf (stderr, " -Werror Treat all warnings as errors.\n"); + fprintf (stderr, " -Wextra Print extra (possibly unwanted) warnings.\n"); + fprintf (stderr, " -Wshadow Warn when one variable shadows another.\n"); fprintf (stderr, "\n"); fprintf (stderr, " --traditional-linemarker-format Use #line instead of short form.\n"); -- 2.34.1