Skip to content
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

@sizeOf() packed struct changes depending on relative sizes of members #10104

Closed
1 task done
mirrexagon opened this issue Nov 5, 2021 · 2 comments
Closed
1 task done
Labels
bug Observed behavior contradicts documented or intended behavior miscompilation The compiler reports success but produces semantically incorrect code. stage1 The process of building from source via WebAssembly and the C backend.
Milestone

Comments

@mirrexagon
Copy link

mirrexagon commented Nov 5, 2021

Remember to search before filing a new report

  • I searched for this bug and did not find it in the issue tracker, and furthermore, the title I used above will make this new bug report turn up in the search results for my query.

Zig Version

0.9.0 (built with Nix from master commit e97feb9)

Steps to Reproduce

const std = @import("std");

const txdata = packed struct {
    /// Transmit data (RW)
    data: u8,
    _reserved_8: u23,
    /// Transmit FIFO full (RO)
    full: bool = false,
};

const txdata_passes = packed struct {
    /// Transmit data (RW)
    data: u9, // Changed to u9
    _reserved_8: u22, // Changed to u22
    /// Transmit FIFO full (RO)
    full: bool = false,
};

const register_size_bits = 32;
const register_size_bytes = register_size_bits / 8;

test "txdata size correct but fails" {
    try std.testing.expectEqual(register_size_bits, @bitSizeOf(txdata));
    try std.testing.expectEqual(register_size_bytes, @sizeOf(txdata));
}

test "txdata size adjusted to pass" {
    try std.testing.expectEqual(register_size_bits, @bitSizeOf(txdata_passes));
    try std.testing.expectEqual(register_size_bytes, @sizeOf(txdata_passes));
}

Run zig test on the above.

Expected Behavior

@bitSizeOf(txdata) and @bitSizeOf(txdata_passes) should be 32, and @sizeOf(txdata) and @sizeOf(txdata_passes) should be 4.

Actual Behavior

@sizeOf(txdata) is 5.


This came up when implementing MMIO registers here: https://github.com/mirrexagon/luxos/blob/a0d46e992ac256685ee36a85f9f255299f0fbe7d/src/target/soc/fe310-g002/uart.zig#L50

Trying to @bitCast() between txdata and usize (32 bits on riscv32) failed due to this. I can work around this by increasing the size of the data member from u8 to u9, and decreasing the size of the next member by one bit (u23 to u22) - doing that makes the sizes match up.

Also affects this register: https://github.com/mirrexagon/luxos/blob/a0d46e992ac256685ee36a85f9f255299f0fbe7d/src/target/arch/riscv/mcsr.zig#L17

Is this something that should work? My understanding is that packed structs that fit exactly into a whole number of bytes should not have any padding.

I'm unsure if this is related to or would be fixed by #8102.

@mirrexagon mirrexagon added the bug Observed behavior contradicts documented or intended behavior label Nov 5, 2021
@andrewrk andrewrk added stage1 The process of building from source via WebAssembly and the C backend. miscompilation The compiler reports success but produces semantically incorrect code. labels Nov 20, 2021
@andrewrk andrewrk added this to the 0.10.0 milestone Nov 20, 2021
@igor84
Copy link
Contributor

igor84 commented Feb 19, 2022

I just noticed that this code:

export fn run() u8 {
    const TestStruct = packed struct {
        a: u32,
        b: [3]u8,
    };
    return @sizeOf(TestStruct);
}

returns 8 instead of 7, but if I change b array to have 2 elements it returns correct 6.

igor84 pushed a commit to igor84/zig that referenced this issue Mar 23, 2022
igor84 pushed a commit to igor84/zig that referenced this issue Mar 26, 2022
Fixed formatting in packed-struct-zig

Skipped packed_structs tests in stage2

simplified packed struct tests
scheibo pushed a commit to scheibo/zig that referenced this issue Apr 19, 2022
Fixed formatting in packed-struct-zig

Skipped packed_structs tests in stage2

simplified packed struct tests
andrewrk added a commit that referenced this issue Apr 22, 2022
@mirrexagon
Copy link
Author

#11279 appears to fix my use case! Thanks @igor84 for your work!

@andrewrk andrewrk modified the milestones: 0.12.0, 0.10.0 May 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior miscompilation The compiler reports success but produces semantically incorrect code. stage1 The process of building from source via WebAssembly and the C backend.
Projects
None yet
Development

No branches or pull requests

3 participants