@@ -860,6 +860,16 @@ impl Evaluator<'_> {
860
860
let is_signed = matches ! ( ty. as_builtin( ) , Some ( BuiltinType :: Int ( _) ) ) ;
861
861
let l128 = i128:: from_le_bytes ( pad16 ( lc, is_signed) ) ;
862
862
let r128 = i128:: from_le_bytes ( pad16 ( rc, is_signed) ) ;
863
+ let check_overflow = |r : i128 | {
864
+ // FIXME: this is not very correct, and only catches the basic cases.
865
+ let r = r. to_le_bytes ( ) ;
866
+ for & k in & r[ lc. len ( ) ..] {
867
+ if k != 0 && ( k != 255 || !is_signed) {
868
+ return Err ( MirEvalError :: Panic ( format ! ( "Overflow in {op:?}" ) ) ) ;
869
+ }
870
+ }
871
+ Ok ( Owned ( r[ 0 ..lc. len ( ) ] . into ( ) ) )
872
+ } ;
863
873
match op {
864
874
BinOp :: Ge | BinOp :: Gt | BinOp :: Le | BinOp :: Lt | BinOp :: Eq | BinOp :: Ne => {
865
875
let r = op. run_compare ( l128, r128) as u8 ;
@@ -888,28 +898,23 @@ impl Evaluator<'_> {
888
898
BinOp :: BitXor => l128 ^ r128,
889
899
_ => unreachable ! ( ) ,
890
900
} ;
891
- let r = r. to_le_bytes ( ) ;
892
- for & k in & r[ lc. len ( ) ..] {
893
- if k != 0 && ( k != 255 || !is_signed) {
894
- return Err ( MirEvalError :: Panic ( format ! ( "Overflow in {op:?}" ) ) ) ;
895
- }
896
- }
897
- Owned ( r[ 0 ..lc. len ( ) ] . into ( ) )
901
+ check_overflow ( r) ?
898
902
}
899
903
BinOp :: Shl | BinOp :: Shr => {
900
- let shift_amount = if r128 < 0 {
901
- return Err ( MirEvalError :: Panic ( format ! ( "Overflow in {op:?}" ) ) ) ;
902
- } else if r128 > 128 {
904
+ let r = ' b: {
905
+ if let Ok ( shift_amount) = u32:: try_from ( r128) {
906
+ let r = match op {
907
+ BinOp :: Shl => l128. checked_shl ( shift_amount) ,
908
+ BinOp :: Shr => l128. checked_shr ( shift_amount) ,
909
+ _ => unreachable ! ( ) ,
910
+ } ;
911
+ if let Some ( r) = r {
912
+ break ' b r;
913
+ }
914
+ } ;
903
915
return Err ( MirEvalError :: Panic ( format ! ( "Overflow in {op:?}" ) ) ) ;
904
- } else {
905
- r128 as u8
906
- } ;
907
- let r = match op {
908
- BinOp :: Shl => l128 << shift_amount,
909
- BinOp :: Shr => l128 >> shift_amount,
910
- _ => unreachable ! ( ) ,
911
916
} ;
912
- Owned ( r . to_le_bytes ( ) [ 0 ..lc . len ( ) ] . into ( ) )
917
+ check_overflow ( r ) ?
913
918
}
914
919
BinOp :: Offset => not_supported ! ( "offset binop" ) ,
915
920
}
0 commit comments