Merge pull request #11167 from mitchellh/codegen-arrays

stage2: codegen of arrays should use type length, not value length
This commit is contained in:
Andrew Kelley 2022-03-15 00:40:32 -04:00 committed by GitHub
commit a2a5d3c288
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 21 deletions

View File

@ -207,29 +207,18 @@ pub fn generateSymbol(
.bytes => { .bytes => {
// TODO populate .debug_info for the array // TODO populate .debug_info for the array
const payload = typed_value.val.castTag(.bytes).?; const payload = typed_value.val.castTag(.bytes).?;
if (typed_value.ty.sentinel()) |sentinel| { const len = @intCast(usize, typed_value.ty.arrayLenIncludingSentinel());
try code.ensureUnusedCapacity(payload.data.len + 1); // The bytes payload already includes the sentinel, if any
code.appendSliceAssumeCapacity(payload.data); try code.ensureUnusedCapacity(len);
switch (try generateSymbol(bin_file, src_loc, .{ code.appendSliceAssumeCapacity(payload.data[0..len]);
.ty = typed_value.ty.elemType(),
.val = sentinel,
}, code, debug_output, reloc_info)) {
.appended => return Result{ .appended = {} },
.externally_managed => |slice| {
code.appendSliceAssumeCapacity(slice);
return Result{ .appended = {} }; return Result{ .appended = {} };
}, },
.fail => |em| return Result{ .fail = em },
}
} else {
return Result{ .externally_managed = payload.data };
}
},
.aggregate => { .aggregate => {
// TODO populate .debug_info for the array // TODO populate .debug_info for the array
const elem_vals = typed_value.val.castTag(.aggregate).?.data; const elem_vals = typed_value.val.castTag(.aggregate).?.data;
const elem_ty = typed_value.ty.elemType(); const elem_ty = typed_value.ty.elemType();
for (elem_vals) |elem_val| { const len = @intCast(usize, typed_value.ty.arrayLenIncludingSentinel());
for (elem_vals[0..len]) |elem_val| {
switch (try generateSymbol(bin_file, src_loc, .{ switch (try generateSymbol(bin_file, src_loc, .{
.ty = elem_ty, .ty = elem_ty,
.val = elem_val, .val = elem_val,

View File

@ -1550,7 +1550,7 @@ pub const DeclGen = struct {
const bytes = tv.val.castTag(.bytes).?.data; const bytes = tv.val.castTag(.bytes).?.data;
return dg.context.constString( return dg.context.constString(
bytes.ptr, bytes.ptr,
@intCast(c_uint, bytes.len), @intCast(c_uint, tv.ty.arrayLenIncludingSentinel()),
.True, // don't null terminate. bytes has the sentinel, if any. .True, // don't null terminate. bytes has the sentinel, if any.
); );
}, },
@ -1558,10 +1558,11 @@ pub const DeclGen = struct {
const elem_vals = tv.val.castTag(.aggregate).?.data; const elem_vals = tv.val.castTag(.aggregate).?.data;
const elem_ty = tv.ty.elemType(); const elem_ty = tv.ty.elemType();
const gpa = dg.gpa; const gpa = dg.gpa;
const llvm_elems = try gpa.alloc(*const llvm.Value, elem_vals.len); const len = @intCast(usize, tv.ty.arrayLenIncludingSentinel());
const llvm_elems = try gpa.alloc(*const llvm.Value, len);
defer gpa.free(llvm_elems); defer gpa.free(llvm_elems);
var need_unnamed = false; var need_unnamed = false;
for (elem_vals) |elem_val, i| { for (elem_vals[0..len]) |elem_val, i| {
llvm_elems[i] = try dg.genTypedValue(.{ .ty = elem_ty, .val = elem_val }); llvm_elems[i] = try dg.genTypedValue(.{ .ty = elem_ty, .val = elem_val });
need_unnamed = need_unnamed or dg.isUnnamedType(elem_ty, llvm_elems[i]); need_unnamed = need_unnamed or dg.isUnnamedType(elem_ty, llvm_elems[i]);
} }

View File

@ -62,6 +62,7 @@ test {
_ = @import("behavior/bugs/11100.zig"); _ = @import("behavior/bugs/11100.zig");
_ = @import("behavior/bugs/10970.zig"); _ = @import("behavior/bugs/10970.zig");
_ = @import("behavior/bugs/11046.zig"); _ = @import("behavior/bugs/11046.zig");
_ = @import("behavior/bugs/11165.zig");
_ = @import("behavior/call.zig"); _ = @import("behavior/call.zig");
_ = @import("behavior/cast.zig"); _ = @import("behavior/cast.zig");
_ = @import("behavior/comptime_memory.zig"); _ = @import("behavior/comptime_memory.zig");

View File

@ -0,0 +1,48 @@
const builtin = @import("builtin");
test "bytes" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
const S = struct {
a: u32,
c: [5]u8,
};
const U = union {
s: S,
};
const s_1 = S{
.a = undefined,
.c = "12345".*, // this caused problems
};
_ = s_1;
var u_2 = U{ .s = s_1 };
_ = u_2;
}
test "aggregate" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
const S = struct {
a: u32,
c: [5]u8,
};
const U = union {
s: S,
};
const c = [5:0]u8{ 1, 2, 3, 4, 5 };
const s_1 = S{
.a = undefined,
.c = c, // this caused problems
};
_ = s_1;
var u_2 = U{ .s = s_1 };
_ = u_2;
}