From 9bd782b2abfe11d506a31292d2d94331637a3992 Mon Sep 17 00:00:00 2001 From: "Vladimir N. Makarov" Date: Tue, 8 Aug 2023 11:48:25 -0400 Subject: [PATCH] Implement va block arg without result: Process NULL res in va_block_arg_builtin for all targets. Process null desirable_dest for va_arg in gen. Add new test issue361.c. --- c-tests/new/issue361.c | 17 +++++++++++++++++ c2mir/c2mir.c | 12 +++++++++--- mir-aarch64.c | 6 +++--- mir-ppc64.c | 2 +- mir-riscv64.c | 2 +- mir-s390x.c | 3 ++- mir-x86_64.c | 10 +++++----- 7 files changed, 38 insertions(+), 14 deletions(-) create mode 100644 c-tests/new/issue361.c diff --git a/c-tests/new/issue361.c b/c-tests/new/issue361.c new file mode 100644 index 0000000000..74add2b0c6 --- /dev/null +++ b/c-tests/new/issue361.c @@ -0,0 +1,17 @@ +#include +struct car { + char a; + long d; +}; + +o (int n, ...) { + struct car c0, c; + va_list args; + va_arg (args, struct car); + int n0; + c = va_arg (args, struct car); + int n2 = (args); + return 0; +} + +int main (void) { return 0; } diff --git a/c2mir/c2mir.c b/c2mir/c2mir.c index 75e381c2f9..64f9ac3ea0 100644 --- a/c2mir/c2mir.c +++ b/c2mir/c2mir.c @@ -12809,14 +12809,20 @@ static op_t gen (c2m_ctx_t c2m_ctx, node_t r, MIR_label_t true_label, MIR_label_ op2 = mem_to_address (c2m_ctx, op2, FALSE); } if (type->mode == TM_STRUCT || type->mode == TM_UNION) { - assert (desirable_dest != NULL && desirable_dest->mir_op.mode == MIR_OP_MEM); - res = mem_to_address (c2m_ctx, *desirable_dest, TRUE); + if (desirable_dest == NULL) { + res = get_new_temp (c2m_ctx, MIR_T_I64); + MIR_append_insn (ctx, curr_func, + MIR_new_insn (ctx, MIR_MOV, res.mir_op, MIR_new_int_op (ctx, 0))); + } else { + assert (desirable_dest->mir_op.mode == MIR_OP_MEM); + res = mem_to_address (c2m_ctx, *desirable_dest, TRUE); + } MIR_append_insn (ctx, curr_func, MIR_new_insn (ctx, MIR_VA_BLOCK_ARG, res.mir_op, op2.mir_op, MIR_new_int_op (ctx, type_size (c2m_ctx, type)), MIR_new_int_op (ctx, target_get_blk_type (c2m_ctx, type) - MIR_T_BLK))); - res = *desirable_dest; + if (desirable_dest != NULL) res = *desirable_dest; } else { MIR_append_insn (ctx, curr_func, MIR_new_insn (ctx, MIR_VA_ARG, op1.mir_op, op2.mir_op, diff --git a/mir-aarch64.c b/mir-aarch64.c index 15f5626d9f..594af6e314 100644 --- a/mir-aarch64.c +++ b/mir-aarch64.c @@ -110,7 +110,7 @@ void va_block_arg_builtin (void *res, void *p, size_t s, uint64_t ncase MIR_UNUS a = *(void **) a; va->arg_area++; } - memcpy (res, a, s); + if (res != NULL) memcpy (res, a, s); #else void *a; long size = (s + 7) / 8 * 8; @@ -119,7 +119,7 @@ void va_block_arg_builtin (void *res, void *p, size_t s, uint64_t ncase MIR_UNUS a = va->__stack; va->__stack = (char *) va->__stack + size; va->__gr_offs += size; - memcpy (res, a, s); + if (res != NULL) memcpy (res, a, s); return; } if (size > 2 * 8) size = 8; @@ -131,7 +131,7 @@ void va_block_arg_builtin (void *res, void *p, size_t s, uint64_t ncase MIR_UNUS va->__stack = (char *) va->__stack + size; } if (s > 2 * 8) a = *(void **) a; /* address */ - memcpy (res, a, s); + if (res != NULL) memcpy (res, a, s); #endif } diff --git a/mir-ppc64.c b/mir-ppc64.c index 65eaaab4c3..b053e7136a 100644 --- a/mir-ppc64.c +++ b/mir-ppc64.c @@ -201,7 +201,7 @@ void *va_arg_builtin (void *p, uint64_t t) { void va_block_arg_builtin (void *res, void *p, size_t s, uint64_t ncase MIR_UNUSED) { struct ppc64_va_list *va = p; void *a = va->arg_area; - memcpy (res, a, s); + if (res != NULL) memcpy (res, a, s); va->arg_area += (s + sizeof (uint64_t) - 1) / sizeof (uint64_t); } diff --git a/mir-riscv64.c b/mir-riscv64.c index b993c0649e..c31472f96e 100644 --- a/mir-riscv64.c +++ b/mir-riscv64.c @@ -103,7 +103,7 @@ void va_block_arg_builtin (void *res, void *p, size_t s, uint64_t ncase) { a = *(void **) a; va->arg_area++; } - memcpy (res, a, s); + if (res != NULL) memcpy (res, a, s); } void va_start_interp_builtin (MIR_context_t ctx MIR_UNUSED, void *p, void *a) { diff --git a/mir-s390x.c b/mir-s390x.c index a7fc827ed6..cfd15a1a1b 100644 --- a/mir-s390x.c +++ b/mir-s390x.c @@ -252,7 +252,8 @@ void *va_arg_builtin (void *p, uint64_t t) { } void va_block_arg_builtin (void *res, void *p, size_t s, uint64_t ncase MIR_UNUSED) { - memcpy (res, *(void **) va_arg_builtin (p, MIR_T_I64), s); + void *a = *(void **) va_arg_builtin (p, MIR_T_I64); + if (res == NULL) memcpy (res, a, s); } void va_start_interp_builtin (MIR_context_t ctx MIR_UNUSED, void *p, void *a) { diff --git a/mir-x86_64.c b/mir-x86_64.c index 6475008f32..805d375a68 100644 --- a/mir-x86_64.c +++ b/mir-x86_64.c @@ -81,7 +81,7 @@ void va_block_arg_builtin (void *res, void *p, size_t s, uint64_t ncase) { u[1].i = *(uint64_t *) ((char *) va->reg_save_area + va->gp_offset); va->gp_offset += 8; } - memcpy (res, &u, s); + if (res != NULL) memcpy (res, &u, s); return; case 2: u[0].d = *(double *) ((char *) va->reg_save_area + va->fp_offset); @@ -90,7 +90,7 @@ void va_block_arg_builtin (void *res, void *p, size_t s, uint64_t ncase) { u[1].d = *(double *) ((char *) va->reg_save_area + va->fp_offset); va->fp_offset += 16; } - memcpy (res, &u, s); + if (res != NULL) memcpy (res, &u, s); return; case 3: case 4: @@ -104,11 +104,11 @@ void va_block_arg_builtin (void *res, void *p, size_t s, uint64_t ncase) { } va->fp_offset += 8; va->gp_offset += 8; - memcpy (res, &u, s); + if (res != NULL) memcpy (res, &u, s); return; default: break; } - memcpy (res, a, s); + if (res != NULL) memcpy (res, a, s); va->overflow_arg_area += size / 8; } @@ -136,7 +136,7 @@ void *va_arg_builtin (void *p, uint64_t t) { void va_block_arg_builtin (void *res, void *p, size_t s, uint64_t ncase) { struct x86_64_va_list *va = p; void *a = s <= 8 ? va->arg_area : *(void **) va->arg_area; /* pass by pointer */ - memcpy (res, a, s); + if (res != NULL) memcpy (res, a, s); va->arg_area++; }