@@ -499,55 +499,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
499
499
}
500
500
}
501
501
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
-
551
502
fn propagate_operand ( & mut self , operand : & mut Operand < ' tcx > ) {
552
503
match * operand {
553
504
Operand :: Copy ( l) | Operand :: Move ( l) => {
@@ -583,28 +534,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
583
534
// 2. Working around bugs in other parts of the compiler
584
535
// - In this case, we'll return `None` from this function to stop evaluation.
585
536
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
-
608
537
// Do not try creating references (#67862)
609
538
Rvalue :: AddressOf ( _, place) | Rvalue :: Ref ( _, _, place) => {
610
539
trace ! ( "skipping AddressOf | Ref for {:?}" , place) ;
@@ -634,7 +563,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
634
563
| Rvalue :: Cast ( ..)
635
564
| Rvalue :: ShallowInitBox ( ..)
636
565
| Rvalue :: Discriminant ( ..)
637
- | Rvalue :: NullaryOp ( ..) => { }
566
+ | Rvalue :: NullaryOp ( ..)
567
+ | Rvalue :: UnaryOp ( ..)
568
+ | Rvalue :: BinaryOp ( ..)
569
+ | Rvalue :: CheckedBinaryOp ( ..) => { }
638
570
}
639
571
640
572
// FIXME we need to revisit this for #67176
@@ -1071,31 +1003,18 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
1071
1003
1072
1004
match & mut terminator. kind {
1073
1005
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)
1077
1007
// FIXME should be used use_ecx rather than a local match... but we have
1078
1008
// 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
+ ) ;
1099
1018
}
1100
1019
}
1101
1020
TerminatorKind :: SwitchInt { ref mut discr, .. } => {
0 commit comments