Fixed address constant initializers for integer types
authorRobert Pengelly <robertapengelly@hotmail.com>
Tue, 8 Sep 2026 08:00:15 +0000 (09:00 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Tue, 8 Sep 2026 08:00:15 +0000 (09:00 +0100)
amd64.c
i386.c

diff --git a/amd64.c b/amd64.c
index e18515a19b8cdd7f585479365129eb12b83df046..9f458fdd26a2cd72381168d9554d5211c569de92 100644 (file)
--- 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 91a2e8b24f9383f5bab412f02d971164253e25d5..ec78cdbf6388117f92177cc136f5b5d88222a7a4 100644 (file)
--- 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));