-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Nested property access of packed struct loads wrong value #3091
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
Comments
Heh, I discovered a similar bug when trying to nest my own packed Another example: const std = @import("std");
const Vec2 = packed struct {
x: f32,
y: f32,
};
const NestedVec2 = packed struct {
nested: Vec2,
};
test "packed vec2 set" {
const v = Vec2{
.x = 1.0,
.y = 2.0,
};
std.testing.expectEqual(v.x, 1.0);
std.testing.expectEqual(v.y, 2.0);
}
test "packed vec2 ptr set" {
const v = Vec2{
.x = 1.0,
.y = 2.0,
};
var o: Vec2 = undefined;
const o_ptr: *Vec2 = &o;
o_ptr.* = v;
std.testing.expectEqual(o.x, 1.0);
std.testing.expectEqual(o.y, 2.0);
}
test "nested packed vec2 set" {
const a = NestedVec2{
.nested = Vec2{
.x = 1.0,
.y = 2.0,
},
};
std.testing.expectEqual(a.nested.x, 1.0);
std.testing.expectEqual(a.nested.y, 2.0);
}
test "nested packed vec2 ptr set" {
const a = NestedVec2{
.nested = Vec2{
.x = 1.0,
.y = 2.0,
},
};
var o: NestedVec2 = undefined;
const o_ptr: *NestedVec2 = &o;
o_ptr.* = a;
std.testing.expectEqual(o.nested.x, 1.0);
std.testing.expectEqual(o.nested.y, 2.0);
}
const Vec3 = packed struct {
x: f32,
y: f32,
z: f32,
};
const NestedVec3 = packed struct {
nested: Vec3,
};
test "packed vec3 set" {
const v = Vec3{
.x = 1.0,
.y = 2.0,
.z = 3.0,
};
std.testing.expectEqual(v.x, 1.0);
std.testing.expectEqual(v.y, 2.0);
std.testing.expectEqual(v.z, 3.0);
}
test "packed vec3 ptr set" {
const v = Vec3{
.x = 1.0,
.y = 2.0,
.z = 3.0,
};
var o: Vec3 = undefined;
const o_ptr: *Vec3 = &o;
o_ptr.* = v;
std.testing.expectEqual(o.x, 1.0);
std.testing.expectEqual(o.y, 2.0);
std.testing.expectEqual(o.z, 3.0);
}
test "nested packed vec3 set" {
const a = NestedVec3{
.nested = Vec3{
.x = 1.0,
.y = 2.0,
.z = 3.0,
},
};
std.testing.expectEqual(a.nested.x, 1.0);
std.testing.expectEqual(a.nested.y, 2.0);
std.testing.expectEqual(a.nested.z, 3.0);
}
test "nested packed vec3 ptr set" {
const a = NestedVec3{
.nested = Vec3{
.x = 1.0,
.y = 2.0,
.z = 3.0,
},
};
var o: NestedVec3 = undefined;
const o_ptr: *NestedVec3 = &o;
o_ptr.* = a;
std.testing.expectEqual(o.nested.x, 1.0);
std.testing.expectEqual(o.nested.y, 2.0);
std.testing.expectEqual(o.nested.z, 3.0);
}
|
I have the same bug, but even when not assigned by pointer: const std = @import("std");
const assert = std.debug.assert;
const hld = packed struct {
c: u64,
d: u32,
};
const mld = packed struct {
h: u64,
i: u64,
};
const a = packed struct {
b: hld,
g: mld,
};
test "c" {
var arg = a{ .b = hld{ .c = 1, .d = 2 }, .g = mld{ .h = 6, .i = 8 } };
assert(arg.b.c == 1);
}
test "d" {
var arg = a{ .b = hld{ .c = 1, .d = 2 }, .g = mld{ .h = 6, .i = 8 } };
assert(arg.b.d == 2);
}
test "h" {
var arg = a{ .b = hld{ .c = 1, .d = 2 }, .g = mld{ .h = 6, .i = 8 } };
assert(arg.g.h == 6);
}
test "i" {
var arg = a{ .b = hld{ .c = 1, .d = 2 }, .g = mld{ .h = 6, .i = 8 } };
assert(arg.g.i == 8);
}
But when the outer struct is not packed or both are not, then all tests pass. |
Accessing nested properties of packed structs seems to silently load from the wrong offset within the struct, without a compile error or runtime crash.
This only fails if
Foo
andVec3
arepacked
, and it seems to be sensitive to the size/contents/alignment of the structs: for aVec2
orVec4
, this works fine.This is likely related to #2731 or #2784, but the issue here is incorrect behavior at runtime.
The text was updated successfully, but these errors were encountered: