@@ -197,7 +197,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
197
197
// rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
198
198
let layout_val = self . layout_of ( instance_args. type_at ( 0 ) ) ?;
199
199
let val = self . read_scalar ( & args[ 0 ] ) ?;
200
- let val_bits = val. to_bits ( layout_val. size ) ?;
200
+ let val_bits = val. to_bits ( layout_val. size ) ?; // sign is ignored here
201
201
202
202
let layout_raw_shift = self . layout_of ( self . tcx . types . u32 ) ?;
203
203
let raw_shift = self . read_scalar ( & args[ 1 ] ) ?;
@@ -484,7 +484,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
484
484
ret_layout : TyAndLayout < ' tcx > ,
485
485
) -> InterpResult < ' tcx , Scalar < M :: Provenance > > {
486
486
assert ! ( layout. ty. is_integral( ) , "invalid type for numeric intrinsic: {}" , layout. ty) ;
487
- let bits = val. to_bits ( layout. size ) ?;
487
+ let bits = val. to_bits ( layout. size ) ?; // these operations all ignore the sign
488
488
let extra = 128 - u128:: from ( layout. size . bits ( ) ) ;
489
489
let bits_out = match name {
490
490
sym:: ctpop => u128:: from ( bits. count_ones ( ) ) ,
@@ -519,6 +519,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
519
519
// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`.
520
520
// First, check x % y != 0 (or if that computation overflows).
521
521
let rem = self . binary_op ( BinOp :: Rem , a, b) ?;
522
+ // sign does not matter for 0 test, so `to_bits` is fine
522
523
if rem. to_scalar ( ) . to_bits ( a. layout . size ) ? != 0 {
523
524
throw_ub_custom ! (
524
525
fluent:: const_eval_exact_div_has_remainder,
@@ -545,22 +546,19 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
545
546
self . binary_op ( mir_op. wrapping_to_overflowing ( ) . unwrap ( ) , l, r) ?. to_scalar_pair ( ) ;
546
547
Ok ( if overflowed. to_bool ( ) ? {
547
548
let size = l. layout . size ;
548
- let num_bits = size. bits ( ) ;
549
549
if l. layout . abi . is_signed ( ) {
550
550
// For signed ints the saturated value depends on the sign of the first
551
551
// term since the sign of the second term can be inferred from this and
552
552
// the fact that the operation has overflowed (if either is 0 no
553
553
// overflow can occur)
554
- let first_term: u128 = l. to_scalar ( ) . to_bits ( l. layout . size ) ?;
555
- let first_term_positive = first_term & ( 1 << ( num_bits - 1 ) ) == 0 ;
556
- if first_term_positive {
554
+ let first_term: i128 = l. to_scalar ( ) . to_int ( l. layout . size ) ?;
555
+ if first_term >= 0 {
557
556
// Negative overflow not possible since the positive first term
558
557
// can only increase an (in range) negative term for addition
559
- // or corresponding negated positive term for subtraction
558
+ // or corresponding negated positive term for subtraction.
560
559
Scalar :: from_int ( size. signed_int_max ( ) , size)
561
560
} else {
562
- // Positive overflow not possible for similar reason
563
- // max negative
561
+ // Positive overflow not possible for similar reason.
564
562
Scalar :: from_int ( size. signed_int_min ( ) , size)
565
563
}
566
564
} else {
0 commit comments