@@ -383,7 +383,7 @@ impl<'tcx> GotocCtx<'tcx> {
383
383
384
384
match intrinsic {
385
385
"add_with_overflow" => codegen_op_with_overflow ! ( add_overflow) ,
386
- "arith_offset" => unstable_codegen ! ( codegen_wrapping_op! ( plus ) ) ,
386
+ "arith_offset" => self . codegen_offset ( intrinsic , instance , fargs , p , loc ) ,
387
387
"assert_inhabited" => self . codegen_assert_intrinsic ( instance, intrinsic, span) ,
388
388
"assert_uninit_valid" => self . codegen_assert_intrinsic ( instance, intrinsic, span) ,
389
389
"assert_zero_valid" => self . codegen_assert_intrinsic ( instance, intrinsic, span) ,
@@ -562,7 +562,7 @@ impl<'tcx> GotocCtx<'tcx> {
562
562
"https://github.com/model-checking/kani/issues/1025"
563
563
) ,
564
564
"needs_drop" => codegen_intrinsic_const ! ( ) ,
565
- "offset" => self . codegen_offset ( instance, fargs, p, loc) ,
565
+ "offset" => self . codegen_offset ( intrinsic , instance, fargs, p, loc) ,
566
566
"powf32" => unstable_codegen ! ( codegen_simple_intrinsic!( Powf ) ) ,
567
567
"powf64" => unstable_codegen ! ( codegen_simple_intrinsic!( Pow ) ) ,
568
568
"powif32" => unstable_codegen ! ( codegen_simple_intrinsic!( Powif ) ) ,
@@ -992,10 +992,24 @@ impl<'tcx> GotocCtx<'tcx> {
992
992
Stmt :: block ( vec ! [ src_align_check, dst_align_check, overflow_check, copy_expr] , loc)
993
993
}
994
994
995
- /// Computes the offset from a pointer
996
- /// https://doc.rust-lang.org/std/intrinsics/fn.offset.html
995
+ /// Computes the offset from a pointer.
996
+ ///
997
+ /// Note that this function handles code generation for:
998
+ /// 1. The `offset` intrinsic.
999
+ /// https://doc.rust-lang.org/std/intrinsics/fn.offset.html
1000
+ /// 2. The `arith_offset` intrinsic.
1001
+ /// https://doc.rust-lang.org/std/intrinsics/fn.arith_offset.html
1002
+ ///
1003
+ /// Note(std): We don't check that the starting or resulting pointer stay
1004
+ /// within bounds of the object they point to. Doing so causes spurious
1005
+ /// failures due to the usage of these intrinsics in the standard library.
1006
+ /// See https://github.com/model-checking/kani/issues/1233 for more details.
1007
+ /// Also, note that this isn't a requirement for `arith_offset`, but it's
1008
+ /// one of the safety conditions specified for `offset`:
1009
+ /// https://doc.rust-lang.org/std/primitive.pointer.html#safety-2
997
1010
fn codegen_offset (
998
1011
& mut self ,
1012
+ intrinsic : & str ,
999
1013
instance : Instance < ' tcx > ,
1000
1014
mut fargs : Vec < Expr > ,
1001
1015
p : & Place < ' tcx > ,
@@ -1007,7 +1021,7 @@ impl<'tcx> GotocCtx<'tcx> {
1007
1021
// Check that computing `offset` in bytes would not overflow
1008
1022
let ty = self . monomorphize ( instance. substs . type_at ( 0 ) ) ;
1009
1023
let ( offset_bytes, bytes_overflow_check) =
1010
- self . count_in_bytes ( offset. clone ( ) , ty, Type :: ssize_t ( ) , "offset" , loc) ;
1024
+ self . count_in_bytes ( offset. clone ( ) , ty, Type :: ssize_t ( ) , intrinsic , loc) ;
1011
1025
1012
1026
// Check that the computation would not overflow an `isize`
1013
1027
// These checks may allow a wrapping-around behavior in CBMC:
0 commit comments