| author | |
| committer | |
| log | 4ffab5b85f03f63a7e724698482f8497cacc7212 |
| tree | 0928e6e3573faf78e3b11e53f16affd183cc92a3 |
| parent | c7dc03fcb16abfac2d914002a609b8144f7cdab2 |
| signature |
5 files changed, 36 insertions(+), 22 deletions(-)
src/codegen.cpp+12-3| ... | ... | @@ -4983,7 +4983,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu |
| 4983 | 4983 | } |
| 4984 | 4984 | } |
| 4985 | 4985 | |
| 4986 | static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, IrInstructionOptionalWrap *instruction) { | |
| 4986 | static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutable *executable, IrInstructionOptionalWrap *instruction) { | |
| 4987 | 4987 | ZigType *wanted_type = instruction->base.value.type; |
| 4988 | 4988 | |
| 4989 | 4989 | assert(wanted_type->id == ZigTypeIdOptional); |
| ... | ... | @@ -4991,11 +4991,20 @@ static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, I |
| 4991 | 4991 | ZigType *child_type = wanted_type->data.maybe.child_type; |
| 4992 | 4992 | |
| 4993 | 4993 | if (!type_has_bits(child_type)) { |
| 4994 | return LLVMConstInt(LLVMInt1Type(), 1, false); | |
| 4994 | LLVMValueRef result = LLVMConstAllOnes(LLVMInt1Type()); | |
| 4995 | if (instruction->result_loc != nullptr) { | |
| 4996 | LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); | |
| 4997 | gen_store_untyped(g, result, result_loc, 0, false); | |
| 4998 | } | |
| 4999 | return result; | |
| 4995 | 5000 | } |
| 4996 | 5001 | |
| 4997 | 5002 | LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand); |
| 4998 | 5003 | if (!handle_is_ptr(wanted_type)) { |
| 5004 | if (instruction->result_loc != nullptr) { | |
| 5005 | LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); | |
| 5006 | gen_store_untyped(g, payload_val, result_loc, 0, false); | |
| 5007 | } | |
| 4999 | 5008 | return payload_val; |
| 5000 | 5009 | } |
| 5001 | 5010 | |
| ... | ... | @@ -5666,7 +5675,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 5666 | 5675 | case IrInstructionIdUnwrapErrPayload: |
| 5667 | 5676 | return ir_render_unwrap_err_payload(g, executable, (IrInstructionUnwrapErrPayload *)instruction); |
| 5668 | 5677 | case IrInstructionIdOptionalWrap: |
| 5669 | return ir_render_maybe_wrap(g, executable, (IrInstructionOptionalWrap *)instruction); | |
| 5678 | return ir_render_optional_wrap(g, executable, (IrInstructionOptionalWrap *)instruction); | |
| 5670 | 5679 | case IrInstructionIdErrWrapCode: |
| 5671 | 5680 | return ir_render_err_wrap_code(g, executable, (IrInstructionErrWrapCode *)instruction); |
| 5672 | 5681 | case IrInstructionIdErrWrapPayload: |
src/ir.cpp+10-5| ... | ... | @@ -1826,7 +1826,7 @@ static IrInstruction *ir_build_optional_wrap(IrAnalyze *ira, IrInstruction *sour |
| 1826 | 1826 | instruction->result_loc = result_loc; |
| 1827 | 1827 | |
| 1828 | 1828 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| 1829 | ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); | |
| 1829 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); | |
| 1830 | 1830 | |
| 1831 | 1831 | return &instruction->base; |
| 1832 | 1832 | } |
| ... | ... | @@ -11277,10 +11277,15 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so |
| 11277 | 11277 | return &const_instruction->base; |
| 11278 | 11278 | } |
| 11279 | 11279 | |
| 11280 | if (result_loc == nullptr) result_loc = no_result_loc(); | |
| 11281 | IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true); | |
| 11282 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { | |
| 11283 | return result_loc_inst; | |
| 11280 | if (result_loc == nullptr && handle_is_ptr(wanted_type)) { | |
| 11281 | result_loc = no_result_loc(); | |
| 11282 | } | |
| 11283 | IrInstruction *result_loc_inst = nullptr; | |
| 11284 | if (result_loc != nullptr) { | |
| 11285 | result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true); | |
| 11286 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { | |
| 11287 | return result_loc_inst; | |
| 11288 | } | |
| 11284 | 11289 | } |
| 11285 | 11290 | IrInstruction *result = ir_build_optional_wrap(ira, source_instr, wanted_type, value, result_loc_inst); |
| 11286 | 11291 | result->value.data.rh_maybe = RuntimeHintOptionalNonNull; |
test/stage1/behavior.zig+2-2| ... | ... | @@ -66,10 +66,10 @@ comptime { |
| 66 | 66 | _ = @import("behavior/namespace_depends_on_compile_var.zig"); |
| 67 | 67 | _ = @import("behavior/new_stack_call.zig"); |
| 68 | 68 | _ = @import("behavior/null.zig"); |
| 69 | _ = @import("behavior/optional.zig"); // TODO | |
| 69 | _ = @import("behavior/optional.zig"); | |
| 70 | 70 | _ = @import("behavior/pointers.zig"); |
| 71 | 71 | _ = @import("behavior/popcount.zig"); |
| 72 | _ = @import("behavior/ptrcast.zig"); // TODO | |
| 72 | _ = @import("behavior/ptrcast.zig"); | |
| 73 | 73 | _ = @import("behavior/pub_enum.zig"); |
| 74 | 74 | _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); |
| 75 | 75 | _ = @import("behavior/reflection.zig"); |
test/stage1/behavior/optional.zig+5-5| ... | ... | @@ -2,11 +2,11 @@ const expect = @import("std").testing.expect; |
| 2 | 2 | |
| 3 | 3 | pub const EmptyStruct = struct {}; |
| 4 | 4 | |
| 5 | //test "optional pointer to size zero struct" { | |
| 6 | // var e = EmptyStruct{}; | |
| 7 | // var o: ?*EmptyStruct = &e; | |
| 8 | // expect(o != null); | |
| 9 | //} | |
| 5 | test "optional pointer to size zero struct" { | |
| 6 | var e = EmptyStruct{}; | |
| 7 | var o: ?*EmptyStruct = &e; | |
| 8 | expect(o != null); | |
| 9 | } | |
| 10 | 10 | |
| 11 | 11 | test "equality compare nullable pointers" { |
| 12 | 12 | testNullPtrsEql(); |
test/stage1/behavior/ptrcast.zig+7-7| ... | ... | @@ -59,10 +59,10 @@ test "comptime ptrcast keeps larger alignment" { |
| 59 | 59 | } |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | //test "implicit optional pointer to optional c_void pointer" { | |
| 63 | // var buf: [4]u8 = "aoeu"; | |
| 64 | // var x: ?[*]u8 = &buf; | |
| 65 | // var y: ?*c_void = x; | |
| 66 | // var z = @ptrCast(*[4]u8, y); | |
| 67 | // expect(std.mem.eql(u8, z, "aoeu")); | |
| 68 | //} | |
| 62 | test "implicit optional pointer to optional c_void pointer" { | |
| 63 | var buf: [4]u8 = "aoeu"; | |
| 64 | var x: ?[*]u8 = &buf; | |
| 65 | var y: ?*c_void = x; | |
| 66 | var z = @ptrCast(*[4]u8, y); | |
| 67 | expect(std.mem.eql(u8, z, "aoeu")); | |
| 68 | } |