Commit 409cf4aeb8

Veikka Tuominen <git@vexu.eu>
2022-09-29 14:04:07
Sema: use correct ptr ty to check for attributes of slice field ptr
Closes #12870 Closes #13006
1 parent 36d2a55
Changed files (2)
src
test
behavior
src/Sema.zig
@@ -21664,14 +21664,17 @@ fn fieldPtr(
             else
                 object_ptr;
 
+            const attr_ptr_ty = if (is_pointer_to) object_ty else object_ptr_ty;
+
             if (mem.eql(u8, field_name, "ptr")) {
                 const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer);
                 const slice_ptr_ty = inner_ty.slicePtrFieldType(buf);
 
                 const result_ty = try Type.ptr(sema.arena, sema.mod, .{
                     .pointee_type = slice_ptr_ty,
-                    .mutable = object_ptr_ty.ptrIsMutable(),
-                    .@"addrspace" = object_ptr_ty.ptrAddressSpace(),
+                    .mutable = attr_ptr_ty.ptrIsMutable(),
+                    .@"volatile" = attr_ptr_ty.isVolatilePtr(),
+                    .@"addrspace" = attr_ptr_ty.ptrAddressSpace(),
                 });
 
                 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
@@ -21690,8 +21693,9 @@ fn fieldPtr(
             } else if (mem.eql(u8, field_name, "len")) {
                 const result_ty = try Type.ptr(sema.arena, sema.mod, .{
                     .pointee_type = Type.usize,
-                    .mutable = object_ptr_ty.ptrIsMutable(),
-                    .@"addrspace" = object_ptr_ty.ptrAddressSpace(),
+                    .mutable = attr_ptr_ty.ptrIsMutable(),
+                    .@"volatile" = attr_ptr_ty.isVolatilePtr(),
+                    .@"addrspace" = attr_ptr_ty.ptrAddressSpace(),
                 });
 
                 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
test/behavior/slice.zig
@@ -684,3 +684,31 @@ test "slice len modification at comptime" {
         try expect(items[1] == 1);
     }
 }
+
+test "slice field ptr const" {
+    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+
+    const const_slice: []const u8 = "string";
+
+    const const_ptr_const_slice = &const_slice;
+    try expectEqual(*const []const u8, @TypeOf(&const_ptr_const_slice.*));
+    try expectEqual(*const [*]const u8, @TypeOf(&const_ptr_const_slice.ptr));
+
+    var var_ptr_const_slice = &const_slice;
+    try expectEqual(*const []const u8, @TypeOf(&var_ptr_const_slice.*));
+    try expectEqual(*const [*]const u8, @TypeOf(&var_ptr_const_slice.ptr));
+}
+
+test "slice field ptr var" {
+    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+
+    var var_slice: []const u8 = "string";
+
+    var var_ptr_var_slice = &var_slice;
+    try expectEqual(*[]const u8, @TypeOf(&var_ptr_var_slice.*));
+    try expectEqual(*[*]const u8, @TypeOf(&var_ptr_var_slice.ptr));
+
+    const const_ptr_var_slice = &var_slice;
+    try expectEqual(*[]const u8, @TypeOf(&const_ptr_var_slice.*));
+    try expectEqual(*[*]const u8, @TypeOf(&const_ptr_var_slice.ptr));
+}