Skip to content

Commit 931d99f

Browse files
committed
Make overflow handling more precise
1 parent be9013f commit 931d99f

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

compiler/rustc_mir_transform/src/dataflow_const_prop.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,26 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'tcx> {
7373
});
7474

7575
if value_target.is_some() || overflow_target.is_some() {
76-
let (val, mut overflow) = self.binary_op(state, *op, left, right);
77-
78-
if !self.propagate_overflow {
79-
overflow = FlatSet::Top;
80-
}
76+
let (val, overflow) = self.binary_op(state, *op, left, right);
8177

8278
if let Some(value_target) = value_target {
8379
state.assign_idx(value_target, ValueOrPlaceOrRef::Value(val), self.map());
8480
}
8581
if let Some(overflow_target) = overflow_target {
82+
let overflow = match overflow {
83+
FlatSet::Top => FlatSet::Top,
84+
FlatSet::Elem(overflow) => {
85+
if overflow && !self.propagate_overflow {
86+
FlatSet::Top
87+
} else {
88+
self.wrap_scalar(
89+
Scalar::from_bool(overflow),
90+
self.tcx.types.bool,
91+
)
92+
}
93+
}
94+
FlatSet::Bottom => FlatSet::Bottom,
95+
};
8696
state.assign_idx(
8797
overflow_target,
8898
ValueOrPlaceOrRef::Value(overflow),
@@ -120,8 +130,8 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'tcx> {
120130
}
121131
}
122132
Rvalue::BinaryOp(op, box (left, right)) => {
133+
// Overflows must be ignored here.
123134
let (val, _overflow) = self.binary_op(state, *op, left, right);
124-
// FIXME: Just ignore overflow here?
125135
ValueOrPlaceOrRef::Value(val)
126136
}
127137
Rvalue::UnaryOp(op, operand) => match self.eval_operand(operand, state) {
@@ -230,16 +240,13 @@ impl<'tcx> ConstAnalysis<'tcx> {
230240
op: BinOp,
231241
left: &Operand<'tcx>,
232242
right: &Operand<'tcx>,
233-
) -> (FlatSet<ScalarTy<'tcx>>, FlatSet<ScalarTy<'tcx>>) {
243+
) -> (FlatSet<ScalarTy<'tcx>>, FlatSet<bool>) {
234244
let left = self.eval_operand(left, state);
235245
let right = self.eval_operand(right, state);
236246
match (left, right) {
237247
(FlatSet::Elem(left), FlatSet::Elem(right)) => {
238248
match self.ecx.overflowing_binary_op(op, &left, &right) {
239-
Ok((val, overflow, ty)) => (
240-
self.wrap_scalar(val, ty),
241-
self.wrap_scalar(Scalar::from_bool(overflow), self.tcx.types.bool),
242-
),
249+
Ok((val, overflow, ty)) => (self.wrap_scalar(val, ty), FlatSet::Elem(overflow)),
243250
_ => (FlatSet::Top, FlatSet::Top),
244251
}
245252
}

0 commit comments

Comments
 (0)