@@ -364,13 +364,41 @@ impl fmt::Pointer for VirtAddr {
364
364
365
365
impl Add < u64 > for VirtAddr {
366
366
type Output = Self ;
367
+
368
+ #[ cfg_attr( not( feature = "step_trait" ) , allow( rustdoc:: broken_intra_doc_links) ) ]
369
+ /// Add an offset to a virtual address.
370
+ ///
371
+ /// This function performs normal arithmetic addition and doesn't jump the
372
+ /// address gap. If you're looking for a successor operation that jumps the
373
+ /// address gap, use [`Step::forward`].
374
+ ///
375
+ /// # Panics
376
+ ///
377
+ /// This function will panic on overflow or if the result is not a
378
+ /// canonical address.
367
379
#[ inline]
368
380
fn add ( self , rhs : u64 ) -> Self :: Output {
369
- VirtAddr :: new ( self . 0 + rhs)
381
+ VirtAddr :: try_new (
382
+ self . 0
383
+ . checked_add ( rhs)
384
+ . expect ( "attempt to add with overflow" ) ,
385
+ )
386
+ . expect ( "attempt to add resulted in non-canonical virtual address" )
370
387
}
371
388
}
372
389
373
390
impl AddAssign < u64 > for VirtAddr {
391
+ #[ cfg_attr( not( feature = "step_trait" ) , allow( rustdoc:: broken_intra_doc_links) ) ]
392
+ /// Add an offset to a virtual address.
393
+ ///
394
+ /// This function performs normal arithmetic addition and doesn't jump the
395
+ /// address gap. If you're looking for a successor operation that jumps the
396
+ /// address gap, use [`Step::forward`].
397
+ ///
398
+ /// # Panics
399
+ ///
400
+ /// This function will panic on overflow or if the result is not a
401
+ /// canonical address.
374
402
#[ inline]
375
403
fn add_assign ( & mut self , rhs : u64 ) {
376
404
* self = * self + rhs;
@@ -379,13 +407,41 @@ impl AddAssign<u64> for VirtAddr {
379
407
380
408
impl Sub < u64 > for VirtAddr {
381
409
type Output = Self ;
410
+
411
+ #[ cfg_attr( not( feature = "step_trait" ) , allow( rustdoc:: broken_intra_doc_links) ) ]
412
+ /// Subtract an offset from a virtual address.
413
+ ///
414
+ /// This function performs normal arithmetic subtraction and doesn't jump
415
+ /// the address gap. If you're looking for a predecessor operation that
416
+ /// jumps the address gap, use [`Step::backward`].
417
+ ///
418
+ /// # Panics
419
+ ///
420
+ /// This function will panic on overflow or if the result is not a
421
+ /// canonical address.
382
422
#[ inline]
383
423
fn sub ( self , rhs : u64 ) -> Self :: Output {
384
- VirtAddr :: new ( self . 0 . checked_sub ( rhs) . unwrap ( ) )
424
+ VirtAddr :: try_new (
425
+ self . 0
426
+ . checked_sub ( rhs)
427
+ . expect ( "attempt to subtract with overflow" ) ,
428
+ )
429
+ . expect ( "attempt to subtract resulted in non-canonical virtual address" )
385
430
}
386
431
}
387
432
388
433
impl SubAssign < u64 > for VirtAddr {
434
+ #[ cfg_attr( not( feature = "step_trait" ) , allow( rustdoc:: broken_intra_doc_links) ) ]
435
+ /// Subtract an offset from a virtual address.
436
+ ///
437
+ /// This function performs normal arithmetic subtraction and doesn't jump
438
+ /// the address gap. If you're looking for a predecessor operation that
439
+ /// jumps the address gap, use [`Step::backward`].
440
+ ///
441
+ /// # Panics
442
+ ///
443
+ /// This function will panic on overflow or if the result is not a
444
+ /// canonical address.
389
445
#[ inline]
390
446
fn sub_assign ( & mut self , rhs : u64 ) {
391
447
* self = * self - rhs;
@@ -394,9 +450,17 @@ impl SubAssign<u64> for VirtAddr {
394
450
395
451
impl Sub < VirtAddr > for VirtAddr {
396
452
type Output = u64 ;
453
+
454
+ /// Returns the difference between two addresses.
455
+ ///
456
+ /// # Panics
457
+ ///
458
+ /// This function will panic on overflow.
397
459
#[ inline]
398
460
fn sub ( self , rhs : VirtAddr ) -> Self :: Output {
399
- self . as_u64 ( ) . checked_sub ( rhs. as_u64 ( ) ) . unwrap ( )
461
+ self . as_u64 ( )
462
+ . checked_sub ( rhs. as_u64 ( ) )
463
+ . expect ( "attempt to subtract with overflow" )
400
464
}
401
465
}
402
466
@@ -593,7 +657,7 @@ impl Add<u64> for PhysAddr {
593
657
type Output = Self ;
594
658
#[ inline]
595
659
fn add ( self , rhs : u64 ) -> Self :: Output {
596
- PhysAddr :: new ( self . 0 + rhs)
660
+ PhysAddr :: new ( self . 0 . checked_add ( rhs) . unwrap ( ) )
597
661
}
598
662
}
599
663
@@ -663,6 +727,30 @@ pub const fn align_up(addr: u64, align: u64) -> u64 {
663
727
mod tests {
664
728
use super :: * ;
665
729
730
+ #[ test]
731
+ #[ should_panic]
732
+ pub fn add_overflow_virtaddr ( ) {
733
+ let _ = VirtAddr :: new ( 0xffff_ffff_ffff_ffff ) + 1 ;
734
+ }
735
+
736
+ #[ test]
737
+ #[ should_panic]
738
+ pub fn add_overflow_physaddr ( ) {
739
+ let _ = PhysAddr :: new ( 0x000f_ffff_ffff_ffff ) + 0xffff_0000_0000_0000 ;
740
+ }
741
+
742
+ #[ test]
743
+ #[ should_panic]
744
+ pub fn sub_underflow_virtaddr ( ) {
745
+ let _ = VirtAddr :: new ( 0 ) - 1 ;
746
+ }
747
+
748
+ #[ test]
749
+ #[ should_panic]
750
+ pub fn sub_overflow_physaddr ( ) {
751
+ let _ = PhysAddr :: new ( 0 ) - 1 ;
752
+ }
753
+
666
754
#[ test]
667
755
pub fn virtaddr_new_truncate ( ) {
668
756
assert_eq ! ( VirtAddr :: new_truncate( 0 ) , VirtAddr ( 0 ) ) ;
0 commit comments