@@ -499,55 +499,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
499499 }
500500 }
501501
502- fn check_unary_op ( & mut self , op : UnOp , arg : & Operand < ' tcx > ) -> Option < ( ) > {
503- if self . use_ecx ( |this| {
504- let val = this. ecx . read_immediate ( & this. ecx . eval_operand ( arg, None ) ?) ?;
505- let ( _res, overflow, _ty) = this. ecx . overflowing_unary_op ( op, & val) ?;
506- Ok ( overflow)
507- } ) ? {
508- // `AssertKind` only has an `OverflowNeg` variant, so make sure that is
509- // appropriate to use.
510- assert_eq ! ( op, UnOp :: Neg , "Neg is the only UnOp that can overflow" ) ;
511- return None ;
512- }
513-
514- Some ( ( ) )
515- }
516-
517- fn check_binary_op (
518- & mut self ,
519- op : BinOp ,
520- left : & Operand < ' tcx > ,
521- right : & Operand < ' tcx > ,
522- ) -> Option < ( ) > {
523- let r = self . use_ecx ( |this| this. ecx . read_immediate ( & this. ecx . eval_operand ( right, None ) ?) ) ;
524- let l = self . use_ecx ( |this| this. ecx . read_immediate ( & this. ecx . eval_operand ( left, None ) ?) ) ;
525- // Check for exceeding shifts *even if* we cannot evaluate the LHS.
526- if matches ! ( op, BinOp :: Shr | BinOp :: Shl ) {
527- let r = r. clone ( ) ?;
528- // We need the type of the LHS. We cannot use `place_layout` as that is the type
529- // of the result, which for checked binops is not the same!
530- let left_ty = left. ty ( self . local_decls , self . tcx ) ;
531- let left_size = self . ecx . layout_of ( left_ty) . ok ( ) ?. size ;
532- let right_size = r. layout . size ;
533- let r_bits = r. to_scalar ( ) . to_bits ( right_size) . ok ( ) ;
534- if r_bits. map_or ( false , |b| b >= left_size. bits ( ) as u128 ) {
535- return None ;
536- }
537- }
538-
539- if let ( Some ( l) , Some ( r) ) = ( & l, & r) {
540- // The remaining operators are handled through `overflowing_binary_op`.
541- if self . use_ecx ( |this| {
542- let ( _res, overflow, _ty) = this. ecx . overflowing_binary_op ( op, l, r) ?;
543- Ok ( overflow)
544- } ) ? {
545- return None ;
546- }
547- }
548- Some ( ( ) )
549- }
550-
551502 fn propagate_operand ( & mut self , operand : & mut Operand < ' tcx > ) {
552503 match * operand {
553504 Operand :: Copy ( l) | Operand :: Move ( l) => {
@@ -583,28 +534,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
583534 // 2. Working around bugs in other parts of the compiler
584535 // - In this case, we'll return `None` from this function to stop evaluation.
585536 match rvalue {
586- // Additional checking: give lints to the user if an overflow would occur.
587- // We do this here and not in the `Assert` terminator as that terminator is
588- // only sometimes emitted (overflow checks can be disabled), but we want to always
589- // lint.
590- Rvalue :: UnaryOp ( op, arg) => {
591- trace ! ( "checking UnaryOp(op = {:?}, arg = {:?})" , op, arg) ;
592- self . check_unary_op ( * op, arg) ?;
593- }
594- Rvalue :: BinaryOp ( op, box ( left, right) ) => {
595- trace ! ( "checking BinaryOp(op = {:?}, left = {:?}, right = {:?})" , op, left, right) ;
596- self . check_binary_op ( * op, left, right) ?;
597- }
598- Rvalue :: CheckedBinaryOp ( op, box ( left, right) ) => {
599- trace ! (
600- "checking CheckedBinaryOp(op = {:?}, left = {:?}, right = {:?})" ,
601- op,
602- left,
603- right
604- ) ;
605- self . check_binary_op ( * op, left, right) ?;
606- }
607-
608537 // Do not try creating references (#67862)
609538 Rvalue :: AddressOf ( _, place) | Rvalue :: Ref ( _, _, place) => {
610539 trace ! ( "skipping AddressOf | Ref for {:?}" , place) ;
@@ -634,7 +563,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
634563 | Rvalue :: Cast ( ..)
635564 | Rvalue :: ShallowInitBox ( ..)
636565 | Rvalue :: Discriminant ( ..)
637- | Rvalue :: NullaryOp ( ..) => { }
566+ | Rvalue :: NullaryOp ( ..)
567+ | Rvalue :: UnaryOp ( ..)
568+ | Rvalue :: BinaryOp ( ..)
569+ | Rvalue :: CheckedBinaryOp ( ..) => { }
638570 }
639571
640572 // FIXME we need to revisit this for #67176
@@ -1071,31 +1003,18 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
10711003
10721004 match & mut terminator. kind {
10731005 TerminatorKind :: Assert { expected, ref mut cond, .. } => {
1074- if let Some ( ref value) = self . eval_operand ( & cond) {
1075- trace ! ( "assertion on {:?} should be {:?}" , value, expected) ;
1076- let expected = Scalar :: from_bool ( * expected) ;
1006+ if let Some ( ref value) = self . eval_operand ( & cond)
10771007 // FIXME should be used use_ecx rather than a local match... but we have
10781008 // quite a few of these read_scalar/read_immediate that need fixing.
1079- if let Ok ( value_const) = self . ecx . read_scalar ( & value) {
1080- if expected != value_const {
1081- // Poison all places this operand references so that further code
1082- // doesn't use the invalid value
1083- match cond {
1084- Operand :: Move ( ref place) | Operand :: Copy ( ref place) => {
1085- Self :: remove_const ( & mut self . ecx , place. local ) ;
1086- }
1087- Operand :: Constant ( _) => { }
1088- }
1089- } else {
1090- if self . should_const_prop ( value) {
1091- * cond = self . operand_from_scalar (
1092- value_const,
1093- self . tcx . types . bool ,
1094- source_info. span ,
1095- ) ;
1096- }
1097- }
1098- }
1009+ && let Ok ( value_const) = self . ecx . read_scalar ( & value)
1010+ && self . should_const_prop ( value)
1011+ {
1012+ trace ! ( "assertion on {:?} should be {:?}" , value, expected) ;
1013+ * cond = self . operand_from_scalar (
1014+ value_const,
1015+ self . tcx . types . bool ,
1016+ source_info. span ,
1017+ ) ;
10991018 }
11001019 }
11011020 TerminatorKind :: SwitchInt { ref mut discr, .. } => {
0 commit comments