Fixed floating-point dereference in va_arg expressions
authorRobert Pengelly <robertapengelly@hotmail.com>
Sat, 22 Aug 2026 16:37:50 +0000 (17:37 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Sat, 22 Aug 2026 16:37:50 +0000 (17:37 +0100)
amd64.c
i386.c

diff --git a/amd64.c b/amd64.c
index 2c6572f6cfe9cad0e0899f74b898d70619775b25..881406cfc115b2b7d2dbccf29daabae21a2d4b13 100644 (file)
--- a/amd64.c
+++ b/amd64.c
@@ -22756,6 +22756,15 @@ static void emit_load_floating_rhs_operand_now (int result_size) {
             
             if (is_type_start (tok.kind) && parse_deref_cast_type_name (&deref_size)) {
             
+                /*
+                 * parse_deref_cast_type_name() consumes only the cast in
+                 * *(type *)expr.  The following expression still has to be
+                 * evaluated to obtain the address before loading through it.
+                 * This is especially important for va_arg(), whose expansion
+                 * uses a parenthesized comma expression here.
+                 */
+                emit_load_assignment_rhs_to_reg ("rax");
+                
                 emit_load_any_deref_as_floating_now ("rax", deref_size, last_deref_cast_type_is_floating);
                 return;
             
diff --git a/i386.c b/i386.c
index 76086a68b71a1f9b546ff88775c3c1065dbbf0e9..4d28806833c786ba27c5ed9e717d17597e064ac5 100644 (file)
--- a/i386.c
+++ b/i386.c
@@ -21491,6 +21491,15 @@ static void emit_load_floating_rhs_operand_now (int result_size) {
             
             if (is_type_start (tok.kind) && parse_deref_cast_type_name (&deref_size)) {
             
+                /*
+                 * parse_deref_cast_type_name() consumes only the cast in
+                 * *(type *)expr.  The following expression still has to be
+                 * evaluated to obtain the address before loading through it.
+                 * This is especially important for va_arg(), whose expansion
+                 * uses a parenthesized comma expression here.
+                 */
+                emit_load_assignment_rhs_to_reg ("eax");
+                
                 emit_load_any_deref_as_floating_now ("eax", deref_size, last_deref_cast_type_is_floating);
                 return;