Commit c0c9d11d8c

Michael Dusan <michael.dusan@gmail.com>
2020-06-05 06:48:36
stage1: fix constness in some corner cases
- for one-possible-value types, ir_analyze_struct_field_ptr() no longer hardcodes const/volatile - when slicing arrays, ir_analyze_instruction_slice() no longer consults ConstValSpecialStatic closes #5474
1 parent f839d34
Changed files (3)
src
test
stage1
behavior
src/ir.cpp
@@ -21924,7 +21924,9 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins
         case OnePossibleValueYes: {
             IrInstGen *elem = ir_const_move(ira, source_instr,
                  get_the_one_possible_value(ira->codegen, field_type));
-            return ir_get_ref(ira, source_instr, elem, false, false);
+            return ir_get_ref(ira, source_instr, elem,
+                struct_ptr->value->type->data.pointer.is_const,
+                struct_ptr->value->type->data.pointer.is_volatile);
         }
         case OnePossibleValueNo:
             break;
@@ -27097,10 +27099,8 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
 
     if (array_type->id == ZigTypeIdArray) {
         elem_type = array_type->data.array.child_type;
-        bool is_comptime_const = ptr_ptr->value->special == ConstValSpecialStatic &&
-            ptr_ptr->value->data.x_ptr.mut == ConstPtrMutComptimeConst;
         non_sentinel_slice_ptr_type = get_pointer_to_type_extra(ira->codegen, elem_type,
-            ptr_ptr_type->data.pointer.is_const || is_comptime_const,
+            ptr_ptr_type->data.pointer.is_const,
             ptr_ptr_type->data.pointer.is_volatile,
             PtrLenUnknown,
             ptr_ptr_type->data.pointer.explicit_alignment, 0, 0, false);
test/stage1/behavior/bugs/5474.zig
@@ -0,0 +1,57 @@
+const std = @import("std");
+
+// baseline (control) struct with array of scalar
+const Box0 = struct {
+    items: [4]Item,
+
+    const Item = struct {
+        num: u32,
+    };
+};
+
+// struct with array of empty struct
+const Box1 = struct {
+    items: [4]Item,
+
+    const Item = struct {};
+};
+
+// struct with array of zero-size struct
+const Box2 = struct {
+    items: [4]Item,
+
+    const Item = struct {
+        nothing: void,
+    };
+};
+
+fn doTest() void {
+    // var
+    {
+        var box0: Box0 = .{ .items = undefined };
+        std.testing.expect(@typeInfo(@TypeOf(box0.items[0..])).Pointer.is_const == false);
+
+        var box1: Box1 = .{ .items = undefined };
+        std.testing.expect(@typeInfo(@TypeOf(box1.items[0..])).Pointer.is_const == false);
+
+        var box2: Box2 = .{ .items = undefined };
+        std.testing.expect(@typeInfo(@TypeOf(box2.items[0..])).Pointer.is_const == false);
+    }
+
+    // const
+    {
+        const box0: Box0 = .{ .items = undefined };
+        std.testing.expect(@typeInfo(@TypeOf(box0.items[0..])).Pointer.is_const == true);
+
+        const box1: Box1 = .{ .items = undefined };
+        std.testing.expect(@typeInfo(@TypeOf(box1.items[0..])).Pointer.is_const == true);
+
+        const box2: Box2 = .{ .items = undefined };
+        std.testing.expect(@typeInfo(@TypeOf(box2.items[0..])).Pointer.is_const == true);
+    }
+}
+
+test "pointer-to-array constness for zero-size elements" {
+    doTest();
+    comptime doTest();
+}
test/stage1/behavior.zig
@@ -50,6 +50,7 @@ comptime {
     _ = @import("behavior/bugs/4769_b.zig");
     _ = @import("behavior/bugs/4769_c.zig");
     _ = @import("behavior/bugs/4954.zig");
+    _ = @import("behavior/bugs/5474.zig");
     _ = @import("behavior/bugs/5487.zig");
     _ = @import("behavior/bugs/394.zig");
     _ = @import("behavior/bugs/421.zig");