From 5a92d714be6a04a6322c67f47dfc859b16992e69 Mon Sep 17 00:00:00 2001 From: Robert Pengelly Date: Thu, 16 Jul 2026 09:03:38 +0100 Subject: [PATCH] Fixed local initialization --- amd64.c | 177 ++++++++++++++++++++++++++++++-------------------------- i386.c | 177 ++++++++++++++++++++++++++++++-------------------------- 2 files changed, 192 insertions(+), 162 deletions(-) diff --git a/amd64.c b/amd64.c index ca75b13..1463381 100644 --- a/amd64.c +++ b/amd64.c @@ -8313,12 +8313,28 @@ static void parse_local_string_field_initializer (struct local_init *inits, int } -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 void append_local_zero_initializer (struct local_init *inits, int *init_count, int max_inits, long offset, int size) { - int field_index = 0; - int braced = 0; + if (*init_count >= max_inits) { + return; + } - long field_offset = 0; + inits[*init_count].offset = offset; + inits[*init_count].size = size; + inits[*init_count].kind = LOCAL_INIT_CONST; + inits[*init_count].symbol = 0; + inits[*init_count].value.low = 0; + inits[*init_count].value.high = 0; + inits[*init_count].source_offset = 0; + inits[*init_count].source_size = 0; + + (*init_count)++; + +} + +static void parse_local_aggregate_initializer_group (struct local_init *inits, int *init_count, int max_inits, long base_offset, const int *fields, int field_count, int *field_index, long *field_offset) { + + int braced = 0; if (tok.kind == TOK_LBRACE) { @@ -8327,115 +8343,87 @@ static void parse_local_aggregate_initializer_values (struct local_init *inits, } - while (field_index < field_count) { + while (*field_index < field_count) { - int field_size = fields[field_index]; + int field_size; - if (field_size < 0) { + while (*field_index < field_count && fields[*field_index] < 0) { - field_offset += -field_size; - - field_index++; - continue; + *field_offset += -fields[*field_index]; + (*field_index)++; } + if (*field_index >= field_count) { + break; + } + if (braced && tok.kind == TOK_RBRACE) { + get_token (); + return; + + } + + field_size = fields[*field_index]; + + if (tok.kind == TOK_LBRACE) { + parse_local_aggregate_initializer_group (inits, init_count, max_inits, base_offset, fields, field_count, field_index, field_offset); + } else { + if (*init_count < max_inits) { - inits[*init_count].offset = base_offset + field_offset; - inits[*init_count].size = field_size; - inits[*init_count].kind = LOCAL_INIT_CONST; - inits[*init_count].symbol = 0; - inits[*init_count].value.low = 0; - inits[*init_count].value.high = 0; - inits[*init_count].source_offset = 0; - inits[*init_count].source_size = 0; + if (is_string_token ()) { + parse_local_string_field_initializer (inits, init_count, max_inits, base_offset + *field_offset, field_size); + } else { - (*init_count)++; + inits[*init_count].offset = base_offset + *field_offset; + inits[*init_count].size = field_size; + + parse_local_initializer_value (&inits[*init_count], 0, 0); + (*init_count)++; + + } + } else { + skip_initializer (); } - field_offset += field_size; - field_index++; - - continue; + *field_offset += field_size; + (*field_index)++; } - if (*init_count < max_inits) { + if (!braced) { + return; + } - if (is_string_token ()) { - parse_local_string_field_initializer (inits, init_count, max_inits, base_offset + field_offset, field_size); - } else { + if (_accept (TOK_COMMA)) { + + if (tok.kind == TOK_RBRACE) { - inits[*init_count].offset = base_offset + field_offset; - inits[*init_count].size = field_size; - - parse_local_initializer_value (&inits[*init_count], 0, 0); - (*init_count)++; + get_token (); + return; } + + continue; - } else { - skip_initializer (); } - field_offset += field_size; - field_index++; - - if (braced) { + if (tok.kind == TOK_RBRACE) { - if (!_accept (TOK_COMMA)) { - break; - } - - if (tok.kind == TOK_RBRACE) { - break; - } + get_token (); + return; - } else { - break; } + + break; } if (braced) { - while (field_index < field_count) { - - int field_size = fields[field_index]; - - if (field_size < 0) { - - field_offset += -field_size; - - field_index++; - continue; - - } - - if (*init_count < max_inits) { - - inits[*init_count].offset = base_offset + field_offset; - inits[*init_count].size = field_size; - inits[*init_count].kind = LOCAL_INIT_CONST; - inits[*init_count].symbol = 0; - inits[*init_count].value.low = 0; - inits[*init_count].value.high = 0; - inits[*init_count].source_offset = 0; - inits[*init_count].source_size = 0; - - (*init_count)++; - - } - - field_offset += field_size; - field_index++; - - } - while (tok.kind != TOK_EOF && tok.kind != TOK_RBRACE) { skip_initializer (); @@ -8443,6 +8431,7 @@ static void parse_local_aggregate_initializer_values (struct local_init *inits, if (!_accept (TOK_COMMA)) { break; } + } expect (TOK_RBRACE, "}"); @@ -8451,6 +8440,32 @@ static void parse_local_aggregate_initializer_values (struct local_init *inits, } +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) { + + 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); + + while (field_index < field_count) { + + int field_size = fields[field_index]; + + if (field_size < 0) { + field_offset += -field_size; + } else { + + append_local_zero_initializer (inits, init_count, max_inits, base_offset + field_offset, field_size); + field_offset += field_size; + + } + + field_index++; + + } + +} + static void make_local_static_label (char *buf, size_t bufsz, const char *name) { if (!buf || bufsz == 0) { diff --git a/i386.c b/i386.c index 67e82f9..723d02b 100644 --- a/i386.c +++ b/i386.c @@ -7529,12 +7529,28 @@ static void parse_local_string_field_initializer (struct local_init *inits, int } -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 void append_local_zero_initializer (struct local_init *inits, int *init_count, int max_inits, long offset, int size) { - int field_index = 0; - int braced = 0; + if (*init_count >= max_inits) { + return; + } - long field_offset = 0; + inits[*init_count].offset = offset; + inits[*init_count].size = size; + inits[*init_count].kind = LOCAL_INIT_CONST; + inits[*init_count].symbol = 0; + inits[*init_count].value.low = 0; + inits[*init_count].value.high = 0; + inits[*init_count].source_offset = 0; + inits[*init_count].source_size = 0; + + (*init_count)++; + +} + +static void parse_local_aggregate_initializer_group (struct local_init *inits, int *init_count, int max_inits, long base_offset, const int *fields, int field_count, int *field_index, long *field_offset) { + + int braced = 0; if (tok.kind == TOK_LBRACE) { @@ -7543,115 +7559,87 @@ static void parse_local_aggregate_initializer_values (struct local_init *inits, } - while (field_index < field_count) { + while (*field_index < field_count) { - int field_size = fields[field_index]; + int field_size; - if (field_size < 0) { + while (*field_index < field_count && fields[*field_index] < 0) { - field_offset += -field_size; - - field_index++; - continue; + *field_offset += -fields[*field_index]; + (*field_index)++; } + if (*field_index >= field_count) { + break; + } + if (braced && tok.kind == TOK_RBRACE) { + get_token (); + return; + + } + + field_size = fields[*field_index]; + + if (tok.kind == TOK_LBRACE) { + parse_local_aggregate_initializer_group (inits, init_count, max_inits, base_offset, fields, field_count, field_index, field_offset); + } else { + if (*init_count < max_inits) { - inits[*init_count].offset = base_offset + field_offset; - inits[*init_count].size = field_size; - inits[*init_count].kind = LOCAL_INIT_CONST; - inits[*init_count].symbol = 0; - inits[*init_count].value.low = 0; - inits[*init_count].value.high = 0; - inits[*init_count].source_offset = 0; - inits[*init_count].source_size = 0; + if (is_string_token ()) { + parse_local_string_field_initializer (inits, init_count, max_inits, base_offset + *field_offset, field_size); + } else { - (*init_count)++; + inits[*init_count].offset = base_offset + *field_offset; + inits[*init_count].size = field_size; + + parse_local_initializer_value (&inits[*init_count], 0, 0); + (*init_count)++; + + } + } else { + skip_initializer (); } - field_offset += field_size; - field_index++; - - continue; + *field_offset += field_size; + (*field_index)++; } - if (*init_count < max_inits) { + if (!braced) { + return; + } - if (is_string_token ()) { - parse_local_string_field_initializer (inits, init_count, max_inits, base_offset + field_offset, field_size); - } else { + if (_accept (TOK_COMMA)) { + + if (tok.kind == TOK_RBRACE) { - inits[*init_count].offset = base_offset + field_offset; - inits[*init_count].size = field_size; - - parse_local_initializer_value (&inits[*init_count], 0, 0); - (*init_count)++; + get_token (); + return; } + + continue; - } else { - skip_initializer (); } - field_offset += field_size; - field_index++; - - if (braced) { + if (tok.kind == TOK_RBRACE) { - if (!_accept (TOK_COMMA)) { - break; - } - - if (tok.kind == TOK_RBRACE) { - break; - } + get_token (); + return; - } else { - break; } + + break; } if (braced) { - while (field_index < field_count) { - - int field_size = fields[field_index]; - - if (field_size < 0) { - - field_offset += -field_size; - - field_index++; - continue; - - } - - if (*init_count < max_inits) { - - inits[*init_count].offset = base_offset + field_offset; - inits[*init_count].size = field_size; - inits[*init_count].kind = LOCAL_INIT_CONST; - inits[*init_count].symbol = 0; - inits[*init_count].value.low = 0; - inits[*init_count].value.high = 0; - inits[*init_count].source_offset = 0; - inits[*init_count].source_size = 0; - - (*init_count)++; - - } - - field_offset += field_size; - field_index++; - - } - while (tok.kind != TOK_EOF && tok.kind != TOK_RBRACE) { skip_initializer (); @@ -7659,6 +7647,7 @@ static void parse_local_aggregate_initializer_values (struct local_init *inits, if (!_accept (TOK_COMMA)) { break; } + } expect (TOK_RBRACE, "}"); @@ -7667,6 +7656,32 @@ static void parse_local_aggregate_initializer_values (struct local_init *inits, } +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) { + + 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); + + while (field_index < field_count) { + + int field_size = fields[field_index]; + + if (field_size < 0) { + field_offset += -field_size; + } else { + + append_local_zero_initializer (inits, init_count, max_inits, base_offset + field_offset, field_size); + field_offset += field_size; + + } + + field_index++; + + } + +} + static void make_local_static_label (char *buf, size_t bufsz, const char *name) { if (!buf || bufsz == 0) { -- 2.34.1