| ... | @@ -83,7 +83,7 @@ static void render_const_val_global(CodeGen *g, ZigValue *const_val, const char | ... | @@ -83,7 +83,7 @@ static void render_const_val_global(CodeGen *g, ZigValue *const_val, const char |
| 83 | static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *name); | 83 | static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *name); |
| 84 | static void generate_error_name_table(CodeGen *g); | 84 | static void generate_error_name_table(CodeGen *g); |
| 85 | static bool value_is_all_undef(CodeGen *g, ZigValue *const_val); | 85 | static bool value_is_all_undef(CodeGen *g, ZigValue *const_val); |
| 86 | static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr); | 86 | static void gen_undef_init(CodeGen *g, ZigType *ptr_type, ZigType *value_type, LLVMValueRef ptr); |
| 87 | static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment); | 87 | static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment); |
| 88 | static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr, | 88 | static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr, |
| 89 | LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type, | 89 | LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type, |
| ... | @@ -3351,7 +3351,7 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutableGen | ... | @@ -3351,7 +3351,7 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutableGen |
| 3351 | gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false); | 3351 | gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false); |
| 3352 | } else if (ir_want_runtime_safety(g, &instruction->base)) { | 3352 | } else if (ir_want_runtime_safety(g, &instruction->base)) { |
| 3353 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, ""); | 3353 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, ""); |
| 3354 | gen_undef_init(g, slice_ptr_type->abi_align, slice_ptr_type, ptr_field_ptr); | 3354 | gen_undef_init(g, slice_ptr_type, slice_ptr_type, ptr_field_ptr); |
| 3355 | } | 3355 | } |
| 3356 | | 3356 | |
| 3357 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, len_index, ""); | 3357 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, len_index, ""); |
| ... | @@ -3816,22 +3816,35 @@ static void gen_valgrind_undef(CodeGen *g, LLVMValueRef dest_ptr, LLVMValueRef b | ... | @@ -3816,22 +3816,35 @@ static void gen_valgrind_undef(CodeGen *g, LLVMValueRef dest_ptr, LLVMValueRef b |
| 3816 | gen_valgrind_client_request(g, zero, req, ptr_as_usize, byte_count, zero, zero, zero); | 3816 | gen_valgrind_client_request(g, zero, req, ptr_as_usize, byte_count, zero, zero, zero); |
| 3817 | } | 3817 | } |
| 3818 | | 3818 | |
| 3819 | static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr) { | 3819 | static void gen_undef_init(CodeGen *g, ZigType *ptr_type, ZigType *value_type, LLVMValueRef ptr) { |
| 3820 | assert(type_has_bits(g, value_type)); | 3820 | assert(type_has_bits(g, value_type)); |
| | 3821 | |
| | 3822 | uint64_t ptr_align_bytes = get_ptr_align(g, ptr_type); |
| | 3823 | assert(ptr_align_bytes > 0); |
| 3821 | uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, get_llvm_type(g, value_type)); | 3824 | uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, get_llvm_type(g, value_type)); |
| 3822 | assert(size_bytes > 0); | 3825 | assert(size_bytes > 0); |
| 3823 | assert(ptr_align_bytes > 0); | 3826 | |
| 3824 | // memset uninitialized memory to 0xaa | 3827 | if (ptr_type->data.pointer.host_int_bytes == 0) { |
| 3825 | LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); | 3828 | // memset uninitialized memory to 0xaa |
| 3826 | LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false); | 3829 | LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); |
| 3827 | LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, ptr, ptr_u8, ""); | 3830 | LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false); |
| 3828 | ZigType *usize = g->builtin_types.entry_usize; | 3831 | LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, ptr, ptr_u8, ""); |
| 3829 | LLVMValueRef byte_count = LLVMConstInt(usize->llvm_type, size_bytes, false); | 3832 | ZigType *usize = g->builtin_types.entry_usize; |
| 3830 | ZigLLVMBuildMemSet(g->builder, dest_ptr, fill_char, byte_count, ptr_align_bytes, false); | 3833 | LLVMValueRef byte_count = LLVMConstInt(usize->llvm_type, size_bytes, false); |
| 3831 | // then tell valgrind that the memory is undefined even though we just memset it | 3834 | ZigLLVMBuildMemSet(g->builder, dest_ptr, fill_char, byte_count, ptr_align_bytes, false); |
| 3832 | if (g->valgrind_enabled) { | 3835 | // then tell valgrind that the memory is undefined even though we just memset it |
| 3833 | gen_valgrind_undef(g, dest_ptr, byte_count); | 3836 | if (g->valgrind_enabled) { |
| | 3837 | gen_valgrind_undef(g, dest_ptr, byte_count); |
| | 3838 | } |
| | 3839 | return; |
| 3834 | } | 3840 | } |
| | 3841 | |
| | 3842 | // This is a pointer into a packed struct, we can't use memset here. |
| | 3843 | // The jury is still out on what pattern should be written here so clear the |
| | 3844 | // old value and call it a day. Generating a 0xAA...AA mask for this n-bit |
| | 3845 | // value is left as an exercise for the (bored) reader. |
| | 3846 | LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, value_type)); |
| | 3847 | gen_assign_raw(g, ptr, ptr_type, zero); |
| 3835 | } | 3848 | } |
| 3836 | | 3849 | |
| 3837 | static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutableGen *executable, IrInstGenStorePtr *instruction) { | 3850 | static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutableGen *executable, IrInstGenStorePtr *instruction) { |
| ... | @@ -3860,7 +3873,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutableGen *executable, | ... | @@ -3860,7 +3873,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutableGen *executable, |
| 3860 | LLVMValueRef value = ir_llvm_value(g, instruction->value); | 3873 | LLVMValueRef value = ir_llvm_value(g, instruction->value); |
| 3861 | gen_assign_raw(g, ptr, ptr_type, value); | 3874 | gen_assign_raw(g, ptr, ptr_type, value); |
| 3862 | } else if (ir_want_runtime_safety(g, &instruction->base)) { | 3875 | } else if (ir_want_runtime_safety(g, &instruction->base)) { |
| 3863 | gen_undef_init(g, get_ptr_align(g, ptr_type), instruction->value->value->type, | 3876 | gen_undef_init(g, ptr_type, instruction->value->value->type, |
| 3864 | ir_llvm_value(g, instruction->ptr)); | 3877 | ir_llvm_value(g, instruction->ptr)); |
| 3865 | } | 3878 | } |
| 3866 | return nullptr; | 3879 | return nullptr; |
| ... | @@ -5885,7 +5898,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI | ... | @@ -5885,7 +5898,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI |
| 5885 | if (slice_start_ptr != nullptr) { | 5898 | if (slice_start_ptr != nullptr) { |
| 5886 | gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false); | 5899 | gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false); |
| 5887 | } else if (want_runtime_safety) { | 5900 | } else if (want_runtime_safety) { |
| 5888 | gen_undef_init(g, slice_ptr_type->abi_align, slice_ptr_type, ptr_field_ptr); | 5901 | gen_undef_init(g, slice_ptr_type, slice_ptr_type, ptr_field_ptr); |
| 5889 | } else { | 5902 | } else { |
| 5890 | gen_store_untyped(g, LLVMGetUndef(get_llvm_type(g, slice_ptr_type)), ptr_field_ptr, 0, false); | 5903 | gen_store_untyped(g, LLVMGetUndef(get_llvm_type(g, slice_ptr_type)), ptr_field_ptr, 0, false); |
| 5891 | } | 5904 | } |