fix optional pointer to size zero struct
This commit is contained in:
parent
c7dc03fcb1
commit
4ffab5b85f
|
@ -4983,7 +4983,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
|
|||
}
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, IrInstructionOptionalWrap *instruction) {
|
||||
static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutable *executable, IrInstructionOptionalWrap *instruction) {
|
||||
ZigType *wanted_type = instruction->base.value.type;
|
||||
|
||||
assert(wanted_type->id == ZigTypeIdOptional);
|
||||
|
@ -4991,11 +4991,20 @@ static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, I
|
|||
ZigType *child_type = wanted_type->data.maybe.child_type;
|
||||
|
||||
if (!type_has_bits(child_type)) {
|
||||
return LLVMConstInt(LLVMInt1Type(), 1, false);
|
||||
LLVMValueRef result = LLVMConstAllOnes(LLVMInt1Type());
|
||||
if (instruction->result_loc != nullptr) {
|
||||
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
|
||||
gen_store_untyped(g, result, result_loc, 0, false);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand);
|
||||
if (!handle_is_ptr(wanted_type)) {
|
||||
if (instruction->result_loc != nullptr) {
|
||||
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
|
||||
gen_store_untyped(g, payload_val, result_loc, 0, false);
|
||||
}
|
||||
return payload_val;
|
||||
}
|
||||
|
||||
|
@ -5666,7 +5675,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
|||
case IrInstructionIdUnwrapErrPayload:
|
||||
return ir_render_unwrap_err_payload(g, executable, (IrInstructionUnwrapErrPayload *)instruction);
|
||||
case IrInstructionIdOptionalWrap:
|
||||
return ir_render_maybe_wrap(g, executable, (IrInstructionOptionalWrap *)instruction);
|
||||
return ir_render_optional_wrap(g, executable, (IrInstructionOptionalWrap *)instruction);
|
||||
case IrInstructionIdErrWrapCode:
|
||||
return ir_render_err_wrap_code(g, executable, (IrInstructionErrWrapCode *)instruction);
|
||||
case IrInstructionIdErrWrapPayload:
|
||||
|
|
15
src/ir.cpp
15
src/ir.cpp
|
@ -1826,7 +1826,7 @@ static IrInstruction *ir_build_optional_wrap(IrAnalyze *ira, IrInstruction *sour
|
|||
instruction->result_loc = result_loc;
|
||||
|
||||
ir_ref_instruction(operand, ira->new_irb.current_basic_block);
|
||||
ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
|
||||
if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
|
||||
|
||||
return &instruction->base;
|
||||
}
|
||||
|
@ -11277,10 +11277,15 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so
|
|||
return &const_instruction->base;
|
||||
}
|
||||
|
||||
if (result_loc == nullptr) result_loc = no_result_loc();
|
||||
IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true);
|
||||
if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
|
||||
return result_loc_inst;
|
||||
if (result_loc == nullptr && handle_is_ptr(wanted_type)) {
|
||||
result_loc = no_result_loc();
|
||||
}
|
||||
IrInstruction *result_loc_inst = nullptr;
|
||||
if (result_loc != nullptr) {
|
||||
result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true);
|
||||
if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
|
||||
return result_loc_inst;
|
||||
}
|
||||
}
|
||||
IrInstruction *result = ir_build_optional_wrap(ira, source_instr, wanted_type, value, result_loc_inst);
|
||||
result->value.data.rh_maybe = RuntimeHintOptionalNonNull;
|
||||
|
|
|
@ -66,10 +66,10 @@ comptime {
|
|||
_ = @import("behavior/namespace_depends_on_compile_var.zig");
|
||||
_ = @import("behavior/new_stack_call.zig");
|
||||
_ = @import("behavior/null.zig");
|
||||
_ = @import("behavior/optional.zig"); // TODO
|
||||
_ = @import("behavior/optional.zig");
|
||||
_ = @import("behavior/pointers.zig");
|
||||
_ = @import("behavior/popcount.zig");
|
||||
_ = @import("behavior/ptrcast.zig"); // TODO
|
||||
_ = @import("behavior/ptrcast.zig");
|
||||
_ = @import("behavior/pub_enum.zig");
|
||||
_ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
|
||||
_ = @import("behavior/reflection.zig");
|
||||
|
|
|
@ -2,11 +2,11 @@ const expect = @import("std").testing.expect;
|
|||
|
||||
pub const EmptyStruct = struct {};
|
||||
|
||||
//test "optional pointer to size zero struct" {
|
||||
// var e = EmptyStruct{};
|
||||
// var o: ?*EmptyStruct = &e;
|
||||
// expect(o != null);
|
||||
//}
|
||||
test "optional pointer to size zero struct" {
|
||||
var e = EmptyStruct{};
|
||||
var o: ?*EmptyStruct = &e;
|
||||
expect(o != null);
|
||||
}
|
||||
|
||||
test "equality compare nullable pointers" {
|
||||
testNullPtrsEql();
|
||||
|
|
|
@ -59,10 +59,10 @@ test "comptime ptrcast keeps larger alignment" {
|
|||
}
|
||||
}
|
||||
|
||||
//test "implicit optional pointer to optional c_void pointer" {
|
||||
// var buf: [4]u8 = "aoeu";
|
||||
// var x: ?[*]u8 = &buf;
|
||||
// var y: ?*c_void = x;
|
||||
// var z = @ptrCast(*[4]u8, y);
|
||||
// expect(std.mem.eql(u8, z, "aoeu"));
|
||||
//}
|
||||
test "implicit optional pointer to optional c_void pointer" {
|
||||
var buf: [4]u8 = "aoeu";
|
||||
var x: ?[*]u8 = &buf;
|
||||
var y: ?*c_void = x;
|
||||
var z = @ptrCast(*[4]u8, y);
|
||||
expect(std.mem.eql(u8, z, "aoeu"));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user