11use crate :: cmp;
2+ use crate :: convert:: TryFrom ;
23use crate :: fmt;
34use crate :: mem;
45use crate :: num:: NonZeroUsize ;
@@ -53,8 +54,8 @@ impl Layout {
5354 /// * `align` must be a power of two,
5455 ///
5556 /// * `size`, when rounded up to the nearest multiple of `align`,
56- /// must not overflow (i.e., the rounded value must be less than
57- /// or equal to `usize ::MAX`).
57+ /// must not overflow isize (i.e., the rounded value must be
58+ /// less than or equal to `isize ::MAX`).
5859 #[ stable( feature = "alloc_layout" , since = "1.28.0" ) ]
5960 #[ rustc_const_stable( feature = "const_alloc_layout" , since = "1.50.0" ) ]
6061 #[ inline]
@@ -77,7 +78,7 @@ impl Layout {
7778 //
7879 // Above implies that checking for summation overflow is both
7980 // necessary and sufficient.
80- if size > usize :: MAX - ( align - 1 ) {
81+ if size > isize :: MAX as usize - ( align - 1 ) {
8182 return Err ( LayoutError ) ;
8283 }
8384
@@ -277,8 +278,8 @@ impl Layout {
277278 let pad = self . padding_needed_for ( self . align ( ) ) ;
278279 // This cannot overflow. Quoting from the invariant of Layout:
279280 // > `size`, when rounded up to the nearest multiple of `align`,
280- // > must not overflow (i.e., the rounded value must be less than
281- // > `usize ::MAX`)
281+ // > must not overflow isize (i.e., the rounded value must be
282+ // > less than or equal to `isize ::MAX`)
282283 let new_size = self . size ( ) + pad;
283284
284285 // SAFETY: self.align is already known to be valid and new_size has been
@@ -299,14 +300,21 @@ impl Layout {
299300 pub fn repeat ( & self , n : usize ) -> Result < ( Self , usize ) , LayoutError > {
300301 // This cannot overflow. Quoting from the invariant of Layout:
301302 // > `size`, when rounded up to the nearest multiple of `align`,
302- // > must not overflow (i.e., the rounded value must be less than
303- // > `usize ::MAX`)
303+ // > must not overflow isize (i.e., the rounded value must be
304+ // > less than or equal to `isize ::MAX`)
304305 let padded_size = self . size ( ) + self . padding_needed_for ( self . align ( ) ) ;
305- let alloc_size = padded_size. checked_mul ( n) . ok_or ( LayoutError ) ?;
306+ // Size manipulation is done in isize space to avoid overflowing isize.
307+ let n = isize:: try_from ( n) . map_err ( |_| LayoutError ) ?;
308+ let alloc_size = ( padded_size as isize ) . checked_mul ( n) . ok_or ( LayoutError ) ?;
306309
307310 // SAFETY: self.align is already known to be valid and alloc_size has been
308311 // padded already.
309- unsafe { Ok ( ( Layout :: from_size_align_unchecked ( alloc_size, self . align ( ) ) , padded_size) ) }
312+ unsafe {
313+ Ok ( (
314+ Layout :: from_size_align_unchecked ( alloc_size as usize , self . align ( ) ) ,
315+ padded_size as usize ,
316+ ) )
317+ }
310318 }
311319
312320 /// Creates a layout describing the record for `self` followed by
@@ -360,11 +368,12 @@ impl Layout {
360368 let new_align = cmp:: max ( self . align ( ) , next. align ( ) ) ;
361369 let pad = self . padding_needed_for ( next. align ( ) ) ;
362370
363- let offset = self . size ( ) . checked_add ( pad) . ok_or ( LayoutError ) ?;
364- let new_size = offset. checked_add ( next. size ( ) ) . ok_or ( LayoutError ) ?;
371+ // Size manipulation is done in isize space to avoid overflowing isize.
372+ let offset = ( self . size ( ) as isize ) . checked_add ( pad as isize ) . ok_or ( LayoutError ) ?;
373+ let new_size = offset. checked_add ( next. size ( ) as isize ) . ok_or ( LayoutError ) ?;
365374
366- let layout = Layout :: from_size_align ( new_size, new_align) ?;
367- Ok ( ( layout, offset) )
375+ let layout = Layout :: from_size_align ( new_size as usize , new_align) ?;
376+ Ok ( ( layout, offset as usize ) )
368377 }
369378
370379 /// Creates a layout describing the record for `n` instances of
@@ -382,8 +391,10 @@ impl Layout {
382391 #[ unstable( feature = "alloc_layout_extra" , issue = "55724" ) ]
383392 #[ inline]
384393 pub fn repeat_packed ( & self , n : usize ) -> Result < Self , LayoutError > {
385- let size = self . size ( ) . checked_mul ( n) . ok_or ( LayoutError ) ?;
386- Layout :: from_size_align ( size, self . align ( ) )
394+ // Size manipulation is done in isize space to avoid overflowing isize.
395+ let n = isize:: try_from ( n) . map_err ( |_| LayoutError ) ?;
396+ let size = ( self . size ( ) as isize ) . checked_mul ( n) . ok_or ( LayoutError ) ?;
397+ Layout :: from_size_align ( size as usize , self . align ( ) )
387398 }
388399
389400 /// Creates a layout describing the record for `self` followed by
@@ -395,8 +406,10 @@ impl Layout {
395406 #[ unstable( feature = "alloc_layout_extra" , issue = "55724" ) ]
396407 #[ inline]
397408 pub fn extend_packed ( & self , next : Self ) -> Result < Self , LayoutError > {
398- let new_size = self . size ( ) . checked_add ( next. size ( ) ) . ok_or ( LayoutError ) ?;
399- Layout :: from_size_align ( new_size, self . align ( ) )
409+ // Size manipulation is done in isize space to avoid overflowing isize.
410+ let new_size =
411+ ( self . size ( ) as isize ) . checked_add ( next. size ( ) as isize ) . ok_or ( LayoutError ) ?;
412+ Layout :: from_size_align ( new_size as usize , self . align ( ) )
400413 }
401414
402415 /// Creates a layout describing the record for a `[T; n]`.
@@ -405,7 +418,9 @@ impl Layout {
405418 #[ stable( feature = "alloc_layout_manipulation" , since = "1.44.0" ) ]
406419 #[ inline]
407420 pub fn array < T > ( n : usize ) -> Result < Self , LayoutError > {
408- let array_size = mem:: size_of :: < T > ( ) . checked_mul ( n) . ok_or ( LayoutError ) ?;
421+ // Size manipulation is done in isize space to avoid overflowing isize.
422+ let n = isize:: try_from ( n) . map_err ( |_| LayoutError ) ?;
423+ let array_size = ( mem:: size_of :: < T > ( ) as isize ) . checked_mul ( n) . ok_or ( LayoutError ) ?;
409424
410425 // SAFETY:
411426 // - Size: `array_size` cannot be too big because `size_of::<T>()` must
@@ -415,7 +430,7 @@ impl Layout {
415430 // just checked by the `checked_mul()`.
416431 // - Alignment: `align_of::<T>()` will always give an acceptable
417432 // (non-zero, power of two) alignment.
418- Ok ( unsafe { Layout :: from_size_align_unchecked ( array_size, mem:: align_of :: < T > ( ) ) } )
433+ Ok ( unsafe { Layout :: from_size_align_unchecked ( array_size as usize , mem:: align_of :: < T > ( ) ) } )
419434 }
420435}
421436
0 commit comments