stage1: Don't ask LLVM to emit misaligned memcpy

Pay close attention to the RHS type alignment when rendering an
assignment op as it may differ from the LHS pointer one.

This problem was noticed when debugging a CI failure in #6648: due to
sheer luck the misalignment caused a segfault on macos that was also
reproduced locally.

I tried to write a small test case but it turned out to be a daunting
task as I couldn't manage to trigger the problem consistently (and stop
the optimizer from simplifying everything). Patches welcome.
This commit is contained in:
LemonBoy 2020-10-16 12:15:46 +02:00 committed by Andrew Kelley
parent 2a62d4b20b
commit f78380b936

View File

@ -1645,11 +1645,13 @@ static void gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type,
ZigType *usize = g->builtin_types.entry_usize;
uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, get_llvm_type(g, child_type));
uint64_t align_bytes = get_ptr_align(g, ptr_type);
uint64_t src_align_bytes = get_abi_alignment(g, child_type);
uint64_t dest_align_bytes = get_ptr_align(g, ptr_type);
assert(size_bytes > 0);
assert(align_bytes > 0);
assert(src_align_bytes > 0);
assert(dest_align_bytes > 0);
ZigLLVMBuildMemCpy(g->builder, dest_ptr, align_bytes, src_ptr, align_bytes,
ZigLLVMBuildMemCpy(g->builder, dest_ptr, dest_align_bytes, src_ptr, src_align_bytes,
LLVMConstInt(usize->llvm_type, size_bytes, false),
ptr_type->data.pointer.is_volatile);
return;