@@ -15,7 +15,7 @@ use rustc_middle::mir::visit::{
15
15
} ;
16
16
use rustc_middle:: mir:: {
17
17
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 ,
19
19
RETURN_PLACE ,
20
20
} ;
21
21
use rustc_middle:: ty:: layout:: { LayoutError , LayoutOf , LayoutOfHelpers , TyAndLayout } ;
@@ -503,55 +503,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
503
503
}
504
504
}
505
505
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
-
555
506
fn propagate_operand ( & mut self , operand : & mut Operand < ' tcx > ) {
556
507
match * operand {
557
508
Operand :: Copy ( l) | Operand :: Move ( l) => {
@@ -587,28 +538,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
587
538
// 2. Working around bugs in other parts of the compiler
588
539
// - In this case, we'll return `None` from this function to stop evaluation.
589
540
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
-
612
541
// Do not try creating references (#67862)
613
542
Rvalue :: AddressOf ( _, place) | Rvalue :: Ref ( _, _, place) => {
614
543
trace ! ( "skipping AddressOf | Ref for {:?}" , place) ;
@@ -638,7 +567,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
638
567
| Rvalue :: Cast ( ..)
639
568
| Rvalue :: ShallowInitBox ( ..)
640
569
| Rvalue :: Discriminant ( ..)
641
- | Rvalue :: NullaryOp ( ..) => { }
570
+ | Rvalue :: NullaryOp ( ..)
571
+ | Rvalue :: UnaryOp ( ..)
572
+ | Rvalue :: BinaryOp ( ..)
573
+ | Rvalue :: CheckedBinaryOp ( ..) => { }
642
574
}
643
575
644
576
// FIXME we need to revisit this for #67176
@@ -1079,31 +1011,18 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
1079
1011
// Do NOT early return in this function, it does some crucial fixup of the state at the end!
1080
1012
match & mut terminator. kind {
1081
1013
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)
1085
1015
// FIXME should be used use_ecx rather than a local match... but we have
1086
1016
// 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
+ ) ;
1107
1026
}
1108
1027
}
1109
1028
TerminatorKind :: SwitchInt { ref mut discr, .. } => {
0 commit comments