langref: docs for invalid error set cast and incorrect pointer alignment
also add detection of incorrect pointer alignment at compile-time of pointers that were constructed with `@intToPtr`.
This commit is contained in:
parent
9eb51e20ed
commit
2ee67b7642
@ -6649,12 +6649,60 @@ pub fn main() void {
|
|||||||
{#header_close#}
|
{#header_close#}
|
||||||
|
|
||||||
{#header_open|Invalid Error Set Cast#}
|
{#header_open|Invalid Error Set Cast#}
|
||||||
<p>TODO</p>
|
<p>At compile-time:</p>
|
||||||
|
{#code_begin|test_err|error.B not a member of error set 'Set2'#}
|
||||||
|
const Set1 = error{
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
};
|
||||||
|
const Set2 = error{
|
||||||
|
A,
|
||||||
|
C,
|
||||||
|
};
|
||||||
|
comptime {
|
||||||
|
_ = @errSetCast(Set2, Set1.B);
|
||||||
|
}
|
||||||
|
{#code_end#}
|
||||||
|
<p>At runtime:</p>
|
||||||
|
{#code_begin|exe_err#}
|
||||||
|
const Set1 = error{
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
};
|
||||||
|
const Set2 = error{
|
||||||
|
A,
|
||||||
|
C,
|
||||||
|
};
|
||||||
|
pub fn main() void {
|
||||||
|
_ = foo(Set1.B);
|
||||||
|
}
|
||||||
|
fn foo(set1: Set1) Set2 {
|
||||||
|
return @errSetCast(Set2, set1);
|
||||||
|
}
|
||||||
|
{#code_end#}
|
||||||
{#header_close#}
|
{#header_close#}
|
||||||
|
|
||||||
{#header_open|Incorrect Pointer Alignment#}
|
{#header_open|Incorrect Pointer Alignment#}
|
||||||
<p>TODO</p>
|
<p>At compile-time:</p>
|
||||||
|
{#code_begin|test_err|pointer address 0x1 is not aligned to 4 bytes#}
|
||||||
|
comptime {
|
||||||
|
const ptr = @intToPtr(*i32, 0x1);
|
||||||
|
const aligned = @alignCast(4, ptr);
|
||||||
|
}
|
||||||
|
{#code_end#}
|
||||||
|
<p>At runtime:</p>
|
||||||
|
{#code_begin|exe_err#}
|
||||||
|
pub fn main() !void {
|
||||||
|
var array align(4) = []u32{ 0x11111111, 0x11111111 };
|
||||||
|
const bytes = @sliceToBytes(array[0..]);
|
||||||
|
if (foo(bytes) != 0x11111111) return error.Wrong;
|
||||||
|
}
|
||||||
|
fn foo(bytes: []u8) u32 {
|
||||||
|
const slice4 = bytes[1..5];
|
||||||
|
const int_slice = @bytesToSlice(u32, @alignCast(4, slice4));
|
||||||
|
return int_slice[0];
|
||||||
|
}
|
||||||
|
{#code_end#}
|
||||||
{#header_close#}
|
{#header_close#}
|
||||||
{#header_open|Wrong Union Field Access#}
|
{#header_open|Wrong Union Field Access#}
|
||||||
<p>TODO</p>
|
<p>TODO</p>
|
||||||
|
@ -19370,6 +19370,15 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3
|
|||||||
if (!val)
|
if (!val)
|
||||||
return ira->codegen->invalid_instruction;
|
return ira->codegen->invalid_instruction;
|
||||||
|
|
||||||
|
if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr &&
|
||||||
|
val->data.x_ptr.data.hard_coded_addr.addr % align_bytes != 0)
|
||||||
|
{
|
||||||
|
ir_add_error(ira, target,
|
||||||
|
buf_sprintf("pointer address 0x%lx is not aligned to %" PRIu32 " bytes",
|
||||||
|
val->data.x_ptr.data.hard_coded_addr.addr, align_bytes));
|
||||||
|
return ira->codegen->invalid_instruction;
|
||||||
|
}
|
||||||
|
|
||||||
IrInstruction *result = ir_create_const(&ira->new_irb, target->scope, target->source_node, result_type);
|
IrInstruction *result = ir_create_const(&ira->new_irb, target->scope, target->source_node, result_type);
|
||||||
copy_const_val(&result->value, val, false);
|
copy_const_val(&result->value, val, false);
|
||||||
result->value.type = result_type;
|
result->value.type = result_type;
|
||||||
|
@ -1,6 +1,16 @@
|
|||||||
const tests = @import("tests.zig");
|
const tests = @import("tests.zig");
|
||||||
|
|
||||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||||
|
cases.add(
|
||||||
|
"bad @alignCast at comptime",
|
||||||
|
\\comptime {
|
||||||
|
\\ const ptr = @intToPtr(*i32, 0x1);
|
||||||
|
\\ const aligned = @alignCast(4, ptr);
|
||||||
|
\\}
|
||||||
|
,
|
||||||
|
".tmp_source.zig:3:35: error: pointer address 0x1 is not aligned to 4 bytes",
|
||||||
|
);
|
||||||
|
|
||||||
cases.add(
|
cases.add(
|
||||||
"@ptrToInt on *void",
|
"@ptrToInt on *void",
|
||||||
\\export fn entry() bool {
|
\\export fn entry() bool {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user