From: Robert Pengelly Date: Tue, 8 Sep 2026 08:00:15 +0000 (+0100) Subject: Fixed address constant initializers for integer types X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=7f4ac661d852900bd789479f2215f9afe1dadfd3;p=scc.git Fixed address constant initializers for integer types --- diff --git a/amd64.c b/amd64.c index e18515a..9f458fd 100644 --- a/amd64.c +++ b/amd64.c @@ -8763,6 +8763,7 @@ static void ensure_block_stack_allocated (long block_stack_start, long *block_st } +static int global_initializer_cast_before_address_now (void); static void parse_global_initializer_values (int64_s *values, char **symbols, int max_values, int *count); static int aggregate_initializer_value_field_count (const int *field_sizes, int field_count); @@ -9086,7 +9087,7 @@ static void parse_block (void) { { int saved_accept_symbol_addresses = global_initializer_accept_symbol_addresses; - global_initializer_accept_symbol_addresses = declarator_is_pointer || parsed_type_is_aggregate || declarator_has_array; + global_initializer_accept_symbol_addresses = declarator_is_pointer || parsed_type_is_aggregate || declarator_has_array || global_initializer_cast_before_address_now (); if (declarator_has_array && !declarator_is_pointer && parsed_type_is_aggregate && parsed_field_count > 0 && tok.kind == TOK_LBRACE) { parse_global_initializer_values_padded_elements (init_values, init_symbols, MAX_AGG_FIELDS, &init_value_count, aggregate_initializer_value_field_count (parsed_field_sizes, parsed_field_count)); @@ -39514,10 +39515,56 @@ static int global_initializer_cast_before_symbol_now (void) { p++; } + if (*p == '&') { + + p++; + + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + p++; + } + + } + return ident_start_now ((unsigned char) *p); } +static int global_initializer_cast_before_address_now (void) { + + const char *p = tok.caret; + int depth; + + if (!p || *p != '(') { + return 0; + } + + p++; + depth = 1; + + while (*p && depth > 0) { + + if (*p == '(') { + depth++; + } else if (*p == ')') { + depth--; + } + + p++; + + } + + if (depth != 0) { + return 0; + } + + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + p++; + } + + return *p == '&'; + +} + static void append_global_zero_initializer_value (int64_s *values, char **symbols, int max_values, int *count) { if (*count < max_values) { @@ -39690,23 +39737,31 @@ static void parse_global_initializer_values (int64_s *values, char **symbols, in if (!token_starts_type_name () || !parse_cast_type_name (&cast_size, &cast_is_unsigned, &cast_is_pointer)) { report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "invalid cast in global initializer"); - } else if (tok.kind != TOK_IDENT || find_global_symbol (tok.ident) < 0) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "global symbol expected after cast"); } else { - if (*count < max_values) { + if (tok.kind == TOK_AMPER) { + get_token (); + } - values[*count].low = 0; - values[*count].high = 0; + if (tok.kind != TOK_IDENT || find_global_symbol (tok.ident) < 0) { + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "global symbol expected after cast"); + } else { + + if (*count < max_values) { + + values[*count].low = 0; + values[*count].high = 0; + + if (symbols) { + symbols[*count] = xstrdup (tok.ident); + } - if (symbols) { - symbols[*count] = xstrdup (tok.ident); } + + (*count)++; + get_token (); } - - (*count)++; - get_token (); } @@ -40813,7 +40868,7 @@ static void parse_external_after_type (void) { { int saved_accept_symbol_addresses = global_initializer_accept_symbol_addresses; - global_initializer_accept_symbol_addresses = declarator_is_pointer || declarator_has_function || parsed_type_is_aggregate || declarator_has_array; + global_initializer_accept_symbol_addresses = declarator_is_pointer || declarator_has_function || parsed_type_is_aggregate || declarator_has_array || global_initializer_cast_before_address_now (); if (declarator_has_array && !declarator_is_pointer && parsed_type_is_aggregate && parsed_field_count > 0 && tok.kind == TOK_LBRACE) { parse_global_initializer_values_padded_elements (init_values, init_symbols, MAX_GLOBAL_INIT_FIELDS, &init_value_count, aggregate_initializer_value_field_count (parsed_field_sizes, parsed_field_count)); diff --git a/i386.c b/i386.c index 91a2e8b..ec78cdb 100644 --- a/i386.c +++ b/i386.c @@ -7966,6 +7966,8 @@ static int token_identifier_is_label_now (void) { } +static int global_initializer_cast_before_address_now (void); + static void parse_block (void) { int declaration_phase = 1, is_function_body = (current_parse_block_depth == 0); @@ -8237,7 +8239,7 @@ static void parse_block (void) { { int saved_accept_symbol_addresses = global_initializer_accept_symbol_addresses; - global_initializer_accept_symbol_addresses = declarator_is_pointer || parsed_type_is_aggregate || declarator_has_array; + global_initializer_accept_symbol_addresses = declarator_is_pointer || parsed_type_is_aggregate || declarator_has_array || global_initializer_cast_before_address_now (); if (declarator_has_array && !declarator_is_pointer && parsed_type_is_aggregate && parsed_field_count > 0 && tok.kind == TOK_LBRACE) { parse_global_initializer_values_padded_elements (init_values, init_symbols, MAX_AGG_FIELDS, &init_value_count, aggregate_initializer_value_field_count (parsed_field_sizes, parsed_field_count)); @@ -37029,10 +37031,56 @@ static int global_initializer_cast_before_symbol_now (void) { p++; } + if (*p == '&') { + + p++; + + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + p++; + } + + } + return ident_start_now ((unsigned char) *p); } +static int global_initializer_cast_before_address_now (void) { + + const char *p = tok.caret; + int depth; + + if (!p || *p != '(') { + return 0; + } + + p++; + depth = 1; + + while (*p && depth > 0) { + + if (*p == '(') { + depth++; + } else if (*p == ')') { + depth--; + } + + p++; + + } + + if (depth != 0) { + return 0; + } + + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + p++; + } + + return *p == '&'; + +} + static void append_global_zero_initializer_value (int64_s *values, char **symbols, int max_values, int *count) { if (*count < max_values) { @@ -37205,23 +37253,31 @@ static void parse_global_initializer_values (int64_s *values, char **symbols, in if (!token_starts_type_name () || !parse_cast_type_name (&cast_size, &cast_is_unsigned, &cast_is_pointer)) { report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "invalid cast in global initializer"); - } else if (tok.kind != TOK_IDENT || find_global_symbol (tok.ident) < 0) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "global symbol expected after cast"); } else { - if (*count < max_values) { + if (tok.kind == TOK_AMPER) { + get_token (); + } - values[*count].low = 0; - values[*count].high = 0; + if (tok.kind != TOK_IDENT || find_global_symbol (tok.ident) < 0) { + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "global symbol expected after cast"); + } else { + + if (*count < max_values) { + + values[*count].low = 0; + values[*count].high = 0; + + if (symbols) { + symbols[*count] = xstrdup (tok.ident); + } - if (symbols) { - symbols[*count] = xstrdup (tok.ident); } + + (*count)++; + get_token (); } - - (*count)++; - get_token (); } @@ -38242,7 +38298,7 @@ static void parse_external_after_type (void) { { int saved_accept_symbol_addresses = global_initializer_accept_symbol_addresses; - global_initializer_accept_symbol_addresses = declarator_is_pointer || declarator_has_function || parsed_type_is_aggregate || declarator_has_array; + global_initializer_accept_symbol_addresses = declarator_is_pointer || declarator_has_function || parsed_type_is_aggregate || declarator_has_array || global_initializer_cast_before_address_now (); if (declarator_has_array && !declarator_is_pointer && parsed_type_is_aggregate && parsed_field_count > 0 && tok.kind == TOK_LBRACE) { parse_global_initializer_values_padded_elements (init_values, init_symbols, MAX_GLOBAL_INIT_FIELDS, &init_value_count, aggregate_initializer_value_field_count (parsed_field_sizes, parsed_field_count));