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(...@@ -207,29 +207,18 @@ pub fn generateSymbol(
207 .bytes => {207 .bytes => {
208 // TODO populate .debug_info for the array208 // TODO populate .debug_info for the array
209 const payload = typed_value.val.castTag(.bytes).?;209 const payload = typed_value.val.castTag(.bytes).?;
210 if (typed_value.ty.sentinel()) |sentinel| {210 const len = @intCast(usize, typed_value.ty.arrayLenIncludingSentinel());
211 try code.ensureUnusedCapacity(payload.data.len + 1);211 // The bytes payload already includes the sentinel, if any
212 code.appendSliceAssumeCapacity(payload.data);212 try code.ensureUnusedCapacity(len);
213 switch (try generateSymbol(bin_file, src_loc, .{213 code.appendSliceAssumeCapacity(payload.data[0..len]);
214 .ty = typed_value.ty.elemType(),214 return Result{ .appended = {} };
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 }
227 },215 },
228 .aggregate => {216 .aggregate => {
229 // TODO populate .debug_info for the array217 // TODO populate .debug_info for the array
230 const elem_vals = typed_value.val.castTag(.aggregate).?.data;218 const elem_vals = typed_value.val.castTag(.aggregate).?.data;
231 const elem_ty = typed_value.ty.elemType();219 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| {
233 switch (try generateSymbol(bin_file, src_loc, .{222 switch (try generateSymbol(bin_file, src_loc, .{
234 .ty = elem_ty,223 .ty = elem_ty,
235 .val = elem_val,224 .val = elem_val,
src/codegen/llvm.zig+4-3
...@@ -1550,7 +1550,7 @@ pub const DeclGen = struct {...@@ -1550,7 +1550,7 @@ pub const DeclGen = struct {
1550 const bytes = tv.val.castTag(.bytes).?.data;1550 const bytes = tv.val.castTag(.bytes).?.data;
1551 return dg.context.constString(1551 return dg.context.constString(
1552 bytes.ptr,1552 bytes.ptr,
1553 @intCast(c_uint, bytes.len),1553 @intCast(c_uint, tv.ty.arrayLenIncludingSentinel()),
1554 .True, // don't null terminate. bytes has the sentinel, if any.1554 .True, // don't null terminate. bytes has the sentinel, if any.
1555 );1555 );
1556 },1556 },
...@@ -1558,10 +1558,11 @@ pub const DeclGen = struct {...@@ -1558,10 +1558,11 @@ pub const DeclGen = struct {
1558 const elem_vals = tv.val.castTag(.aggregate).?.data;1558 const elem_vals = tv.val.castTag(.aggregate).?.data;
1559 const elem_ty = tv.ty.elemType();1559 const elem_ty = tv.ty.elemType();
1560 const gpa = dg.gpa;1560 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);
1562 defer gpa.free(llvm_elems);1563 defer gpa.free(llvm_elems);
1563 var need_unnamed = false;1564 var need_unnamed = false;
1564 for (elem_vals) |elem_val, i| {1565 for (elem_vals[0..len]) |elem_val, i| {
1565 llvm_elems[i] = try dg.genTypedValue(.{ .ty = elem_ty, .val = elem_val });1566 llvm_elems[i] = try dg.genTypedValue(.{ .ty = elem_ty, .val = elem_val });
1566 need_unnamed = need_unnamed or dg.isUnnamedType(elem_ty, llvm_elems[i]);1567 need_unnamed = need_unnamed or dg.isUnnamedType(elem_ty, llvm_elems[i]);
1567 }1568 }
test/behavior.zig+1
...@@ -62,6 +62,7 @@ test {...@@ -62,6 +62,7 @@ test {
62 _ = @import("behavior/bugs/11100.zig");62 _ = @import("behavior/bugs/11100.zig");
63 _ = @import("behavior/bugs/10970.zig");63 _ = @import("behavior/bugs/10970.zig");
64 _ = @import("behavior/bugs/11046.zig");64 _ = @import("behavior/bugs/11046.zig");
65 _ = @import("behavior/bugs/11165.zig");
65 _ = @import("behavior/call.zig");66 _ = @import("behavior/call.zig");
66 _ = @import("behavior/cast.zig");67 _ = @import("behavior/cast.zig");
67 _ = @import("behavior/comptime_memory.zig");68 _ = @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}