aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-03-15 00:40:32 -0400
committerGitHub <noreply@github.com>2022-03-15 00:40:32 -0400
commita2a5d3c2885cacf16d55d7943d10a81a5dc31b8a (patch)
tree1061a7063f360df1f547a959ca174bda4d9db02f
parentc757f197903940115c1d42883240ec1fe7ef660c (diff)
parent67647154c1c307dcf34413d013e6cd4a1df81945 (diff)
downloadzig-a2a5d3c2885cacf16d55d7943d10a81a5dc31b8a.tar.gz
zig-a2a5d3c2885cacf16d55d7943d10a81a5dc31b8a.zip
Merge pull request #11167 from mitchellh/codegen-arrays
stage2: codegen of arrays should use type length, not value length
-rw-r--r--src/codegen.zig25
-rw-r--r--src/codegen/llvm.zig7
-rw-r--r--test/behavior.zig1
-rw-r--r--test/behavior/bugs/11165.zig48
4 files changed, 60 insertions, 21 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index 1a30738b07..6d5e140dca 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -207,29 +207,18 @@ pub fn generateSymbol(
.bytes => {
// TODO populate .debug_info for the array
const payload = typed_value.val.castTag(.bytes).?;
- if (typed_value.ty.sentinel()) |sentinel| {
- try code.ensureUnusedCapacity(payload.data.len + 1);
- code.appendSliceAssumeCapacity(payload.data);
- switch (try generateSymbol(bin_file, src_loc, .{
- .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 = {} };
- },
- .fail => |em| return Result{ .fail = em },
- }
- } else {
- return Result{ .externally_managed = payload.data };
- }
+ const len = @intCast(usize, typed_value.ty.arrayLenIncludingSentinel());
+ // The bytes payload already includes the sentinel, if any
+ try code.ensureUnusedCapacity(len);
+ code.appendSliceAssumeCapacity(payload.data[0..len]);
+ return Result{ .appended = {} };
},
.aggregate => {
// TODO populate .debug_info for the array
const elem_vals = typed_value.val.castTag(.aggregate).?.data;
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, .{
.ty = elem_ty,
.val = elem_val,
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 4d59b73f20..7c4455f296 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -1550,7 +1550,7 @@ pub const DeclGen = struct {
const bytes = tv.val.castTag(.bytes).?.data;
return dg.context.constString(
bytes.ptr,
- @intCast(c_uint, bytes.len),
+ @intCast(c_uint, tv.ty.arrayLenIncludingSentinel()),
.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_ty = tv.ty.elemType();
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);
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 });
need_unnamed = need_unnamed or dg.isUnnamedType(elem_ty, llvm_elems[i]);
}
diff --git a/test/behavior.zig b/test/behavior.zig
index b353ee78c9..22298ef191 100644
--- a/test/behavior.zig
+++ b/test/behavior.zig
@@ -62,6 +62,7 @@ test {
_ = @import("behavior/bugs/11100.zig");
_ = @import("behavior/bugs/10970.zig");
_ = @import("behavior/bugs/11046.zig");
+ _ = @import("behavior/bugs/11165.zig");
_ = @import("behavior/call.zig");
_ = @import("behavior/cast.zig");
_ = @import("behavior/comptime_memory.zig");
diff --git a/test/behavior/bugs/11165.zig b/test/behavior/bugs/11165.zig
new file mode 100644
index 0000000000..cf2f9698f9
--- /dev/null
+++ b/test/behavior/bugs/11165.zig
@@ -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;
+}