From 409cf4aeb826d8f7c35f0aa10bb0a8fe45188555 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Thu, 29 Sep 2022 15:04:07 +0300 Subject: [PATCH] Sema: use correct ptr ty to check for attributes of slice field ptr Closes #12870 Closes #13006 --- src/Sema.zig | 12 ++++++++---- test/behavior/slice.zig | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index 5e65132510..7ad7491ea1 100644 --- a/src/Sema.zig +++ b/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| { diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index e5cb8ea408..5aeb6a3414 100644 --- a/test/behavior/slice.zig +++ b/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)); +}