authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-19 18:47:02-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-19 18:47:02-04:00
log4ffab5b85f03f63a7e724698482f8497cacc7212
tree0928e6e3573faf78e3b11e53f16affd183cc92a3
parentc7dc03fcb16abfac2d914002a609b8144f7cdab2
signaturelock-open Commit is signed but in an unrecognized format.

fix optional pointer to size zero struct


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
49834983 }
49844984}
49854985
4986static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, IrInstructionOptionalWrap *instruction) {
4986static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutable *executable, IrInstructionOptionalWrap *instruction) {
49874987 ZigType *wanted_type = instruction->base.value.type;
49884988
49894989 assert(wanted_type->id == ZigTypeIdOptional);
......@@ -4991,11 +4991,20 @@ static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, I
49914991 ZigType *child_type = wanted_type->data.maybe.child_type;
49924992
49934993 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;
49955000 }
49965001
49975002 LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand);
49985003 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 }
49995008 return payload_val;
50005009 }
50015010
......@@ -5666,7 +5675,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
56665675 case IrInstructionIdUnwrapErrPayload:
56675676 return ir_render_unwrap_err_payload(g, executable, (IrInstructionUnwrapErrPayload *)instruction);
56685677 case IrInstructionIdOptionalWrap:
5669 return ir_render_maybe_wrap(g, executable, (IrInstructionOptionalWrap *)instruction);
5678 return ir_render_optional_wrap(g, executable, (IrInstructionOptionalWrap *)instruction);
56705679 case IrInstructionIdErrWrapCode:
56715680 return ir_render_err_wrap_code(g, executable, (IrInstructionErrWrapCode *)instruction);
56725681 case IrInstructionIdErrWrapPayload:
src/ir.cpp+10-5
......@@ -1826,7 +1826,7 @@ static IrInstruction *ir_build_optional_wrap(IrAnalyze *ira, IrInstruction *sour
18261826 instruction->result_loc = result_loc;
18271827
18281828 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);
18301830
18311831 return &instruction->base;
18321832}
......@@ -11277,10 +11277,15 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so
1127711277 return &const_instruction->base;
1127811278 }
1127911279
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 }
1128411289 }
1128511290 IrInstruction *result = ir_build_optional_wrap(ira, source_instr, wanted_type, value, result_loc_inst);
1128611291 result->value.data.rh_maybe = RuntimeHintOptionalNonNull;
test/stage1/behavior.zig+2-2
......@@ -66,10 +66,10 @@ comptime {
6666 _ = @import("behavior/namespace_depends_on_compile_var.zig");
6767 _ = @import("behavior/new_stack_call.zig");
6868 _ = @import("behavior/null.zig");
69 _ = @import("behavior/optional.zig"); // TODO
69 _ = @import("behavior/optional.zig");
7070 _ = @import("behavior/pointers.zig");
7171 _ = @import("behavior/popcount.zig");
72 _ = @import("behavior/ptrcast.zig"); // TODO
72 _ = @import("behavior/ptrcast.zig");
7373 _ = @import("behavior/pub_enum.zig");
7474 _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
7575 _ = @import("behavior/reflection.zig");
test/stage1/behavior/optional.zig+5-5
......@@ -2,11 +2,11 @@ const expect = @import("std").testing.expect;
22
33pub const EmptyStruct = struct {};
44
5//test "optional pointer to size zero struct" {
6// var e = EmptyStruct{};
7// var o: ?*EmptyStruct = &e;
8// expect(o != null);
9//}
5test "optional pointer to size zero struct" {
6 var e = EmptyStruct{};
7 var o: ?*EmptyStruct = &e;
8 expect(o != null);
9}
1010
1111test "equality compare nullable pointers" {
1212 testNullPtrsEql();
test/stage1/behavior/ptrcast.zig+7-7
......@@ -59,10 +59,10 @@ test "comptime ptrcast keeps larger alignment" {
5959 }
6060}
6161
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//}
62test "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}