| author | |
| committer | |
| log | a2a5d3c2885cacf16d55d7943d10a81a5dc31b8a |
| tree | 1061a7063f360df1f547a959ca174bda4d9db02f |
| parent | c757f197903940115c1d42883240ec1fe7ef660c |
| parent | 67647154c1c307dcf34413d013e6cd4a1df81945 |
| signature |
stage2: codegen of arrays should use type length, not value length4 files changed, 60 insertions(+), 21 deletions(-)
src/codegen.zig+7-18| ... | ... | @@ -207,29 +207,18 @@ pub fn generateSymbol( |
| 207 | 207 | .bytes => { |
| 208 | 208 | // TODO populate .debug_info for the array |
| 209 | 209 | 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 = {} }; | |
| 227 | 215 | }, |
| 228 | 216 | .aggregate => { |
| 229 | 217 | // TODO populate .debug_info for the array |
| 230 | 218 | const elem_vals = typed_value.val.castTag(.aggregate).?.data; |
| 231 | 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 | 222 | switch (try generateSymbol(bin_file, src_loc, .{ |
| 234 | 223 | .ty = elem_ty, |
| 235 | 224 | .val = elem_val, |
src/codegen/llvm.zig+4-3| ... | ... | @@ -1550,7 +1550,7 @@ pub const DeclGen = struct { |
| 1550 | 1550 | const bytes = tv.val.castTag(.bytes).?.data; |
| 1551 | 1551 | return dg.context.constString( |
| 1552 | 1552 | bytes.ptr, |
| 1553 | @intCast(c_uint, bytes.len), | |
| 1553 | @intCast(c_uint, tv.ty.arrayLenIncludingSentinel()), | |
| 1554 | 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 | 1558 | const elem_vals = tv.val.castTag(.aggregate).?.data; |
| 1559 | 1559 | const elem_ty = tv.ty.elemType(); |
| 1560 | 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 | 1563 | defer gpa.free(llvm_elems); |
| 1563 | 1564 | var need_unnamed = false; |
| 1564 | for (elem_vals) |elem_val, i| { | |
| 1565 | for (elem_vals[0..len]) |elem_val, i| { | |
| 1565 | 1566 | llvm_elems[i] = try dg.genTypedValue(.{ .ty = elem_ty, .val = elem_val }); |
| 1566 | 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 | 62 | _ = @import("behavior/bugs/11100.zig"); |
| 63 | 63 | _ = @import("behavior/bugs/10970.zig"); |
| 64 | 64 | _ = @import("behavior/bugs/11046.zig"); |
| 65 | _ = @import("behavior/bugs/11165.zig"); | |
| 65 | 66 | _ = @import("behavior/call.zig"); |
| 66 | 67 | _ = @import("behavior/cast.zig"); |
| 67 | 68 | _ = @import("behavior/comptime_memory.zig"); |
test/behavior/bugs/11165.zig created+48| ... | ... | @@ -0,0 +1,48 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | ||
| 3 | test "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 | ||
| 26 | test "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 | } |