diff options
| author | LemonBoy <thatlemon@gmail.com> | 2019-12-15 12:48:35 +0100 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-12-15 14:41:05 -0500 |
| commit | 19ddbd9e9e691ff7ab8789e8c6962497fbba4b88 (patch) | |
| tree | f7523737827e07e2b17f7d6ce2a64d630b814f4c /src/codegen.cpp | |
| parent | cf0d300ddecf3e1bf0363002c995425dab007b74 (diff) | |
| download | zig-19ddbd9e9e691ff7ab8789e8c6962497fbba4b88.tar.gz zig-19ddbd9e9e691ff7ab8789e8c6962497fbba4b88.zip | |
Make sure the address is aligned for intToPtr ops
Closes #773
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index cad67e3788..845375a25c 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3241,17 +3241,37 @@ static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executa static LLVMValueRef ir_render_int_to_ptr(CodeGen *g, IrExecutable *executable, IrInstructionIntToPtr *instruction) { ZigType *wanted_type = instruction->base.value->type; LLVMValueRef target_val = ir_llvm_value(g, instruction->target); - if (!ptr_allows_addr_zero(wanted_type) && ir_want_runtime_safety(g, &instruction->base)) { - LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(target_val)); - LLVMValueRef is_zero_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, target_val, zero, ""); - LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "PtrToIntBad"); - LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "PtrToIntOk"); - LLVMBuildCondBr(g->builder, is_zero_bit, bad_block, ok_block); - LLVMPositionBuilderAtEnd(g->builder, bad_block); - gen_safety_crash(g, PanicMsgIdPtrCastNull); + if (ir_want_runtime_safety(g, &instruction->base)) { + ZigType *usize = g->builtin_types.entry_usize; + LLVMValueRef zero = LLVMConstNull(usize->llvm_type); - LLVMPositionBuilderAtEnd(g->builder, ok_block); + if (!ptr_allows_addr_zero(wanted_type)) { + LLVMValueRef is_zero_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, target_val, zero, ""); + LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "PtrToIntBad"); + LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "PtrToIntOk"); + LLVMBuildCondBr(g->builder, is_zero_bit, bad_block, ok_block); + + LLVMPositionBuilderAtEnd(g->builder, bad_block); + gen_safety_crash(g, PanicMsgIdPtrCastNull); + + LLVMPositionBuilderAtEnd(g->builder, ok_block); + } + + { + const uint32_t align_bytes = get_ptr_align(g, wanted_type); + 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, ""); + LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "PtrToIntAlignBad"); + LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "PtrToIntAlignOk"); + LLVMBuildCondBr(g->builder, is_ok_bit, ok_block, bad_block); + + LLVMPositionBuilderAtEnd(g->builder, bad_block); + gen_safety_crash(g, PanicMsgIdIncorrectAlignment); + + LLVMPositionBuilderAtEnd(g->builder, ok_block); + } } return LLVMBuildIntToPtr(g->builder, target_val, get_llvm_type(g, wanted_type), ""); } |
