Pointer arithmetic affects the alignment factor#3955
Conversation
andrewrk
left a comment
There was a problem hiding this comment.
This case regressed:
test "hi" {
var ptr: [*]align(8) u32 = undefined;
const ptr2 = ptr + 1;
@compileLog(@TypeOf(ptr2));
}expected: [*]u32
found: [*]align(1) u32
Hm? You're increasing |
|
Yes but it should still be aligned to 4, e.g. it should not be underaligned. Maybe this is a better example: test "extra aligned ptr" {
var x: [2]u32 align(8) = [_]u32{1, 2};
const result = addTwoNumbers(&x);
@import("std").testing.expect(result == 3);
}
fn addTwoNumbers(ptr: [*]align(8) u32) u32 {
return fetch(ptr + 0) + fetch(ptr + 1);
}
fn fetch(ptr: [*]u32) u32 {
return ptr[0];
}This correctly passes in master branch. |
Gotcha, I've added some code to do so ;) |
| // The resulting pointer is aligned to the lcd between the | ||
| // offset (an arbitrary number) and the alignment factor (always | ||
| // a power of two, non zero) | ||
| uint32_t new_align = 1 << ctzll(byte_offset | align_bytes); |
There was a problem hiding this comment.
👏 👏 👏
much sophisticated, very wow 🐶
| const ptr4 = ptr + x; // runtime-known addend | ||
| expect(@typeInfo(@TypeOf(ptr4)).Pointer.alignment == 1); |
There was a problem hiding this comment.
Wait, this should still be aligned to u32. x is runtime known but the number of bytes the pointer marches forward is @sizeOf(u32) * x which is guaranteed to be divisible by @sizeOf(u32).
There was a problem hiding this comment.
Yeah, I focused too much on the comptime-known branch and forgot the other one, now it should be fine!
Closes #1528