@@ -53,28 +53,36 @@ macro_rules! unsafe_wild_copy {
5353 ( [ $T: ident; $N: ident] , $src: ident, $dst: ident, $n: ident) => {
5454 debug_assert!( $n != 0 && $n <= $N) ;
5555
56- let page_size = 4096 ;
57- let read_size = core:: mem:: size_of:: <[ $T; $N] >( ) ;
58- let within_page = $src as usize & ( page_size - 1 ) < ( page_size - read_size) && cfg!( all(
59- // Miri doesn't like this.
60- not( miri) ,
61- // cargo fuzz's memory sanitizer complains about buffer overrun.
62- // Without nightly we can't detect memory sanitizers, so we check debug_assertions.
63- not( debug_assertions) ,
64- // x86/x86_64/aarch64 all have min page size of 4096, so reading past the end of a non-empty
65- // buffer won't page fault.
66- any( target_arch = "x86" , target_arch = "x86_64" , target_arch = "aarch64" )
67- ) ) ;
56+ // Note: Neither Miri nor the fuzzer's memory sanitizer like this feature. We prevent
57+ // the latter from seeing it with `not(debug_assertions)`.
58+ #[ cfg( all( feature = "unsound" , not( debug_assertions) ) ) ]
59+ {
60+ let page_size = 4096 ;
61+ let read_size = core:: mem:: size_of:: <[ $T; $N] >( ) ;
62+ let within_page = $src as usize & ( page_size - 1 ) < ( page_size - read_size) && cfg!( all(
63+ // Miri doesn't like this.
64+ not( miri) ,
65+ // cargo fuzz's memory sanitizer complains about buffer overrun.
66+ // Without nightly we can't detect memory sanitizers, so we check debug_assertions.
67+ not( debug_assertions) ,
68+ // x86/x86_64/aarch64 all have min page size of 4096, so reading past the end of a non-empty
69+ // buffer won't page fault.
70+ any( target_arch = "x86" , target_arch = "x86_64" , target_arch = "aarch64" )
71+ ) ) ;
6872
69- if within_page {
70- * ( $dst as * mut core:: mem:: MaybeUninit <[ $T; $N] >) = core:: ptr:: read( $src as * const core:: mem:: MaybeUninit <[ $T; $N] >) ;
71- } else {
72- #[ cold]
73- unsafe fn cold<T >( src: * const T , dst: * mut T , n: usize ) {
74- src. copy_to_nonoverlapping( dst, n) ;
73+ if within_page {
74+ * ( $dst as * mut core:: mem:: MaybeUninit <[ $T; $N] >) = core:: ptr:: read( $src as * const core:: mem:: MaybeUninit <[ $T; $N] >) ;
75+ } else {
76+ #[ cold]
77+ unsafe fn cold<T >( src: * const T , dst: * mut T , n: usize ) {
78+ src. copy_to_nonoverlapping( dst, n) ;
79+ }
80+ cold( $src, $dst, $n) ;
7581 }
76- cold( $src, $dst, $n) ;
7782 }
83+
84+ #[ cfg( any( not( feature = "unsound" ) , debug_assertions) ) ]
85+ $src. copy_to_nonoverlapping( $dst, $n) ;
7886 }
7987}
8088#[ allow( unused_imports) ]
0 commit comments