Skip to content

Ptr align test has different behavior with build mode ReleaseSafe #22126

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
alanvoss opened this issue Dec 2, 2024 · 1 comment
Open

Ptr align test has different behavior with build mode ReleaseSafe #22126

alanvoss opened this issue Dec 2, 2024 · 1 comment
Labels
bug Observed behavior contradicts documented or intended behavior

Comments

@alanvoss
Copy link

alanvoss commented Dec 2, 2024

Zig Version

0.14.0-dev.1660+444228865

Steps to Reproduce and Observed Behavior

I'm running this on MacOS 15.1.1.

make a file called safetest.zig with the following contents:

const std = @import("std");

pub const S = extern struct {
    a: [11]u8,
    b: u8,
    _: [4]u8 = undefined,
    c: u64,
    d: f64,

    const SIZE: usize = @sizeOf(S);

    pub fn marshal(self: *const S) *const [SIZE]u8 {
        return @alignCast(@ptrCast(self));
    }

    pub fn unmarshal(s: *const [SIZE]u8) *const S {
        return @alignCast(@ptrCast(s));
    }
};

test "test marshal/unmarshal with ReleaseSafe" {
    var s = S{
        .a = [_]u8{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K' },
        .b = 'X',
        .c = 12345678,
        .d = 12.345,
    };
    const marshaled = s.marshal();
    var copy: [S.SIZE]u8 align(8) = [1]u8{0} ** S.SIZE;
    // std.debug.print("anything\n", .{}); // somehow just printing eliminates the error?  huh?
    @memcpy(&copy, marshaled);
    const got = S.unmarshal(&copy);
    try std.testing.expectEqual(s, got.*);
}

run as-is with 3 different test build modes:

 > zig test safetest.zig
All 1 tests passed.
> zig test safetest.zig -O ReleaseFast
All 1 tests passed.
> zig test safetest.zig -O ReleaseSafe
slices differ. first difference occurs at index 0 (0x0)

============ expected this output: =============  len: 4 (0x4)

41 42 43 44                                       ABCD

============= instead found this: ==============  len: 4 (0x4)

00 00 00 00                                       ....

================================================

1/1 safetest.test.test marshal/unmarshal with ReleaseSafe...FAIL (TestExpectedEqual)
0 passed; 0 skipped; 1 failed.
error: the following test command failed with exit code 1:
/Users/avoss/.cache/zig/o/5355486d8b426f44920699a773957766/test --seed=0xae458817

The bug is really above, but if you care to have a second bug that is potentially related to this, simply uncommenting this line in the above:

 std.debug.print("anything\n", .{}); // somehow just printing eliminates the error?  huh?

and then running the same tests, and what I believe would be the expected behavior happens again.

> zig test safetest.zig
anything
All 1 tests passed.

> zig test safetest.zig -O ReleaseFast
anything
All 1 tests passed.

> zig test safetest.zig -O ReleaseSafe
anything
All 1 tests passed.

Expected Behavior

I would expect both versions of the test to pass in all 3 build modes each.

@alanvoss alanvoss added the bug Observed behavior contradicts documented or intended behavior label Dec 2, 2024
@alanvoss alanvoss changed the title ReleaseSafe on ptr align test differs on behavior with build mode ReleaseSafe Ptr align test differs on behavior with build mode ReleaseSafe Dec 2, 2024
@alanvoss alanvoss changed the title Ptr align test differs on behavior with build mode ReleaseSafe Ptr align test has different behavior with build mode ReleaseSafe Dec 2, 2024
@rohlem
Copy link
Contributor

rohlem commented Dec 3, 2024

Comparisons with undefined are illegal behavior (#63).
got.* was copied from s, so got.*._ is undefined.
Branching on an @as(bool, undefined) (from comparing the fields _ which are undefined) in/calling std.testing.expectEqual is illegal behavior.
Besides missing safety in safe build modes, I don't think there is really a Zig bug here.

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
Projects
None yet
Development

No branches or pull requests

2 participants