Commit 423a19fa60

Veikka Tuominen <git@vexu.eu>
2022-07-22 20:10:50
Sema: add error for dereferencing invalid payload ptr at comptime
1 parent 03b1fbe
Changed files (2)
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,
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