@@ -15,7 +15,7 @@ use rustc_middle::mir::visit::{
1515} ;
1616use rustc_middle:: mir:: {
1717 BasicBlock , BinOp , Body , Constant , ConstantKind , Local , LocalDecl , LocalKind , Location ,
18- Operand , Place , Rvalue , SourceInfo , Statement , StatementKind , Terminator , TerminatorKind , UnOp ,
18+ Operand , Place , Rvalue , SourceInfo , Statement , StatementKind , Terminator , TerminatorKind ,
1919 RETURN_PLACE ,
2020} ;
2121use rustc_middle:: ty:: layout:: { LayoutError , LayoutOf , LayoutOfHelpers , TyAndLayout } ;
@@ -503,55 +503,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
503503 }
504504 }
505505
506- fn check_unary_op ( & mut self , op : UnOp , arg : & Operand < ' tcx > ) -> Option < ( ) > {
507- if self . use_ecx ( |this| {
508- let val = this. ecx . read_immediate ( & this. ecx . eval_operand ( arg, None ) ?) ?;
509- let ( _res, overflow, _ty) = this. ecx . overflowing_unary_op ( op, & val) ?;
510- Ok ( overflow)
511- } ) ? {
512- // `AssertKind` only has an `OverflowNeg` variant, so make sure that is
513- // appropriate to use.
514- assert_eq ! ( op, UnOp :: Neg , "Neg is the only UnOp that can overflow" ) ;
515- return None ;
516- }
517-
518- Some ( ( ) )
519- }
520-
521- fn check_binary_op (
522- & mut self ,
523- op : BinOp ,
524- left : & Operand < ' tcx > ,
525- right : & Operand < ' tcx > ,
526- ) -> Option < ( ) > {
527- let r = self . use_ecx ( |this| this. ecx . read_immediate ( & this. ecx . eval_operand ( right, None ) ?) ) ;
528- let l = self . use_ecx ( |this| this. ecx . read_immediate ( & this. ecx . eval_operand ( left, None ) ?) ) ;
529- // Check for exceeding shifts *even if* we cannot evaluate the LHS.
530- if matches ! ( op, BinOp :: Shr | BinOp :: Shl ) {
531- let r = r. clone ( ) ?;
532- // We need the type of the LHS. We cannot use `place_layout` as that is the type
533- // of the result, which for checked binops is not the same!
534- let left_ty = left. ty ( self . local_decls , self . tcx ) ;
535- let left_size = self . ecx . layout_of ( left_ty) . ok ( ) ?. size ;
536- let right_size = r. layout . size ;
537- let r_bits = r. to_scalar ( ) . to_bits ( right_size) . ok ( ) ;
538- if r_bits. map_or ( false , |b| b >= left_size. bits ( ) as u128 ) {
539- return None ;
540- }
541- }
542-
543- if let ( Some ( l) , Some ( r) ) = ( & l, & r) {
544- // The remaining operators are handled through `overflowing_binary_op`.
545- if self . use_ecx ( |this| {
546- let ( _res, overflow, _ty) = this. ecx . overflowing_binary_op ( op, l, r) ?;
547- Ok ( overflow)
548- } ) ? {
549- return None ;
550- }
551- }
552- Some ( ( ) )
553- }
554-
555506 fn propagate_operand ( & mut self , operand : & mut Operand < ' tcx > ) {
556507 match * operand {
557508 Operand :: Copy ( l) | Operand :: Move ( l) => {
@@ -587,28 +538,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
587538 // 2. Working around bugs in other parts of the compiler
588539 // - In this case, we'll return `None` from this function to stop evaluation.
589540 match rvalue {
590- // Additional checking: give lints to the user if an overflow would occur.
591- // We do this here and not in the `Assert` terminator as that terminator is
592- // only sometimes emitted (overflow checks can be disabled), but we want to always
593- // lint.
594- Rvalue :: UnaryOp ( op, arg) => {
595- trace ! ( "checking UnaryOp(op = {:?}, arg = {:?})" , op, arg) ;
596- self . check_unary_op ( * op, arg) ?;
597- }
598- Rvalue :: BinaryOp ( op, box ( left, right) ) => {
599- trace ! ( "checking BinaryOp(op = {:?}, left = {:?}, right = {:?})" , op, left, right) ;
600- self . check_binary_op ( * op, left, right) ?;
601- }
602- Rvalue :: CheckedBinaryOp ( op, box ( left, right) ) => {
603- trace ! (
604- "checking CheckedBinaryOp(op = {:?}, left = {:?}, right = {:?})" ,
605- op,
606- left,
607- right
608- ) ;
609- self . check_binary_op ( * op, left, right) ?;
610- }
611-
612541 // Do not try creating references (#67862)
613542 Rvalue :: AddressOf ( _, place) | Rvalue :: Ref ( _, _, place) => {
614543 trace ! ( "skipping AddressOf | Ref for {:?}" , place) ;
@@ -638,7 +567,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
638567 | Rvalue :: Cast ( ..)
639568 | Rvalue :: ShallowInitBox ( ..)
640569 | Rvalue :: Discriminant ( ..)
641- | Rvalue :: NullaryOp ( ..) => { }
570+ | Rvalue :: NullaryOp ( ..)
571+ | Rvalue :: UnaryOp ( ..)
572+ | Rvalue :: BinaryOp ( ..)
573+ | Rvalue :: CheckedBinaryOp ( ..) => { }
642574 }
643575
644576 // FIXME we need to revisit this for #67176
@@ -1079,31 +1011,18 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
10791011 // Do NOT early return in this function, it does some crucial fixup of the state at the end!
10801012 match & mut terminator. kind {
10811013 TerminatorKind :: Assert { expected, ref mut cond, .. } => {
1082- if let Some ( ref value) = self . eval_operand ( & cond) {
1083- trace ! ( "assertion on {:?} should be {:?}" , value, expected) ;
1084- let expected = Scalar :: from_bool ( * expected) ;
1014+ if let Some ( ref value) = self . eval_operand ( & cond)
10851015 // FIXME should be used use_ecx rather than a local match... but we have
10861016 // quite a few of these read_scalar/read_immediate that need fixing.
1087- if let Ok ( value_const) = self . ecx . read_scalar ( & value) {
1088- if expected != value_const {
1089- // Poison all places this operand references so that further code
1090- // doesn't use the invalid value
1091- match cond {
1092- Operand :: Move ( ref place) | Operand :: Copy ( ref place) => {
1093- Self :: remove_const ( & mut self . ecx , place. local ) ;
1094- }
1095- Operand :: Constant ( _) => { }
1096- }
1097- } else {
1098- if self . should_const_prop ( value) {
1099- * cond = self . operand_from_scalar (
1100- value_const,
1101- self . tcx . types . bool ,
1102- source_info. span ,
1103- ) ;
1104- }
1105- }
1106- }
1017+ && let Ok ( value_const) = self . ecx . read_scalar ( & value)
1018+ && self . should_const_prop ( value)
1019+ {
1020+ trace ! ( "assertion on {:?} should be {:?}" , value, expected) ;
1021+ * cond = self . operand_from_scalar (
1022+ value_const,
1023+ self . tcx . types . bool ,
1024+ source_info. span ,
1025+ ) ;
11071026 }
11081027 }
11091028 TerminatorKind :: SwitchInt { ref mut discr, .. } => {
0 commit comments