@@ -329,9 +329,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
329
329
self . write_scalar ( offset_ptr, dest) ?;
330
330
}
331
331
sym:: ptr_guaranteed_eq | sym:: ptr_guaranteed_ne => {
332
- // FIXME: return `true` for at least some comparisons where we can reliably
333
- // determine the result of runtime (in)equality tests at compile-time.
334
- self . write_scalar ( Scalar :: from_bool ( false ) , dest) ?;
332
+ let a = self . read_immediate ( args[ 0 ] ) ?. to_scalar ( ) ?;
333
+ let b = self . read_immediate ( args[ 1 ] ) ?. to_scalar ( ) ?;
334
+ let cmp = if intrinsic_name == sym:: ptr_guaranteed_eq {
335
+ self . guaranteed_eq ( a, b)
336
+ } else {
337
+ self . guaranteed_ne ( a, b)
338
+ } ;
339
+ self . write_scalar ( Scalar :: from_bool ( cmp) , dest) ?;
335
340
}
336
341
sym:: ptr_offset_from => {
337
342
let a = self . read_immediate ( args[ 0 ] ) ?. to_scalar ( ) ?;
@@ -448,6 +453,37 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
448
453
Ok ( true )
449
454
}
450
455
456
+ fn guaranteed_eq ( & mut self , a : Scalar < M :: PointerTag > , b : Scalar < M :: PointerTag > ) -> bool {
457
+ match ( a, b) {
458
+ // Comparisons between integers are always known.
459
+ ( Scalar :: Raw { .. } , Scalar :: Raw { .. } ) => a == b,
460
+ // Equality with integers can never be known for sure.
461
+ ( Scalar :: Raw { .. } , Scalar :: Ptr ( _) ) | ( Scalar :: Ptr ( _) , Scalar :: Raw { .. } ) => false ,
462
+ // FIXME: return `true` for when both sides are the same pointer, *except* that
463
+ // some things (like functions and vtables) do not have stable addresses
464
+ // so we need to be careful around them.
465
+ ( Scalar :: Ptr ( _) , Scalar :: Ptr ( _) ) => false ,
466
+ }
467
+ }
468
+
469
+ fn guaranteed_ne ( & mut self , a : Scalar < M :: PointerTag > , b : Scalar < M :: PointerTag > ) -> bool {
470
+ match ( a, b) {
471
+ // Comparisons between integers are always known.
472
+ ( Scalar :: Raw { .. } , Scalar :: Raw { .. } ) => a != b,
473
+ // Comparisons of abstract pointers with null pointers are known if the pointer
474
+ // is in bounds, because if they are in bounds, the pointer can't be null.
475
+ ( Scalar :: Raw { data : 0 , .. } , Scalar :: Ptr ( ptr) )
476
+ | ( Scalar :: Ptr ( ptr) , Scalar :: Raw { data : 0 , .. } ) => !self . memory . ptr_may_be_null ( ptr) ,
477
+ // Inequality with integers other than null can never be known for sure.
478
+ ( Scalar :: Raw { .. } , Scalar :: Ptr ( _) ) | ( Scalar :: Ptr ( _) , Scalar :: Raw { .. } ) => false ,
479
+ // FIXME: return `true` for at least some comparisons where we can reliably
480
+ // determine the result of runtime inequality tests at compile-time.
481
+ // Examples include comparison of addresses in static items, for these we can
482
+ // give reliable results.
483
+ ( Scalar :: Ptr ( _) , Scalar :: Ptr ( _) ) => false ,
484
+ }
485
+ }
486
+
451
487
pub fn exact_div (
452
488
& mut self ,
453
489
a : ImmTy < ' tcx , M :: PointerTag > ,
0 commit comments