From 423a19fa60d2b0a11fc2fb43b12001320c2c53c5 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Fri, 22 Jul 2022 21:10:50 +0300 Subject: [PATCH] Sema: add error for dereferencing invalid payload ptr at comptime --- src/Sema.zig | 12 +++++-- ...encing_invalid_payload_ptr_at_comptime.zig | 33 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 test/cases/compile_errors/dereferencing_invalid_payload_ptr_at_comptime.zig diff --git a/src/Sema.zig b/src/Sema.zig index 76b5dcb8c0..8023e60c7d 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -22946,8 +22946,13 @@ fn beginComptimePtrLoad( (try sema.coerceInMemoryAllowed(block, tv.ty, payload_ptr.container_ty, false, target, src, src)) == .ok; if (coerce_in_mem_ok) { const payload_val = switch (ptr_val.tag()) { - .eu_payload_ptr => tv.val.castTag(.eu_payload).?.data, - .opt_payload_ptr => if (tv.val.castTag(.opt_payload)) |some| some.data else tv.val, + .eu_payload_ptr => if (tv.val.castTag(.eu_payload)) |some| some.data else { + return sema.fail(block, src, "attempt to unwrap error: {s}", .{tv.val.castTag(.@"error").?.data.name}); + }, + .opt_payload_ptr => if (tv.val.castTag(.opt_payload)) |some| some.data else opt: { + if (tv.val.isNull()) return sema.fail(block, src, "attempt to use null value", .{}); + break :opt tv.val; + }, else => unreachable, }; tv.* = TypedValue{ .ty = payload_ty, .val = payload_val }; @@ -22957,6 +22962,9 @@ fn beginComptimePtrLoad( deref.pointee = null; break :blk deref; }, + .null_value => { + return sema.fail(block, src, "attempt to use null value", .{}); + }, .zero, .one, diff --git a/test/cases/compile_errors/dereferencing_invalid_payload_ptr_at_comptime.zig b/test/cases/compile_errors/dereferencing_invalid_payload_ptr_at_comptime.zig new file mode 100644 index 0000000000..69457965bb --- /dev/null +++ b/test/cases/compile_errors/dereferencing_invalid_payload_ptr_at_comptime.zig @@ -0,0 +1,33 @@ +const std = @import("std"); + +comptime { + var val: u8 = 15; + var opt_ptr: ?*const u8 = &val; + + const payload_ptr = &opt_ptr.?; + opt_ptr = null; + _ = payload_ptr.*.*; +} +comptime { + var opt: ?u8 = 15; + + const payload_ptr = &opt.?; + opt = null; + _ = payload_ptr.*; +} +comptime { + var val: u8 = 15; + var err_union: anyerror!u8 = val; + + const payload_ptr = &(err_union catch unreachable); + err_union = error.Foo; + _ = payload_ptr.*; +} + +// error +// backend=stage2 +// target=native +// +// :9:20: error: attempt to use null value +// :16:20: error: attempt to use null value +// :24:20: error: attempt to unwrap error: Foo