mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 03:38:29 +00:00
Revert "Remove checked_add
in Layout::repeat
"
This fixes a a segfault in safe code, a stable regression. Reported in
\#69225.
This reverts commit a983e0590a
.
Also adds a test for the expected behaviour.
This commit is contained in:
parent
0176a9eef8
commit
3e17d191fa
@ -241,11 +241,13 @@ impl Layout {
|
|||||||
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
|
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> {
|
pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> {
|
||||||
// This cannot overflow. Quoting from the invariant of Layout:
|
// Warning, removing the checked_add here led to segfaults in #67174. Further
|
||||||
// > `size`, when rounded up to the nearest multiple of `align`,
|
// analysis in #69225 seems to indicate that this is an LTO-related
|
||||||
// > must not overflow (i.e., the rounded value must be less than
|
// miscompilation, so #67174 might be able to be reapplied in the future.
|
||||||
// > `usize::MAX`)
|
let padded_size = self
|
||||||
let padded_size = self.size() + self.padding_needed_for(self.align());
|
.size()
|
||||||
|
.checked_add(self.padding_needed_for(self.align()))
|
||||||
|
.ok_or(LayoutErr { private: () })?;
|
||||||
let alloc_size = padded_size.checked_mul(n).ok_or(LayoutErr { private: () })?;
|
let alloc_size = padded_size.checked_mul(n).ok_or(LayoutErr { private: () })?;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
// Ensure we appropriately error instead of overflowing a calculation when creating a new Alloc
|
||||||
|
// Layout
|
||||||
|
|
||||||
|
// run-fail
|
||||||
|
// compile-flags: -C opt-level=3
|
||||||
|
// error-pattern: index out of bounds: the len is 0 but the index is 16777216
|
||||||
|
// ignore-wasm no panic or subprocess support
|
||||||
|
// ignore-emscripten no panic or subprocess support
|
||||||
|
|
||||||
|
fn do_test(x: usize) {
|
||||||
|
let arr = vec![vec![0u8; 3]];
|
||||||
|
|
||||||
|
let mut z = Vec::new();
|
||||||
|
for arr_ref in arr {
|
||||||
|
for y in 0..x {
|
||||||
|
for _ in 0..1 {
|
||||||
|
z.extend(std::iter::repeat(0).take(x));
|
||||||
|
let a = y * x;
|
||||||
|
let b = (y + 1) * x - 1;
|
||||||
|
let slice = &arr_ref[a..b];
|
||||||
|
eprintln!("{} {} {} {}", a, b, arr_ref.len(), slice.len());
|
||||||
|
eprintln!("{:?}", slice[1 << 24]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
do_test(1);
|
||||||
|
do_test(2);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user