diff --git a/src/ir.cpp b/src/ir.cpp index 8cd780e46..b3b3198ce 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -19971,6 +19971,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf), pointee); if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) return err; + buf_deinit(&buf); return ErrorNone; } @@ -19990,7 +19991,31 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source dst_size, buf_ptr(&pointee->type->name), src_size)); return ErrorSemanticAnalyzeFail; } - case ConstPtrSpecialSubArray: + case ConstPtrSpecialSubArray: { + ZigValue *array_val = ptr_val->data.x_ptr.data.base_array.array_val; + assert(array_val->type->id == ZigTypeIdArray); + if (array_val->data.x_array.special != ConstArraySpecialNone) + zig_panic("TODO"); + if (dst_size > src_size) { + size_t elem_index = ptr_val->data.x_ptr.data.base_array.elem_index; + opt_ir_add_error_node(ira, codegen, source_node, + buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from %s at index %" ZIG_PRI_usize " which is %" ZIG_PRI_usize " bytes", + dst_size, buf_ptr(&array_val->type->name), elem_index, src_size)); + return ErrorSemanticAnalyzeFail; + } + size_t elem_size = src_size; + size_t elem_count = (dst_size % elem_size == 0) ? (dst_size / elem_size) : (dst_size / elem_size + 1); + Buf buf = BUF_INIT; + buf_resize(&buf, elem_count * elem_size); + for (size_t i = 0; i < elem_count; i += 1) { + ZigValue *elem_val = &array_val->data.x_array.data.s_none.elements[i]; + buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf) + (i * elem_size), elem_val); + } + if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) + return err; + buf_deinit(&buf); + return ErrorNone; + } case ConstPtrSpecialBaseArray: { ZigValue *array_val = ptr_val->data.x_ptr.data.base_array.array_val; assert(array_val->type->id == ZigTypeIdArray); @@ -20014,6 +20039,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source } if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) return err; + buf_deinit(&buf); return ErrorNone; } case ConstPtrSpecialBaseStruct: diff --git a/test/compile_errors.zig b/test/compile_errors.zig index abcdc48dc..e3e146217 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -1903,17 +1903,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:7:15: error: switch must handle all possibilities", }); - // TODO uncomment before merging branch - //cases.add("reading past end of pointer casted array", - // \\comptime { - // \\ const array: [4]u8 = "aoeu".*; - // \\ const sub_array = array[1..]; - // \\ const int_ptr = @ptrCast(*const u24, sub_array); - // \\ const deref = int_ptr.*; - // \\} - //, &[_][]const u8{ - // "tmp.zig:5:26: error: attempt to read 4 bytes from [4]u8 at index 1 which is 3 bytes", - //}); + cases.add("reading past end of pointer casted array", + \\comptime { + \\ const array: [4]u8 = "aoeu".*; + \\ const sub_array = array[1..]; + \\ const int_ptr = @ptrCast(*const u24, sub_array); + \\ const deref = int_ptr.*; + \\} + , &[_][]const u8{ + "tmp.zig:5:26: error: attempt to read 4 bytes from [4]u8 at index 1 which is 3 bytes", + }); cases.add("error note for function parameter incompatibility", \\fn do_the_thing(func: fn (arg: i32) void) void {}