@@ -3218,14 +3218,54 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI
3218
3218
return LLVMBuildTrunc (g->builder , shifted_value, child_type->type_ref , " " );
3219
3219
}
3220
3220
3221
- static LLVMValueRef ir_render_store_ptr (CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) {
3222
- LLVMValueRef ptr = ir_llvm_value (g, instruction->ptr );
3223
- LLVMValueRef value = ir_llvm_value (g, instruction->value );
3221
+ static bool value_is_all_undef (ConstExprValue *const_val) {
3222
+ switch (const_val->special ) {
3223
+ case ConstValSpecialRuntime:
3224
+ return false ;
3225
+ case ConstValSpecialUndef:
3226
+ return true ;
3227
+ case ConstValSpecialStatic:
3228
+ if (const_val->type ->id == ZigTypeIdStruct) {
3229
+ for (size_t i = 0 ; i < const_val->type ->data .structure .src_field_count ; i += 1 ) {
3230
+ if (!value_is_all_undef (&const_val->data .x_struct .fields [i]))
3231
+ return false ;
3232
+ }
3233
+ return true ;
3234
+ } else {
3235
+ return false ;
3236
+ }
3237
+ }
3238
+ zig_unreachable ();
3239
+ }
3240
+
3241
+ static void gen_undef_init (CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr) {
3242
+ ZigType *usize = g->builtin_types .entry_usize ;
3243
+ uint64_t size_bytes = LLVMStoreSizeOfType (g->target_data_ref , value_type->type_ref );
3244
+ assert (size_bytes > 0 );
3245
+ assert (ptr_align_bytes > 0 );
3246
+ // memset uninitialized memory to 0xaa
3247
+ LLVMTypeRef ptr_u8 = LLVMPointerType (LLVMInt8Type (), 0 );
3248
+ LLVMValueRef fill_char = LLVMConstInt (LLVMInt8Type (), 0xaa , false );
3249
+ LLVMValueRef dest_ptr = LLVMBuildBitCast (g->builder , ptr, ptr_u8, " " );
3250
+ LLVMValueRef byte_count = LLVMConstInt (usize->type_ref , size_bytes, false );
3251
+ ZigLLVMBuildMemSet (g->builder , dest_ptr, fill_char, byte_count, ptr_align_bytes, false );
3252
+ }
3224
3253
3225
- assert (instruction-> ptr -> value . type -> id == ZigTypeIdPointer);
3254
+ static LLVMValueRef ir_render_store_ptr (CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) {
3226
3255
ZigType *ptr_type = instruction->ptr ->value .type ;
3256
+ assert (ptr_type->id == ZigTypeIdPointer);
3257
+
3258
+ bool have_init_expr = !value_is_all_undef (&instruction->value ->value );
3259
+ if (have_init_expr) {
3260
+ LLVMValueRef ptr = ir_llvm_value (g, instruction->ptr );
3261
+ LLVMValueRef value = ir_llvm_value (g, instruction->value );
3227
3262
3228
- gen_assign_raw (g, ptr, ptr_type, value);
3263
+ gen_assign_raw (g, ptr, ptr_type, value);
3264
+ }
3265
+ if (ir_want_runtime_safety (g, &instruction->base )) {
3266
+ gen_undef_init (g, get_ptr_align (g, ptr_type), instruction->value ->value .type ,
3267
+ ir_llvm_value (g, instruction->ptr ));
3268
+ }
3229
3269
3230
3270
return nullptr ;
3231
3271
}
0 commit comments