| author | |
| committer | |
| log | 2641feb9b98e794608917231c2fa775ea4daea06 |
| tree | 2036379543467c955752c497ba1c7940fe01576f |
| parent | f1ae688d371f49fdbf65f952d655905c74871fdb |
| parent | 8ea1c1932e7bd869ec77a161da7876d171d4ef1d |
| signature |
llvm: fix use after free with pointers to optional slices2 files changed, 21 insertions(+), 1 deletions(-)
src/codegen/llvm.zig+1-1| ... | ... | @@ -1773,7 +1773,7 @@ pub const Object = struct { |
| 1773 | 1773 | if (ty.optionalReprIsPayload()) { |
| 1774 | 1774 | const ptr_di_ty = try o.lowerDebugType(child_ty, resolve); |
| 1775 | 1775 | // The recursive call to `lowerDebugType` means we can't use `gop` anymore. |
| 1776 | try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty), .{ .mod = o.module }); | |
| 1776 | try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve), .{ .mod = o.module }); | |
| 1777 | 1777 | return ptr_di_ty; |
| 1778 | 1778 | } |
| 1779 | 1779 |
test/behavior/slice.zig+20| ... | ... | @@ -747,3 +747,23 @@ test "slice decays to many pointer" { |
| 747 | 747 | const p: [*:0]const u8 = buf[0..7 :0]; |
| 748 | 748 | try expectEqualStrings(buf[0..7], std.mem.span(p)); |
| 749 | 749 | } |
| 750 | ||
| 751 | test "write through pointer to optional slice arg" { | |
| 752 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | |
| 753 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | |
| 754 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; | |
| 755 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 756 | ||
| 757 | const S = struct { | |
| 758 | fn bar(foo: *?[]const u8) !void { | |
| 759 | foo.* = try baz(); | |
| 760 | } | |
| 761 | ||
| 762 | fn baz() ![]const u8 { | |
| 763 | return "ok"; | |
| 764 | } | |
| 765 | }; | |
| 766 | var foo: ?[]const u8 = null; | |
| 767 | try S.bar(&foo); | |
| 768 | try expectEqualStrings(foo.?, "ok"); | |
| 769 | } |