Commit 562ac8be48
Changed files (7)
src
test
src/arch/wasm/CodeGen.zig
@@ -2289,6 +2289,14 @@ fn lowerParentPtr(self: *Self, ptr_val: Value, ptr_child_ty: Type) InnerError!WV
const offset = @intCast(u32, std.mem.alignForwardGeneric(u64, layout.tag_size, layout.tag_align));
break :blk offset;
},
+ .Pointer => switch (parent_ty.ptrSize()) {
+ .Slice => switch (field_ptr.field_index) {
+ 0 => 0,
+ 1 => self.ptrSize(),
+ else => unreachable,
+ },
+ else => unreachable,
+ },
else => unreachable,
};
src/codegen/c.zig
@@ -485,14 +485,24 @@ pub const DeclGen = struct {
const field_ptr = ptr_val.castTag(.field_ptr).?.data;
const container_ty = field_ptr.container_ty;
const index = field_ptr.field_index;
- const field_name = switch (container_ty.zigTypeTag()) {
- .Struct => container_ty.structFields().keys()[index],
- .Union => container_ty.unionFields().keys()[index],
- else => unreachable,
- };
- const field_ty = switch (container_ty.zigTypeTag()) {
- .Struct => container_ty.structFields().values()[index].ty,
- .Union => container_ty.unionFields().values()[index].ty,
+ const FieldInfo = struct { name: []const u8, ty: Type };
+ const field_info: FieldInfo = switch (container_ty.zigTypeTag()) {
+ .Struct => .{
+ .name = container_ty.structFields().keys()[index],
+ .ty = container_ty.structFields().values()[index].ty,
+ },
+ .Union => .{
+ .name = container_ty.unionFields().keys()[index],
+ .ty = container_ty.unionFields().values()[index].ty,
+ },
+ .Pointer => switch (container_ty.ptrSize()) {
+ .Slice => switch (index) {
+ 0 => FieldInfo{ .name = "ptr", .ty = container_ty.childType() },
+ 1 => FieldInfo{ .name = "len", .ty = Type.usize },
+ else => unreachable,
+ },
+ else => unreachable,
+ },
else => unreachable,
};
var container_ptr_ty_pl: Type.Payload.ElemType = .{
@@ -501,16 +511,16 @@ pub const DeclGen = struct {
};
const container_ptr_ty = Type.initPayload(&container_ptr_ty_pl.base);
- if (field_ty.hasRuntimeBitsIgnoreComptime()) {
+ if (field_info.ty.hasRuntimeBitsIgnoreComptime()) {
try writer.writeAll("&(");
try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty);
if (field_ptr.container_ty.tag() == .union_tagged or field_ptr.container_ty.tag() == .union_safety_tagged) {
- try writer.print(")->payload.{ }", .{fmtIdent(field_name)});
+ try writer.print(")->payload.{ }", .{fmtIdent(field_info.name)});
} else {
- try writer.print(")->{ }", .{fmtIdent(field_name)});
+ try writer.print(")->{ }", .{fmtIdent(field_info.name)});
}
} else {
- try dg.renderParentPtr(writer, field_ptr.container_ptr, field_ty);
+ try dg.renderParentPtr(writer, field_ptr.container_ptr, field_info.ty);
}
},
.elem_ptr => {
src/codegen/llvm.zig
@@ -3938,6 +3938,15 @@ pub const DeclGen = struct {
const parent_llvm_ty = try dg.lowerType(parent_ty);
break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
},
+ .Pointer => {
+ assert(parent_ty.isSlice());
+ const indices: [2]*llvm.Value = .{
+ llvm_u32.constInt(0, .False),
+ llvm_u32.constInt(field_index, .False),
+ };
+ const parent_llvm_ty = try dg.lowerType(parent_ty);
+ break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
+ },
else => unreachable,
}
},
src/codegen.zig
@@ -363,11 +363,21 @@ pub fn generateSymbol(
const mod = bin_file.options.module.?;
const decl = mod.declPtr(decl_index);
const addend = blk: {
- switch (decl.ty.tag()) {
- .@"struct" => {
+ switch (decl.ty.zigTypeTag()) {
+ .Struct => {
const addend = decl.ty.structFieldOffset(field_ptr.field_index, target);
break :blk @intCast(u32, addend);
},
+ .Pointer => {
+ assert(decl.ty.isSlice());
+ var buf: Type.SlicePtrFieldTypeBuffer = undefined;
+ const addend = switch (field_ptr.field_index) {
+ 0 => 0,
+ 1 => decl.ty.slicePtrFieldType(&buf).abiSize(target),
+ else => unreachable,
+ };
+ break :blk @intCast(u32, addend);
+ },
else => return Result{
.fail = try ErrorMsg.create(
bin_file.allocator,
test/behavior/bugs/13068.zig
@@ -0,0 +1,15 @@
+const std = @import("std");
+const builtin = @import("builtin");
+
+pub const allocator = std.heap.page_allocator;
+var list = std.ArrayList(u32).init(allocator);
+
+test {
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+
+ list.items.len = 0;
+}
test/behavior/slice.zig
@@ -2,6 +2,7 @@ const builtin = @import("builtin");
const std = @import("std");
const expect = std.testing.expect;
const expectEqualSlices = std.testing.expectEqualSlices;
+const expectEqualStrings = std.testing.expectEqualStrings;
const expectEqual = std.testing.expectEqual;
const mem = std.mem;
@@ -686,8 +687,6 @@ test "slice len modification at comptime" {
}
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;
@@ -700,8 +699,6 @@ test "slice field ptr const" {
}
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;
@@ -712,3 +709,18 @@ test "slice field ptr var" {
try expectEqual(*[]const u8, @TypeOf(&const_ptr_var_slice.*));
try expectEqual(*[*]const u8, @TypeOf(&const_ptr_var_slice.ptr));
}
+
+test "global slice field access" {
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ var slice: []const u8 = undefined;
+ };
+ S.slice = "string";
+ S.slice.ptr += 1;
+ S.slice.len -= 2;
+ try expectEqualStrings("trin", S.slice);
+}
test/behavior.zig
@@ -100,6 +100,7 @@ test {
_ = @import("behavior/bugs/12928.zig");
_ = @import("behavior/bugs/12945.zig");
_ = @import("behavior/bugs/12984.zig");
+ _ = @import("behavior/bugs/13068.zig");
_ = @import("behavior/bugs/13128.zig");
_ = @import("behavior/byteswap.zig");
_ = @import("behavior/byval_arg_var.zig");