Skip to content

Commit ffa31d2

Browse files
committed
libstd: modify wrong shift width.
borrow = *elem << (uint::bits - n_bits); The code above contains a bug that the value of the right operand of the shift operator exceeds the size of the left operand, because sizeof(*elem) == 32, and 0 <= n_bits < 32 in 64bit architecture. If `--opt-level` option is not given to rustc, the code above runs as if the right operand is `(uint::bits - n_bits) % 32`, but if --opt-level is given, `borrow` is always zero. I wonder why this bug is not catched in the libstd's testsuite (I try the `rustc --test --opt-level=2 bigint.rs` before fixing the bug, but the unittest passes normally.)
1 parent e4ca2da commit ffa31d2

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

src/libstd/num/bigint.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ impl BigUint {
623623
let mut shifted = ~[];
624624
for self.data.each_reverse |elem| {
625625
shifted = ~[(*elem >> n_bits) | borrow] + shifted;
626-
borrow = *elem << (uint::bits - n_bits);
626+
borrow = *elem << (BigDigit::bits - n_bits);
627627
}
628628
return BigUint::new(shifted);
629629
}
@@ -1213,6 +1213,7 @@ mod biguint_tests {
12131213
check(~[1 << 2], 2, ~[1]);
12141214
check(~[1, 2], 3, ~[1 << (BigDigit::bits - 2)]);
12151215
check(~[1, 1, 2], 3 + BigDigit::bits, ~[1 << (BigDigit::bits - 2)]);
1216+
check(~[0, 1], 1, ~[0x80000000]);
12161217
test_shr_bits();
12171218

12181219
#[cfg(target_arch = "x86_64")]

0 commit comments

Comments
 (0)