Skip to content

Commit 69b540e

Browse files
committed
Fix unsoundness in new is_power_of_two fast path
1 parent 11f32b7 commit 69b540e

File tree

2 files changed

+14
-8
lines changed

2 files changed

+14
-8
lines changed

library/core/src/num/uint_macros.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,9 +1376,9 @@ macro_rules! uint_impl {
13761376
}
13771377
// SAFETY: We just checked this is a power of two. and above zero.
13781378
let power_used = unsafe { intrinsics::cttz_nonzero(self) as u32 };
1379-
if exp > Self::BITS / power_used { return None; } // Division of constants is free
1379+
if exp >= Self::BITS / power_used { return None; } // Division of constants is free
13801380

1381-
// SAFETY: exp <= Self::BITS / power_used
1381+
// SAFETY: exp < Self::BITS / power_used
13821382
unsafe { Some(intrinsics::unchecked_shl(
13831383
1 as Self,
13841384
intrinsics::unchecked_mul(power_used, exp) as Self
@@ -1920,9 +1920,9 @@ macro_rules! uint_impl {
19201920
}
19211921
// SAFETY: We just checked this is a power of two. and above zero.
19221922
let power_used = unsafe { intrinsics::cttz_nonzero(self) as u32 };
1923-
if exp > Self::BITS / power_used { return 0; } // Division of constants is free
1923+
if exp >= Self::BITS / power_used { return 0; } // Division of constants is free
19241924

1925-
// SAFETY: exp <= Self::BITS / power_used
1925+
// SAFETY: exp < Self::BITS / power_used
19261926
unsafe { intrinsics::unchecked_shl(
19271927
1 as Self,
19281928
intrinsics::unchecked_mul(power_used, exp) as Self
@@ -2395,9 +2395,9 @@ macro_rules! uint_impl {
23952395
}
23962396
// SAFETY: We just checked this is a power of two. and above zero.
23972397
let power_used = unsafe { intrinsics::cttz_nonzero(self) as u32 };
2398-
if exp > Self::BITS / power_used { return (0, true); } // Division of constants is free
2398+
if exp >= Self::BITS / power_used { return (0, true); } // Division of constants is free
23992399

2400-
// SAFETY: exp <= Self::BITS / power_used
2400+
// SAFETY: exp < Self::BITS / power_used
24012401
unsafe { (intrinsics::unchecked_shl(
24022402
1 as Self,
24032403
intrinsics::unchecked_mul(power_used, exp) as Self
@@ -2475,12 +2475,12 @@ macro_rules! uint_impl {
24752475
}
24762476
// SAFETY: We just checked this is a power of two. and above zero.
24772477
let power_used = unsafe { intrinsics::cttz_nonzero(self) as u32 };
2478-
if exp > Self::BITS / power_used { // Division of constants is free
2478+
if exp >= Self::BITS / power_used { // Division of constants is free
24792479
#[allow(arithmetic_overflow)]
24802480
return Self::MAX * Self::MAX * 0;
24812481
}
24822482

2483-
// SAFETY: exp <= Self::BITS / power_used
2483+
// SAFETY: exp < Self::BITS / power_used
24842484
unsafe { intrinsics::unchecked_shl(
24852485
1 as Self,
24862486
intrinsics::unchecked_mul(power_used, exp) as Self
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fn main() {
2+
match 2u64.checked_pow(64) {
3+
Some(n) => println!("2^64: {n}"),
4+
None => {}
5+
}
6+
}

0 commit comments

Comments
 (0)