authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-15 00:40:32-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-03-15 00:40:32-04:00
loga2a5d3c2885cacf16d55d7943d10a81a5dc31b8a
tree1061a7063f360df1f547a959ca174bda4d9db02f
parentc757f197903940115c1d42883240ec1fe7ef660c
parent67647154c1c307dcf34413d013e6cd4a1df81945
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11167 from mitchellh/codegen-arrays

stage2: codegen of arrays should use type length, not value length

4 files changed, 60 insertions(+), 21 deletions(-)

src/codegen.zig+7-18
......@@ -207,29 +207,18 @@ pub fn generateSymbol(
207207 .bytes => {
208208 // TODO populate .debug_info for the array
209209 const payload = typed_value.val.castTag(.bytes).?;
210 if (typed_value.ty.sentinel()) |sentinel| {
211 try code.ensureUnusedCapacity(payload.data.len + 1);
212 code.appendSliceAssumeCapacity(payload.data);
213 switch (try generateSymbol(bin_file, src_loc, .{
214 .ty = typed_value.ty.elemType(),
215 .val = sentinel,
216 }, code, debug_output, reloc_info)) {
217 .appended => return Result{ .appended = {} },
218 .externally_managed => |slice| {
219 code.appendSliceAssumeCapacity(slice);
220 return Result{ .appended = {} };
221 },
222 .fail => |em| return Result{ .fail = em },
223 }
224 } else {
225 return Result{ .externally_managed = payload.data };
226 }
210 const len = @intCast(usize, typed_value.ty.arrayLenIncludingSentinel());
211 // The bytes payload already includes the sentinel, if any
212 try code.ensureUnusedCapacity(len);
213 code.appendSliceAssumeCapacity(payload.data[0..len]);
214 return Result{ .appended = {} };
227215 },
228216 .aggregate => {
229217 // TODO populate .debug_info for the array
230218 const elem_vals = typed_value.val.castTag(.aggregate).?.data;
231219 const elem_ty = typed_value.ty.elemType();
232 for (elem_vals) |elem_val| {
220 const len = @intCast(usize, typed_value.ty.arrayLenIncludingSentinel());
221 for (elem_vals[0..len]) |elem_val| {
233222 switch (try generateSymbol(bin_file, src_loc, .{
234223 .ty = elem_ty,
235224 .val = elem_val,
src/codegen/llvm.zig+4-3
......@@ -1550,7 +1550,7 @@ pub const DeclGen = struct {
15501550 const bytes = tv.val.castTag(.bytes).?.data;
15511551 return dg.context.constString(
15521552 bytes.ptr,
1553 @intCast(c_uint, bytes.len),
1553 @intCast(c_uint, tv.ty.arrayLenIncludingSentinel()),
15541554 .True, // don't null terminate. bytes has the sentinel, if any.
15551555 );
15561556 },
......@@ -1558,10 +1558,11 @@ pub const DeclGen = struct {
15581558 const elem_vals = tv.val.castTag(.aggregate).?.data;
15591559 const elem_ty = tv.ty.elemType();
15601560 const gpa = dg.gpa;
1561 const llvm_elems = try gpa.alloc(*const llvm.Value, elem_vals.len);
1561 const len = @intCast(usize, tv.ty.arrayLenIncludingSentinel());
1562 const llvm_elems = try gpa.alloc(*const llvm.Value, len);
15621563 defer gpa.free(llvm_elems);
15631564 var need_unnamed = false;
1564 for (elem_vals) |elem_val, i| {
1565 for (elem_vals[0..len]) |elem_val, i| {
15651566 llvm_elems[i] = try dg.genTypedValue(.{ .ty = elem_ty, .val = elem_val });
15661567 need_unnamed = need_unnamed or dg.isUnnamedType(elem_ty, llvm_elems[i]);
15671568 }
test/behavior.zig+1
......@@ -62,6 +62,7 @@ test {
6262 _ = @import("behavior/bugs/11100.zig");
6363 _ = @import("behavior/bugs/10970.zig");
6464 _ = @import("behavior/bugs/11046.zig");
65 _ = @import("behavior/bugs/11165.zig");
6566 _ = @import("behavior/call.zig");
6667 _ = @import("behavior/cast.zig");
6768 _ = @import("behavior/comptime_memory.zig");
test/behavior/bugs/11165.zig created+48
......@@ -0,0 +1,48 @@
1const builtin = @import("builtin");
2
3test "bytes" {
4 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
5 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
6
7 const S = struct {
8 a: u32,
9 c: [5]u8,
10 };
11
12 const U = union {
13 s: S,
14 };
15
16 const s_1 = S{
17 .a = undefined,
18 .c = "12345".*, // this caused problems
19 };
20 _ = s_1;
21
22 var u_2 = U{ .s = s_1 };
23 _ = u_2;
24}
25
26test "aggregate" {
27 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
28 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
29
30 const S = struct {
31 a: u32,
32 c: [5]u8,
33 };
34
35 const U = union {
36 s: S,
37 };
38
39 const c = [5:0]u8{ 1, 2, 3, 4, 5 };
40 const s_1 = S{
41 .a = undefined,
42 .c = c, // this caused problems
43 };
44 _ = s_1;
45
46 var u_2 = U{ .s = s_1 };
47 _ = u_2;
48}