authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-12-30 17:05:50+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-12-30 17:43:58-05:00
logc1ee846c221a43b3bb3f9e427a2077b444435ec7
treefb212814ae4d9106d27ec2a73d154eba2c62bab7
parent34b4538d7b15b4f1731228fc9e40b63001771956

Fix ptrCast of zero-sized type

Closes #2431

2 files changed, 27 insertions(+), 17 deletions(-)

src/ir.cpp+17-17
......@@ -26599,6 +26599,23 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
2659926599 if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes)))
2660026600 return ira->codegen->invalid_instruction;
2660126601
26602 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown)))
26603 return ira->codegen->invalid_instruction;
26604
26605 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown)))
26606 return ira->codegen->invalid_instruction;
26607
26608 if (type_has_bits(dest_type) && !type_has_bits(src_type)) {
26609 ErrorMsg *msg = ir_add_error(ira, source_instr,
26610 buf_sprintf("'%s' and '%s' do not have the same in-memory representation",
26611 buf_ptr(&src_type->name), buf_ptr(&dest_type->name)));
26612 add_error_note(ira->codegen, msg, ptr->source_node,
26613 buf_sprintf("'%s' has no in-memory bits", buf_ptr(&src_type->name)));
26614 add_error_note(ira->codegen, msg, dest_type_src->source_node,
26615 buf_sprintf("'%s' has in-memory bits", buf_ptr(&dest_type->name)));
26616 return ira->codegen->invalid_instruction;
26617 }
26618
2660226619 if (instr_is_comptime(ptr)) {
2660326620 bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type);
2660426621 UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad;
......@@ -26649,23 +26666,6 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
2664926666
2665026667 IrInstruction *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on);
2665126668
26652 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown)))
26653 return ira->codegen->invalid_instruction;
26654
26655 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown)))
26656 return ira->codegen->invalid_instruction;
26657
26658 if (type_has_bits(dest_type) && !type_has_bits(src_type)) {
26659 ErrorMsg *msg = ir_add_error(ira, source_instr,
26660 buf_sprintf("'%s' and '%s' do not have the same in-memory representation",
26661 buf_ptr(&src_type->name), buf_ptr(&dest_type->name)));
26662 add_error_note(ira->codegen, msg, ptr->source_node,
26663 buf_sprintf("'%s' has no in-memory bits", buf_ptr(&src_type->name)));
26664 add_error_note(ira->codegen, msg, dest_type_src->source_node,
26665 buf_sprintf("'%s' has in-memory bits", buf_ptr(&dest_type->name)));
26666 return ira->codegen->invalid_instruction;
26667 }
26668
2666926669 // Keep the bigger alignment, it can only help-
2667026670 // unless the target is zero bits.
2667126671 IrInstruction *result;
test/compile_errors.zig+10
......@@ -2,6 +2,16 @@ const tests = @import("tests.zig");
22const builtin = @import("builtin");
33
44pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.add("comptime ptrcast of zero-sized type",
6 \\fn foo() void {
7 \\ const node: struct {} = undefined;
8 \\ const vla_ptr = @ptrCast([*]const u8, &node);
9 \\}
10 \\comptime { foo(); }
11 , &[_][]const u8{
12 "tmp.zig:3:21: error: '*const struct:2:17' and '[*]const u8' do not have the same in-memory representation",
13 });
14
515 cases.add("slice sentinel mismatch",
616 \\fn foo() [:0]u8 {
717 \\ var x: []u8 = undefined;