Skip to content

Commit 506dd70

Browse files
committed
fix const_prop detecting unary neg underflows
1 parent e6a5a94 commit 506dd70

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

src/librustc_mir/transform/const_prop.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
use rustc::hir::def::Def;
1616
use rustc::mir::{Constant, Location, Place, Mir, Operand, Rvalue, Local};
17-
use rustc::mir::{NullOp, StatementKind, Statement, BasicBlock, LocalKind};
17+
use rustc::mir::{NullOp, UnOp, StatementKind, Statement, BasicBlock, LocalKind};
1818
use rustc::mir::{TerminatorKind, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem};
1919
use rustc::mir::visit::{Visitor, PlaceContext};
2020
use rustc::mir::interpret::{
@@ -381,6 +381,20 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
381381
let (arg, _) = self.eval_operand(arg, source_info)?;
382382
let val = self.use_ecx(source_info, |this| {
383383
let prim = this.ecx.read_scalar(arg)?.not_undef()?;
384+
match op {
385+
UnOp::Neg => {
386+
// Need to do overflow check here: For actual CTFE, MIR
387+
// generation emits code that does this before calling the op.
388+
let size = arg.layout.size;
389+
if prim.to_bits(size)? == (1 << (size.bits() - 1)) {
390+
return err!(OverflowNeg);
391+
}
392+
}
393+
UnOp::Not => {
394+
// Cannot overflow
395+
}
396+
}
397+
// Now run the actual operation.
384398
this.ecx.unary_op(op, prim, arg.layout)
385399
})?;
386400
Some((OpTy::from_scalar_value(val, place_layout), span))

0 commit comments

Comments
 (0)