| ... | ... | @@ -415,12 +415,14 @@ static LLVMValueRef get_int_overflow_fn(CodeGen *g, TypeTableEntry *type_entry, |
| 415 | 415 | return *fn; |
| 416 | 416 | } |
| 417 | 417 | |
| 418 | | static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, TypeTableEntry *type) { |
| 418 | static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, TypeTableEntry *type, bool is_volatile) { |
| 419 | 419 | if (type_has_bits(type)) { |
| 420 | 420 | if (handle_is_ptr(type)) { |
| 421 | 421 | return ptr; |
| 422 | 422 | } else { |
| 423 | | return LLVMBuildLoad(g->builder, ptr, ""); |
| 423 | LLVMValueRef result = LLVMBuildLoad(g->builder, ptr, ""); |
| 424 | LLVMSetVolatile(result, is_volatile); |
| 425 | return result; |
| 424 | 426 | } |
| 425 | 427 | } else { |
| 426 | 428 | return nullptr; |
| ... | ... | @@ -1191,6 +1193,7 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst |
| 1191 | 1193 | case IrUnOpInvalid: |
| 1192 | 1194 | case IrUnOpError: |
| 1193 | 1195 | case IrUnOpMaybe: |
| 1196 | case IrUnOpDereference: |
| 1194 | 1197 | zig_unreachable(); |
| 1195 | 1198 | case IrUnOpNegation: |
| 1196 | 1199 | case IrUnOpNegationWrap: |
| ... | ... | @@ -1214,16 +1217,6 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst |
| 1214 | 1217 | } |
| 1215 | 1218 | case IrUnOpBinNot: |
| 1216 | 1219 | return LLVMBuildNot(g->builder, expr, ""); |
| 1217 | | case IrUnOpDereference: |
| 1218 | | { |
| 1219 | | assert(expr_type->id == TypeTableEntryIdPointer); |
| 1220 | | if (!type_has_bits(expr_type)) { |
| 1221 | | return nullptr; |
| 1222 | | } else { |
| 1223 | | TypeTableEntry *child_type = expr_type->data.pointer.child_type; |
| 1224 | | return get_handle_value(g, expr, child_type); |
| 1225 | | } |
| 1226 | | } |
| 1227 | 1220 | } |
| 1228 | 1221 | |
| 1229 | 1222 | zig_unreachable(); |
| ... | ... | @@ -1289,8 +1282,15 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, |
| 1289 | 1282 | } |
| 1290 | 1283 | |
| 1291 | 1284 | static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrInstructionLoadPtr *instruction) { |
| 1285 | TypeTableEntry *child_type = instruction->base.value.type; |
| 1286 | if (!type_has_bits(child_type)) { |
| 1287 | return nullptr; |
| 1288 | } |
| 1292 | 1289 | LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); |
| 1293 | | return get_handle_value(g, ptr, instruction->base.value.type); |
| 1290 | TypeTableEntry *ptr_type = instruction->ptr->value.type; |
| 1291 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 1292 | bool is_volatile = ptr_type->data.pointer.is_volatile; |
| 1293 | return get_handle_value(g, ptr, child_type, is_volatile); |
| 1294 | 1294 | } |
| 1295 | 1295 | |
| 1296 | 1296 | static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) { |
| ... | ... | @@ -1329,8 +1329,9 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI |
| 1329 | 1329 | LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->array_ptr); |
| 1330 | 1330 | TypeTableEntry *array_ptr_type = instruction->array_ptr->value.type; |
| 1331 | 1331 | assert(array_ptr_type->id == TypeTableEntryIdPointer); |
| 1332 | bool is_volatile = array_ptr_type->data.pointer.is_volatile; |
| 1332 | 1333 | TypeTableEntry *array_type = array_ptr_type->data.pointer.child_type; |
| 1333 | | LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type); |
| 1334 | LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, is_volatile); |
| 1334 | 1335 | LLVMValueRef subscript_value = ir_llvm_value(g, instruction->elem_index); |
| 1335 | 1336 | assert(subscript_value); |
| 1336 | 1337 | |
| ... | ... | @@ -1607,12 +1608,13 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable, |
| 1607 | 1608 | { |
| 1608 | 1609 | TypeTableEntry *ptr_type = instruction->value->value.type; |
| 1609 | 1610 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 1611 | bool is_volatile = ptr_type->data.pointer.is_volatile; |
| 1610 | 1612 | TypeTableEntry *maybe_type = ptr_type->data.pointer.child_type; |
| 1611 | 1613 | assert(maybe_type->id == TypeTableEntryIdMaybe); |
| 1612 | 1614 | TypeTableEntry *child_type = maybe_type->data.maybe.child_type; |
| 1613 | 1615 | bool maybe_is_ptr = (child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn); |
| 1614 | 1616 | LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->value); |
| 1615 | | LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type); |
| 1617 | LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, is_volatile); |
| 1616 | 1618 | if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on) { |
| 1617 | 1619 | LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle); |
| 1618 | 1620 | LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeOk"); |
| ... | ... | @@ -1627,7 +1629,7 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable, |
| 1627 | 1629 | if (maybe_is_ptr) { |
| 1628 | 1630 | return maybe_ptr; |
| 1629 | 1631 | } else { |
| 1630 | | LLVMValueRef maybe_struct_ref = get_handle_value(g, maybe_ptr, maybe_type); |
| 1632 | LLVMValueRef maybe_struct_ref = get_handle_value(g, maybe_ptr, maybe_type, is_volatile); |
| 1631 | 1633 | return LLVMBuildStructGEP(g->builder, maybe_struct_ref, maybe_child_index, ""); |
| 1632 | 1634 | } |
| 1633 | 1635 | } |
| ... | ... | @@ -2066,10 +2068,12 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrI |
| 2066 | 2068 | |
| 2067 | 2069 | static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapErrCode *instruction) { |
| 2068 | 2070 | TypeTableEntry *ptr_type = get_underlying_type(instruction->value->value.type); |
| 2071 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 2072 | bool is_volatile = ptr_type->data.pointer.is_volatile; |
| 2069 | 2073 | TypeTableEntry *err_union_type = get_underlying_type(ptr_type->data.pointer.child_type); |
| 2070 | 2074 | TypeTableEntry *child_type = get_underlying_type(err_union_type->data.error.child_type); |
| 2071 | 2075 | LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value); |
| 2072 | | LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type); |
| 2076 | LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, is_volatile); |
| 2073 | 2077 | |
| 2074 | 2078 | if (type_has_bits(child_type)) { |
| 2075 | 2079 | LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, ""); |
| ... | ... | @@ -2081,10 +2085,12 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab |
| 2081 | 2085 | |
| 2082 | 2086 | static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapErrPayload *instruction) { |
| 2083 | 2087 | TypeTableEntry *ptr_type = get_underlying_type(instruction->value->value.type); |
| 2088 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 2089 | bool is_volatile = ptr_type->data.pointer.is_volatile; |
| 2084 | 2090 | TypeTableEntry *err_union_type = get_underlying_type(ptr_type->data.pointer.child_type); |
| 2085 | 2091 | TypeTableEntry *child_type = get_underlying_type(err_union_type->data.error.child_type); |
| 2086 | 2092 | LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value); |
| 2087 | | LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type); |
| 2093 | LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, is_volatile); |
| 2088 | 2094 | |
| 2089 | 2095 | if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on) { |
| 2090 | 2096 | LLVMValueRef err_val; |
| ... | ... | @@ -2193,7 +2199,7 @@ static LLVMValueRef ir_render_enum_tag(CodeGen *g, IrExecutable *executable, IrI |
| 2193 | 2199 | return enum_val; |
| 2194 | 2200 | |
| 2195 | 2201 | LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, enum_val, enum_gen_tag_index, ""); |
| 2196 | | return get_handle_value(g, tag_field_ptr, tag_type); |
| 2202 | return get_handle_value(g, tag_field_ptr, tag_type, false); |
| 2197 | 2203 | } |
| 2198 | 2204 | |
| 2199 | 2205 | static LLVMValueRef ir_render_init_enum(CodeGen *g, IrExecutable *executable, IrInstructionInitEnum *instruction) { |