Skip to content

MultiArrayList can have unexpected results when combining zero sized fields and optional pointers #12781

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Hejsil opened this issue Sep 8, 2022 · 3 comments
Labels
backend-llvm The LLVM backend outputs an LLVM IR Module. bug Observed behavior contradicts documented or intended behavior frontend Tokenization, parsing, AstGen, Sema, and Liveness.
Milestone

Comments

@Hejsil
Copy link
Contributor

Hejsil commented Sep 8, 2022

Zig Version

0.10.0-dev.3885+a7661f115d

Steps to Reproduce

test.zig

const std = @import("std");

const testing = std.testing;

test {
    const S = struct { key: u32, value: void };

    const allocator = std.testing.allocator;
    var list = std.MultiArrayList(S){};
    defer list.deinit(allocator);

    try list.append(allocator, .{ .key = 0, .value = {} });
    const a: ?*const void = &list.items(.value)[0];
    try testing.expect(a != null);
}
$ zig test test.zig

Expected Behavior

All tests pass. We take a pointer to an existing value in the values slices of the list. We store then store this non null pointer in an optional pointer.

Actual Behavior

Test [1/1] test_0... FAIL (TestUnexpectedResult)
/usr/lib/zig/std/testing.zig:351:14: 0x21168f in expect (test)
    if (!ok) return error.TestUnexpectedResult;
             ^
./test.zig:14:5: 0x2117a0 in test_0 (test)
    try testing.expect(a != null);
    ^
0 passed; 0 skipped; 1 failed.
error: the following test command failed with exit code 1:
zig-cache/o/85be9248e4b75e6a5942ec409fcfeca7/test /usr/bin/zig
@Hejsil Hejsil added the bug Observed behavior contradicts documented or intended behavior label Sep 8, 2022
@Hejsil
Copy link
Contributor Author

Hejsil commented Sep 8, 2022

Basically, the problem here is that list.items(.value) returns a slice that points to address 0x0:

const std = @import("std");

const testing = std.testing;

test {
    const S = struct { key: u32, value: void };

    const allocator = std.testing.allocator;
    var list = std.MultiArrayList(S){};
    defer list.deinit(allocator);

    try list.append(allocator, .{ .key = 0, .value = {} });
    std.debug.print("{*}\n", .{list.items(.value).ptr});
}
Test [1/1] test_0... void@0
All 1 tests passed.

@Vexu
Copy link
Member

Vexu commented Sep 8, 2022

Reduction:

test {
    std.debug.print("{*}\n", .{foo()});
}
fn foo() []void {
    const ptr: [*]void = undefined;
    var len: usize = 6;
    return ptr[0..len];
}

@Vexu Vexu added frontend Tokenization, parsing, AstGen, Sema, and Liveness. backend-llvm The LLVM backend outputs an LLVM IR Module. labels Sep 8, 2022
@Vexu Vexu added this to the 0.10.0 milestone Sep 8, 2022
@Hejsil
Copy link
Contributor Author

Hejsil commented Sep 8, 2022

Also of note is this:
#1831 (comment)

@andrewrk andrewrk modified the milestones: 0.10.0, 0.10.1 Oct 12, 2022
@andrewrk andrewrk modified the milestones: 0.10.1, 0.11.0 Jan 10, 2023
@andrewrk andrewrk modified the milestones: 0.11.0, 0.11.1 Jul 20, 2023
@andrewrk andrewrk modified the milestones: 0.11.1, 0.12.0 Jan 29, 2024
@andrewrk andrewrk modified the milestones: 0.12.0, 0.13.0 Mar 22, 2024
@andrewrk andrewrk modified the milestones: 0.14.0, 0.15.0 Feb 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend-llvm The LLVM backend outputs an LLVM IR Module. bug Observed behavior contradicts documented or intended behavior frontend Tokenization, parsing, AstGen, Sema, and Liveness.
Projects
None yet
Development

No branches or pull requests

3 participants