fix compile error for reading past end of pointer casted array
parent
6b6f2fcf96
commit
160367e0dd
28
src/ir.cpp
28
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:
|
||||
|
|
|
@ -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 {}
|
||||
|
|
Loading…
Reference in New Issue