From c1ee846c221a43b3bb3f9e427a2077b444435ec7 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 30 Dec 2019 17:05:50 +0100 Subject: [PATCH] Fix ptrCast of zero-sized type Closes #2431 --- src/ir.cpp | 34 +++++++++++++++++----------------- test/compile_errors.zig | 10 ++++++++++ 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index a862ff1068..c4331d74e3 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -26599,6 +26599,23 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) return ira->codegen->invalid_instruction; + if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) + return ira->codegen->invalid_instruction; + + if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown))) + return ira->codegen->invalid_instruction; + + if (type_has_bits(dest_type) && !type_has_bits(src_type)) { + ErrorMsg *msg = ir_add_error(ira, source_instr, + buf_sprintf("'%s' and '%s' do not have the same in-memory representation", + buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); + add_error_note(ira->codegen, msg, ptr->source_node, + buf_sprintf("'%s' has no in-memory bits", buf_ptr(&src_type->name))); + add_error_note(ira->codegen, msg, dest_type_src->source_node, + buf_sprintf("'%s' has in-memory bits", buf_ptr(&dest_type->name))); + return ira->codegen->invalid_instruction; + } + if (instr_is_comptime(ptr)) { bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type); UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad; @@ -26649,23 +26666,6 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ IrInstruction *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); - if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; - - if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; - - if (type_has_bits(dest_type) && !type_has_bits(src_type)) { - ErrorMsg *msg = ir_add_error(ira, source_instr, - buf_sprintf("'%s' and '%s' do not have the same in-memory representation", - buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); - add_error_note(ira->codegen, msg, ptr->source_node, - buf_sprintf("'%s' has no in-memory bits", buf_ptr(&src_type->name))); - add_error_note(ira->codegen, msg, dest_type_src->source_node, - buf_sprintf("'%s' has in-memory bits", buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; - } - // Keep the bigger alignment, it can only help- // unless the target is zero bits. IrInstruction *result; diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 450f91b9be..a653e1662e 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,6 +2,16 @@ const tests = @import("tests.zig"); const builtin = @import("builtin"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.add("comptime ptrcast of zero-sized type", + \\fn foo() void { + \\ const node: struct {} = undefined; + \\ const vla_ptr = @ptrCast([*]const u8, &node); + \\} + \\comptime { foo(); } + , &[_][]const u8{ + "tmp.zig:3:21: error: '*const struct:2:17' and '[*]const u8' do not have the same in-memory representation", + }); + cases.add("slice sentinel mismatch", \\fn foo() [:0]u8 { \\ var x: []u8 = undefined;