Commit 8f037db885

Veikka Tuominen <git@vexu.eu>
2022-03-07 19:41:48
stage2: correct constness of allocs
1 parent 1f4a097
Changed files (5)
src/AstGen.zig
@@ -2138,6 +2138,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
             .alloc_inferred_mut,
             .alloc_inferred_comptime,
             .alloc_inferred_comptime_mut,
+            .make_ptr_const,
             .array_cat,
             .array_mul,
             .array_type,
@@ -2754,12 +2755,13 @@ fn varDecl(
             if (resolve_inferred_alloc != .none) {
                 _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node);
             }
+            const const_ptr = try gz.addUnNode(.make_ptr_const, init_scope.rl_ptr, node);
             const sub_scope = try block_arena.create(Scope.LocalPtr);
             sub_scope.* = .{
                 .parent = scope,
                 .gen_zir = gz,
                 .name = ident_name,
-                .ptr = init_scope.rl_ptr,
+                .ptr = const_ptr,
                 .token_src = name_token,
                 .maybe_comptime = true,
                 .id_cat = .@"local constant",
src/print_zir.zig
@@ -238,6 +238,7 @@ const Writer = struct {
             .field_base_ptr,
             .validate_array_init_ty,
             .validate_struct_init_ty,
+            .make_ptr_const,
             => try self.writeUnNode(stream, inst),
 
             .ref,
src/Sema.zig
@@ -607,6 +607,7 @@ fn analyzeBodyInner(
             .alloc_inferred_comptime_mut  => try sema.zirAllocInferredComptime(inst, Type.initTag(.inferred_alloc_mut)),
             .alloc_mut                    => try sema.zirAllocMut(block, inst),
             .alloc_comptime_mut           => try sema.zirAllocComptime(block, inst),
+            .make_ptr_const               => try sema.zirMakePtrConst(block, inst),
             .anyframe_type                => try sema.zirAnyframeType(block, inst),
             .array_cat                    => try sema.zirArrayCat(block, inst),
             .array_mul                    => try sema.zirArrayMul(block, inst),
@@ -2409,6 +2410,21 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
     return sema.analyzeComptimeAlloc(block, var_ty, 0, ty_src);
 }
 
+fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
+    const inst_data = sema.code.instructions.items(.data)[inst].un_node;
+    const ptr = sema.resolveInst(inst_data.operand);
+    const ptr_ty = sema.typeOf(ptr);
+    var ptr_info = ptr_ty.ptrInfo().data;
+    ptr_info.mutable = false;
+    const const_ptr_ty = try Type.ptr(sema.arena, sema.mod.getTarget(), ptr_info);
+
+    if (try sema.resolveMaybeUndefVal(block, inst_data.src(), ptr)) |val| {
+        return sema.addConstant(const_ptr_ty, val);
+    }
+    try sema.requireRuntimeBlock(block, inst_data.src());
+    return block.addBitCast(const_ptr_ty, ptr);
+}
+
 fn zirAllocInferredComptime(
     sema: *Sema,
     inst: Zir.Inst.Index,
src/Zir.zig
@@ -954,6 +954,10 @@ pub const Inst = struct {
         /// is the allocation that needs to have its type inferred.
         /// Uses the `un_node` field. The AST node is the var decl.
         resolve_inferred_alloc,
+        /// Turns a pointer coming from an `alloc`, `alloc_inferred`, `alloc_inferred_comptime` or
+        /// `Extended.alloc` into a constant version of the same pointer.
+        /// Uses the `un_node` union field.
+        make_ptr_const,
 
         /// Implements `resume` syntax. Uses `un_node` field.
         @"resume",
@@ -993,6 +997,7 @@ pub const Inst = struct {
                 .alloc_inferred_mut,
                 .alloc_inferred_comptime,
                 .alloc_inferred_comptime_mut,
+                .make_ptr_const,
                 .array_cat,
                 .array_mul,
                 .array_type,
@@ -1496,6 +1501,7 @@ pub const Inst = struct {
                 .alloc_inferred_comptime = .node,
                 .alloc_inferred_comptime_mut = .node,
                 .resolve_inferred_alloc = .un_node,
+                .make_ptr_const = .un_node,
 
                 .@"resume" = .un_node,
                 .@"await" = .un_node,
test/behavior/bugs/5474.zig
@@ -54,8 +54,6 @@ test "pointer-to-array constness for zero-size elements, var" {
 }
 
 test "pointer-to-array constness for zero-size elements, const" {
-    if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
     try constant();
     comptime try constant();
 }