From: Robert Pengelly Date: Thu, 21 May 2026 21:42:42 +0000 (+0100) Subject: 64-bit fix X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=aff2d944de0f69dc3105f3e37ed42e83b3a57c76;p=scc.git 64-bit fix --- diff --git a/parse.c b/parse.c index a3200bd..d6b67fb 100644 --- a/parse.c +++ b/parse.c @@ -6375,9 +6375,12 @@ static int parse_deref_cast_type_name (int *out_size) { parse_declarator (&name); - if (declarator_is_pointer) { - size = DATA_PTR; - } + /* + * This parser is called after a leading unary '*', for forms such + * as *(long long *)p. The '*' outside the cast performs the + * dereference, so the size needed by the caller is the pointed-at + * object size, not DATA_PTR. + */ } @@ -12480,6 +12483,11 @@ static void emit_copy_reg_now (const char *dst, const char *src) { } +static void emit_load_assignment_rhs_to_reg (const char *reg); + +static int expression_text_has_pluseq_before_delim_now (const char *p); +static int emit_parse_va_arg_address_to_reg_now (const char *reg, int size); + static void emit_load_assignment_rhs_to_pair (const char *lo, const char *hi) { if (_accept (TOK_LPAREN)) { @@ -12692,6 +12700,51 @@ static void emit_load_assignment_rhs_to_pair (const char *lo, const char *hi) { name_caret = tok.caret; name_line = get_line_number (); + if (tok.kind == TOK_LPAREN) { + + int cast_deref_size = DATA_INT & 0x1f; + + const char *addr_reg = (strcmp (lo, "ecx") != 0 && strcmp (hi, "ecx") != 0) ? "ecx" : "esi"; + int handled_va_arg = 0; + + get_token (); + + if (is_type_start (tok.kind) && parse_deref_cast_type_name (&cast_deref_size)) { + + if (expression_text_has_pluseq_before_delim_now (tok.start)) { + handled_va_arg = emit_parse_va_arg_address_to_reg_now (lo, cast_deref_size); + } + + if (!handled_va_arg) { + emit_load_assignment_rhs_to_reg (lo); + } + + if ((cast_deref_size & 0x1f) == (DATA_LLONG & 0x1f)) { + + emit_copy_reg_now (addr_reg, lo); + emit_load_pair_from_deref_reg_now (lo, hi, addr_reg); + + } else { + + emit_load_deref_reg_now (lo, cast_deref_size); + emit_extend_pair_high_from_low (lo, hi, cast_deref_size, 1); + + } + + return; + + } + + emit_load_assignment_rhs_expression_to_reg (lo); + expect (TOK_RPAREN, ")"); + + emit_load_deref_reg_now (lo, DATA_INT & 0x1f); + emit_extend_pair_high_from_low (lo, hi, DATA_INT & 0x1f, 1); + + return; + + } + if (tok.kind != TOK_IDENT || !tok.ident) { int64_s zero; @@ -16276,8 +16329,6 @@ static int emit_parse_postfix_copy_source_address_now (const char *reg, struct l } -static void emit_load_assignment_rhs_to_reg (const char *reg); - static void emit_load_floating_deref_reg_now (const char *reg, int size) { if (!state->ofp) {