From 9eb51e20ed1a040a617541303db760f80ffd3aa1 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 9 Jul 2018 10:43:29 -0400 Subject: fix crash on @ptrToInt of a *void closes #1192 --- src/ir.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 98b1bd85ad..5e4c847e14 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -19796,6 +19796,12 @@ static TypeTableEntry *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstr return ira->codegen->builtin_types.entry_invalid; } + if (!type_has_bits(target->value.type)) { + ir_add_error(ira, target, + buf_sprintf("pointer to size 0 type has no address")); + return ira->codegen->builtin_types.entry_invalid; + } + if (instr_is_comptime(target)) { ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); if (!val) -- cgit v1.2.3 From 2ee67b7642cfeef36d8ebbc08080202b5b1d1958 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 9 Jul 2018 11:13:29 -0400 Subject: 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`. --- doc/langref.html.in | 54 ++++++++++++++++++++++++++++++++++++++++++++++--- src/ir.cpp | 9 +++++++++ test/compile_errors.zig | 10 +++++++++ 3 files changed, 70 insertions(+), 3 deletions(-) (limited to 'src/ir.cpp') diff --git a/doc/langref.html.in b/doc/langref.html.in index 8eaffb64ad..16e9023f26 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -6649,12 +6649,60 @@ pub fn main() void { {#header_close#} {#header_open|Invalid Error Set Cast#} -

TODO

+

At compile-time:

+ {#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#} +

At runtime:

+ {#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_open|Incorrect Pointer Alignment#} -

TODO

- +

At compile-time:

+ {#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#} +

At runtime:

+ {#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_open|Wrong Union Field Access#}

TODO

diff --git a/src/ir.cpp b/src/ir.cpp index 5e4c847e14..dcd39ccfe5 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -19370,6 +19370,15 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3 if (!val) 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); copy_const_val(&result->value, val, false); result->value.type = result_type; diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 4ed65e449d..1b76c01564 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -1,6 +1,16 @@ const tests = @import("tests.zig"); 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( "@ptrToInt on *void", \\export fn entry() bool { -- cgit v1.2.3 From 0ac1b83885c7f2a97a8ac25657afcb5c9b80afb4 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 9 Jul 2018 17:13:31 -0400 Subject: fix non-portable format specifier --- src/ir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index dcd39ccfe5..505a32247e 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -19374,7 +19374,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3 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", + buf_sprintf("pointer address 0x%" ZIG_PRI_x64 " is not aligned to %" PRIu32 " bytes", val->data.x_ptr.data.hard_coded_addr.addr, align_bytes)); return ira->codegen->invalid_instruction; } -- cgit v1.2.3