authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-12-18 21:57:18-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-12-18 22:11:26-05:00
log52e5c6602550788cab96957d1a177bc7952d7a09
tree53615c2f51c4ac8cec3fdb63941efe24e9b8875a
parent18f05664dcf9c3a307d269dda4f146bafbca19e9

llvm: fix use of invalid alignment

* Initialize `big_align` with 1 as 0 is not a valid alignment. * Add an assert to `alignForwardGeneric` to catch this issue earlier. * Refactor valid alignment checks to call a more descriptive function.

2 files changed, 13 insertions(+), 6 deletions(-)

lib/std/mem.zig+12-5
......@@ -3291,7 +3291,7 @@ pub fn nativeToBig(comptime T: type, x: T) T {
32913291/// - The delta required to align the pointer is not a multiple of the pointee's
32923292/// type.
32933293pub fn alignPointerOffset(ptr: anytype, align_to: usize) ?usize {
3294 assert(align_to != 0 and @popCount(align_to) == 1);
3294 assert(isValidAlign(align_to));
32953295
32963296 const T = @TypeOf(ptr);
32973297 const info = @typeInfo(T);
......@@ -3751,6 +3751,7 @@ pub fn alignForwardLog2(addr: usize, log2_alignment: u8) usize {
37513751/// The alignment must be a power of 2 and greater than 0.
37523752/// Asserts that rounding up the address does not cause integer overflow.
37533753pub fn alignForwardGeneric(comptime T: type, addr: T, alignment: T) T {
3754 assert(isValidAlignGeneric(T, alignment));
37543755 return alignBackwardGeneric(T, addr + (alignment - 1), alignment);
37553756}
37563757
......@@ -3846,7 +3847,7 @@ test "alignForward" {
38463847/// Round an address down to the previous (or current) aligned address.
38473848/// Unlike `alignBackward`, `alignment` can be any positive number, not just a power of 2.
38483849pub fn alignBackwardAnyAlign(i: usize, alignment: usize) usize {
3849 if (@popCount(alignment) == 1)
3850 if (isValidAlign(alignment))
38503851 return alignBackward(i, alignment);
38513852 assert(alignment != 0);
38523853 return i - @mod(i, alignment);
......@@ -3861,7 +3862,7 @@ pub fn alignBackward(addr: usize, alignment: usize) usize {
38613862/// Round an address down to the previous (or current) aligned address.
38623863/// The alignment must be a power of 2 and greater than 0.
38633864pub fn alignBackwardGeneric(comptime T: type, addr: T, alignment: T) T {
3864 assert(@popCount(alignment) == 1);
3865 assert(isValidAlignGeneric(T, alignment));
38653866 // 000010000 // example alignment
38663867 // 000001111 // subtract 1
38673868 // 111110000 // binary not
......@@ -3871,11 +3872,17 @@ pub fn alignBackwardGeneric(comptime T: type, addr: T, alignment: T) T {
38713872/// Returns whether `alignment` is a valid alignment, meaning it is
38723873/// a positive power of 2.
38733874pub fn isValidAlign(alignment: usize) bool {
3874 return @popCount(alignment) == 1;
3875 return isValidAlignGeneric(usize, alignment);
3876}
3877
3878/// Returns whether `alignment` is a valid alignment, meaning it is
3879/// a positive power of 2.
3880pub fn isValidAlignGeneric(comptime T: type, alignment: T) bool {
3881 return alignment > 0 and std.math.isPowerOfTwo(alignment);
38753882}
38763883
38773884pub fn isAlignedAnyAlign(i: usize, alignment: usize) bool {
3878 if (@popCount(alignment) == 1)
3885 if (isValidAlign(alignment))
38793886 return isAligned(i, alignment);
38803887 assert(alignment != 0);
38813888 return 0 == @mod(i, alignment);
src/codegen/llvm.zig+1-1
......@@ -2969,7 +2969,7 @@ pub const DeclGen = struct {
29692969
29702970 comptime assert(struct_layout_version == 2);
29712971 var offset: u64 = 0;
2972 var big_align: u32 = 0;
2972 var big_align: u32 = 1;
29732973 var any_underaligned_fields = false;
29742974
29752975 for (struct_obj.fields.values()) |field| {