commit 8c1d3ba103dad32d474bcfeb394c629ed00649ea
parent cc083177e030aaca9974f214dbd650968cdc3952
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Sun, 24 May 2026 06:05:56 -0700
c_target: cast pointer operands of mem builtins to void*
cfree's IR represents addresses as integer-width values, which the C target
declares as int64_t. When a mem{cpy,move,set} pointer operand came from
address arithmetic (e.g. `&dst[1]`) rather than a void*-typed slot ref, the
emitted `__builtin_mem*(intptr, ...)` was rejected by the host compiler under
-Wint-conversion.
Cast the pointer operands (dst for all three; src for memcpy/memmove) to
void* at the call site, independent of the operand's CG type. The cast is a
no-op where the operand was already a pointer.
Fixes toy case 63_memory_flags on the --emit=c path.
Diffstat:
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/src/arch/c_target/emit.c b/src/arch/c_target/emit.c
@@ -2461,6 +2461,13 @@ void c_intrinsic(CGTarget* T, IntrinKind k, Operand* dsts, u32 ndst,
cbuf_puts(&t->body, "(");
for (u32 i = 0; i < narg; ++i) {
if (i > 0) cbuf_puts(&t->body, ", ");
+ /* The pointer operands (dst for all three; src for mem{cpy,move})
+ * may be typed as a plain integer reg when they come from address
+ * arithmetic, which the C target declares as int64_t. The builtins
+ * take void*, so cast explicitly to avoid -Wint-conversion. */
+ int is_ptr_arg = (i == 0) ||
+ (i == 1 && (k == INTRIN_MEMCPY || k == INTRIN_MEMMOVE));
+ if (is_ptr_arg) cbuf_puts(&t->body, "(void*)");
c_emit_operand(t, args[i]);
}
cbuf_puts(&t->body, ");\n");
@@ -2649,9 +2656,12 @@ void c_copy_bytes(CGTarget* T, Operand dst_addr, Operand src_addr,
CTarget* t = (CTarget*)T;
c_assert_no_index(t, dst_addr, "copy_bytes dst");
c_assert_no_index(t, src_addr, "copy_bytes src");
- cbuf_puts(&t->body, " __builtin_memcpy(");
+ /* dst/src may be plain integer regs from address arithmetic (declared
+ * int64_t); __builtin_memcpy takes void*, so cast to avoid
+ * -Wint-conversion. */
+ cbuf_puts(&t->body, " __builtin_memcpy((void*)");
c_emit_operand(t, dst_addr);
- cbuf_puts(&t->body, ", ");
+ cbuf_puts(&t->body, ", (void*)");
c_emit_operand(t, src_addr);
cbuf_puts(&t->body, ", ");
cbuf_put_u64(&t->body, (u64)m.size);
@@ -2662,7 +2672,10 @@ void c_set_bytes(CGTarget* T, Operand dst_addr, Operand byte_value,
AggregateAccess m) {
CTarget* t = (CTarget*)T;
c_assert_no_index(t, dst_addr, "set_bytes dst");
- cbuf_puts(&t->body, " __builtin_memset(");
+ /* dst may be a plain integer reg from address arithmetic (declared
+ * int64_t); __builtin_memset takes void*, so cast to avoid
+ * -Wint-conversion. */
+ cbuf_puts(&t->body, " __builtin_memset((void*)");
c_emit_operand(t, dst_addr);
cbuf_puts(&t->body, ", (int)");
c_emit_operand(t, byte_value);