1
1
use crate :: cmp;
2
+ use crate :: convert:: TryFrom ;
2
3
use crate :: fmt;
3
4
use crate :: mem;
4
5
use crate :: num:: NonZeroUsize ;
@@ -53,8 +54,8 @@ impl Layout {
53
54
/// * `align` must be a power of two,
54
55
///
55
56
/// * `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`).
58
59
#[ stable( feature = "alloc_layout" , since = "1.28.0" ) ]
59
60
#[ rustc_const_stable( feature = "const_alloc_layout" , since = "1.50.0" ) ]
60
61
#[ inline]
@@ -77,7 +78,7 @@ impl Layout {
77
78
//
78
79
// Above implies that checking for summation overflow is both
79
80
// necessary and sufficient.
80
- if size > usize :: MAX - ( align - 1 ) {
81
+ if size > isize :: MAX as usize - ( align - 1 ) {
81
82
return Err ( LayoutError ) ;
82
83
}
83
84
@@ -277,8 +278,8 @@ impl Layout {
277
278
let pad = self . padding_needed_for ( self . align ( ) ) ;
278
279
// This cannot overflow. Quoting from the invariant of Layout:
279
280
// > `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`)
282
283
let new_size = self . size ( ) + pad;
283
284
284
285
// SAFETY: self.align is already known to be valid and new_size has been
@@ -299,14 +300,21 @@ impl Layout {
299
300
pub fn repeat ( & self , n : usize ) -> Result < ( Self , usize ) , LayoutError > {
300
301
// This cannot overflow. Quoting from the invariant of Layout:
301
302
// > `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`)
304
305
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 ) ?;
306
309
307
310
// SAFETY: self.align is already known to be valid and alloc_size has been
308
311
// 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
+ }
310
318
}
311
319
312
320
/// Creates a layout describing the record for `self` followed by
@@ -360,11 +368,12 @@ impl Layout {
360
368
let new_align = cmp:: max ( self . align ( ) , next. align ( ) ) ;
361
369
let pad = self . padding_needed_for ( next. align ( ) ) ;
362
370
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 ) ?;
365
374
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 ) )
368
377
}
369
378
370
379
/// Creates a layout describing the record for `n` instances of
@@ -382,8 +391,10 @@ impl Layout {
382
391
#[ unstable( feature = "alloc_layout_extra" , issue = "55724" ) ]
383
392
#[ inline]
384
393
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 ( ) )
387
398
}
388
399
389
400
/// Creates a layout describing the record for `self` followed by
@@ -395,8 +406,10 @@ impl Layout {
395
406
#[ unstable( feature = "alloc_layout_extra" , issue = "55724" ) ]
396
407
#[ inline]
397
408
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 ( ) )
400
413
}
401
414
402
415
/// Creates a layout describing the record for a `[T; n]`.
@@ -405,7 +418,9 @@ impl Layout {
405
418
#[ stable( feature = "alloc_layout_manipulation" , since = "1.44.0" ) ]
406
419
#[ inline]
407
420
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 ) ?;
409
424
410
425
// SAFETY:
411
426
// - Size: `array_size` cannot be too big because `size_of::<T>()` must
@@ -415,7 +430,7 @@ impl Layout {
415
430
// just checked by the `checked_mul()`.
416
431
// - Alignment: `align_of::<T>()` will always give an acceptable
417
432
// (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 > ( ) ) } )
419
434
}
420
435
}
421
436
0 commit comments