aboutsummaryrefslogtreecommitdiff
path: root/lib/std/math
diff options
context:
space:
mode:
authorАндрей Краевский <75577902+AndrewKraevskii@users.noreply.github.com>2024-04-13 13:06:23 +0300
committerGitHub <noreply@github.com>2024-04-13 03:06:23 -0700
commit7cc0e6d4cd5d699d5377cf47ee27a2e089d046bf (patch)
treebacde8ab8eb49a46301c0ce3293a58166a99933b /lib/std/math
parent4fac5bd601da12140586115dc9ddc6a92577ff6d (diff)
downloadzig-7cc0e6d4cd5d699d5377cf47ee27a2e089d046bf.tar.gz
zig-7cc0e6d4cd5d699d5377cf47ee27a2e089d046bf.zip
std: fix big int llshr to respect aliasing (#19612)
Diffstat (limited to 'lib/std/math')
-rw-r--r--lib/std/math/big/int.zig12
-rw-r--r--lib/std/math/big/int_test.zig13
2 files changed, 19 insertions, 6 deletions
diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig
index b564d9a99b..93ad1ccbe2 100644
--- a/lib/std/math/big/int.zig
+++ b/lib/std/math/big/int.zig
@@ -3776,19 +3776,19 @@ fn llshr(r: []Limb, a: []const Limb, shift: usize) void {
const limb_shift = shift / limb_bits;
const interior_limb_shift = @as(Log2Limb, @truncate(shift));
- var carry: Limb = 0;
var i: usize = 0;
while (i < a.len - limb_shift) : (i += 1) {
- const src_i = a.len - i - 1;
- const dst_i = src_i - limb_shift;
+ const dst_i = i;
+ const src_i = dst_i + limb_shift;
const src_digit = a[src_i];
- r[dst_i] = carry | (src_digit >> interior_limb_shift);
- carry = @call(.always_inline, math.shl, .{
+ const src_digit_next = if (src_i + 1 < a.len) a[src_i + 1] else 0;
+ const carry = @call(.always_inline, math.shl, .{
Limb,
- src_digit,
+ src_digit_next,
limb_bits - @as(Limb, @intCast(interior_limb_shift)),
});
+ r[dst_i] = carry | (src_digit >> interior_limb_shift);
}
}
diff --git a/lib/std/math/big/int_test.zig b/lib/std/math/big/int_test.zig
index f9d7543c2b..624bdc0b83 100644
--- a/lib/std/math/big/int_test.zig
+++ b/lib/std/math/big/int_test.zig
@@ -2019,6 +2019,19 @@ test "shift-right multi" {
try a.shiftRight(&a, 63);
try a.shiftRight(&a, 2);
try testing.expect(a.eqlZero());
+
+ try a.set(0xffff0000eeee1111dddd2222cccc3333000000000000000000000);
+ try a.shiftRight(&a, 84);
+ const string = try a.toString(
+ testing.allocator,
+ 16,
+ .lower,
+ );
+ defer testing.allocator.free(string);
+ try std.testing.expectEqualStrings(
+ string,
+ "ffff0000eeee1111dddd2222cccc3333",
+ );
}
test "shift-left single" {