Skip to content

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

@alanvoss

Description

@alanvoss

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions