From a859f94644cb362d84d3f9d72bc02b00a75fc32a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 14 Mar 2022 16:21:11 -0700 Subject: stage2: LLVM codegen of arrays should use type length, not value length It is possible for the value length to be longer than the type because we allow in-memory coercing of types such as `[5:0]u8` to `[5]u8`. In such a case, the value length is 6 but the type length if 5. The `.repeated` value type already got this right, so this is extending similar logic out to `.aggregate` and `.bytes`. Both scenarios are tested in behavior tests. Fixes #11165 --- src/codegen/llvm.zig | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/codegen/llvm.zig') diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 4aba6de5a3..786f77d946 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1507,7 +1507,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. ); }, @@ -1515,10 +1515,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]); } -- cgit v1.2.3