From 0570df69b178c99f4d9d679a57d966f507dda484 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 13 Oct 2020 19:34:20 +0200 Subject: stage1: Fix missing runtime safety check for intToPtr Elide the alignment check if the pointer alignment is one, the null check must be preserved as it depends on the pointer type. Fixes #6667 --- src/stage1/codegen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/stage1/codegen.cpp') diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index 9ed2ba9d73..5e9b84d25a 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -3379,7 +3379,7 @@ static LLVMValueRef ir_render_int_to_ptr(CodeGen *g, IrExecutableGen *executable LLVMValueRef target_val = ir_llvm_value(g, instruction->target); const uint32_t align_bytes = get_ptr_align(g, wanted_type); - if (ir_want_runtime_safety(g, &instruction->base) && align_bytes > 1) { + if (ir_want_runtime_safety(g, &instruction->base)) { ZigType *usize = g->builtin_types.entry_usize; LLVMValueRef zero = LLVMConstNull(usize->llvm_type); @@ -3395,7 +3395,7 @@ static LLVMValueRef ir_render_int_to_ptr(CodeGen *g, IrExecutableGen *executable LLVMPositionBuilderAtEnd(g->builder, ok_block); } - { + if (align_bytes > 1) { LLVMValueRef alignment_minus_1 = LLVMConstInt(usize->llvm_type, align_bytes - 1, false); LLVMValueRef anded_val = LLVMBuildAnd(g->builder, target_val, alignment_minus_1, ""); LLVMValueRef is_ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, anded_val, zero, ""); -- cgit v1.2.3 From f78380b936de862476ea6b3cc3e8d4ba4562c7fa Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 16 Oct 2020 12:15:46 +0200 Subject: 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. --- src/stage1/codegen.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/stage1/codegen.cpp') diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index 5e9b84d25a..b8ac867082 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -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; -- cgit v1.2.3