From 0148f39df929cc00c1b2231acce41c22f74f9969 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 16 Feb 2017 19:35:42 -0500 Subject: pointers with bit offset contain length adds compile error when passing pointer that is byte-aligned at the beginning but not the end to a function expecting a fully byte aligned pointer closes #261 --- src/codegen.cpp | 49 ++++++++++++++++--------------------------------- 1 file changed, 16 insertions(+), 33 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 69cfa66f04..90c910adf3 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1374,27 +1374,17 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI assert(ptr_type->id == TypeTableEntryIdPointer); bool is_volatile = ptr_type->data.pointer.is_volatile; - uint32_t bit_offset = ptr_type->data.pointer.bit_offset; - LLVMValueRef containing_int; - if (bit_offset == 0) { - LLVMValueRef result_val = get_handle_value(g, ptr, child_type, is_volatile); - if (LLVMGetTypeKind(LLVMTypeOf(result_val)) == LLVMIntegerTypeKind && - LLVMGetTypeKind(child_type->type_ref) == LLVMIntegerTypeKind && - LLVMGetIntTypeWidth(child_type->type_ref) < LLVMGetIntTypeWidth(LLVMTypeOf(result_val))) - { - containing_int = result_val; - } else { - return result_val; - } - } else { - assert(!handle_is_ptr(child_type)); - containing_int = LLVMBuildLoad(g->builder, ptr, ""); - LLVMSetVolatile(containing_int, is_volatile); - } + uint32_t unaligned_bit_count = ptr_type->data.pointer.unaligned_bit_count; + if (unaligned_bit_count == 0) + return get_handle_value(g, ptr, child_type, is_volatile); + + assert(!handle_is_ptr(child_type)); + LLVMValueRef containing_int = LLVMBuildLoad(g->builder, ptr, ""); + LLVMSetVolatile(containing_int, is_volatile); - uint32_t child_bit_count = type_size_bits(g, child_type); + uint32_t bit_offset = ptr_type->data.pointer.bit_offset; uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int)); - uint32_t shift_amt = host_bit_count - bit_offset - child_bit_count; + uint32_t shift_amt = host_bit_count - bit_offset - unaligned_bit_count; LLVMValueRef shift_amt_val = LLVMConstInt(LLVMTypeOf(containing_int), shift_amt, false); LLVMValueRef shifted_value = LLVMBuildLShr(g->builder, containing_int, shift_amt_val, ""); @@ -1416,25 +1406,18 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir if (handle_is_ptr(child_type)) return gen_struct_memcpy(g, value, ptr, child_type); - uint32_t bit_offset = ptr_type->data.pointer.bit_offset; - if (bit_offset == 0) { - LLVMTypeRef ptr_child_ref = LLVMGetElementType(LLVMTypeOf(ptr)); - bool need_to_do_some_bit_stuff = - LLVMGetTypeKind(ptr_child_ref) == LLVMIntegerTypeKind && - LLVMGetTypeKind(child_type->type_ref) == LLVMIntegerTypeKind && - LLVMGetIntTypeWidth(child_type->type_ref) < LLVMGetIntTypeWidth(ptr_child_ref); - if (!need_to_do_some_bit_stuff) { - LLVMValueRef llvm_instruction = LLVMBuildStore(g->builder, value, ptr); - LLVMSetVolatile(llvm_instruction, ptr_type->data.pointer.is_volatile); - return nullptr; - } + uint32_t unaligned_bit_count = ptr_type->data.pointer.unaligned_bit_count; + if (unaligned_bit_count == 0) { + LLVMValueRef llvm_instruction = LLVMBuildStore(g->builder, value, ptr); + LLVMSetVolatile(llvm_instruction, ptr_type->data.pointer.is_volatile); + return nullptr; } LLVMValueRef containing_int = LLVMBuildLoad(g->builder, ptr, ""); - uint32_t child_bit_count = type_size_bits(g, child_type); + uint32_t bit_offset = ptr_type->data.pointer.bit_offset; uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int)); - uint32_t shift_amt = host_bit_count - bit_offset - child_bit_count; + uint32_t shift_amt = host_bit_count - bit_offset - unaligned_bit_count; LLVMValueRef shift_amt_val = LLVMConstInt(LLVMTypeOf(containing_int), shift_amt, false); LLVMValueRef mask_val = LLVMConstAllOnes(child_type->type_ref); -- cgit v1.2.3