aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-02-16 19:35:42 -0500
committerAndrew Kelley <superjoe30@gmail.com>2017-02-16 19:35:42 -0500
commit0148f39df929cc00c1b2231acce41c22f74f9969 (patch)
tree6b7904248232572d9edc5b69b74a67c166bb8008 /src/codegen.cpp
parent244362fed7ed9280a0612c7c57ed67f6fa33b40d (diff)
downloadzig-0148f39df929cc00c1b2231acce41c22f74f9969.tar.gz
zig-0148f39df929cc00c1b2231acce41c22f74f9969.zip
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
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp49
1 files changed, 16 insertions, 33 deletions
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);