Change with_cond
to build_cond_br
This is simpler to work with than `with_cond`.
This commit is contained in:
parent
bcdb2602f8
commit
7fbff36d01
@ -83,10 +83,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
// Helper method for generating MIR inside a conditional block.
|
||||
pub fn with_cond<F>(&mut self, block: BasicBlock, span: Span,
|
||||
cond: Operand<'tcx>, f: F) -> BasicBlock
|
||||
where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>, BasicBlock) -> BasicBlock {
|
||||
// Helper method for generating a conditional branch
|
||||
// Returns (TrueBlock, FalseBlock)
|
||||
pub fn build_cond_br(&mut self, block: BasicBlock, span: Span,
|
||||
cond: Operand<'tcx>) -> (BasicBlock, BasicBlock) {
|
||||
let scope_id = self.innermost_scope_id();
|
||||
|
||||
let then_block = self.cfg.start_new_block();
|
||||
@ -98,15 +98,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
targets: (then_block, else_block)
|
||||
});
|
||||
|
||||
let after = f(self, then_block);
|
||||
|
||||
// If the returned block isn't terminated, add a branch to the "else"
|
||||
// block
|
||||
if !self.cfg.terminated(after) {
|
||||
self.cfg.terminate(after, scope_id, span,
|
||||
TerminatorKind::Goto { target: else_block });
|
||||
}
|
||||
|
||||
else_block
|
||||
(then_block, else_block)
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ impl<'tcx> CFG<'tcx> {
|
||||
scope: ScopeId,
|
||||
span: Span,
|
||||
kind: TerminatorKind<'tcx>) {
|
||||
debug_assert!(!self.terminated(block),
|
||||
debug_assert!(self.block_data(block).terminator.is_none(),
|
||||
"terminate: block {:?} already has a terminator set", block);
|
||||
self.block_data_mut(block).terminator = Some(Terminator {
|
||||
span: span,
|
||||
@ -94,9 +94,4 @@ impl<'tcx> CFG<'tcx> {
|
||||
kind: kind,
|
||||
});
|
||||
}
|
||||
|
||||
/// Returns whether or not the given block has been terminated or not
|
||||
pub fn terminated(&self, block: BasicBlock) -> bool {
|
||||
self.block_data(block).terminator.is_some()
|
||||
}
|
||||
}
|
||||
|
@ -88,11 +88,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
this.cfg.push_assign(block, scope_id, expr_span, &is_min,
|
||||
Rvalue::BinaryOp(BinOp::Eq, arg.clone(), minval));
|
||||
|
||||
block = this.with_cond(
|
||||
block, expr_span, Operand::Consume(is_min), |this, block| {
|
||||
this.panic(block, "attempted to negate with overflow", expr_span);
|
||||
block
|
||||
});
|
||||
let (of_block, ok_block) = this.build_cond_br(block, expr_span,
|
||||
Operand::Consume(is_min));
|
||||
this.panic(of_block, "attempted to negate with overflow", expr_span);
|
||||
block = ok_block;
|
||||
}
|
||||
block.and(Rvalue::UnaryOp(op, arg))
|
||||
}
|
||||
@ -243,7 +242,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_binary_op(&mut self, mut block: BasicBlock, op: BinOp, span: Span, ty: ty::Ty<'tcx>,
|
||||
pub fn build_binary_op(&mut self, mut block: BasicBlock,
|
||||
op: BinOp, span: Span, ty: ty::Ty<'tcx>,
|
||||
lhs: Operand<'tcx>, rhs: Operand<'tcx>) -> BlockAnd<Rvalue<'tcx>> {
|
||||
let scope_id = self.innermost_scope_id();
|
||||
let bool_ty = self.hir.bool_ty();
|
||||
@ -267,12 +267,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
"arithmetic operation overflowed"
|
||||
};
|
||||
|
||||
block = self.with_cond(block, span, Operand::Consume(of), |this, block| {
|
||||
this.panic(block, msg, span);
|
||||
block
|
||||
});
|
||||
let (of_block, ok_block) = self.build_cond_br(block, span, Operand::Consume(of));
|
||||
self.panic(of_block, msg, span);
|
||||
|
||||
block.and(Rvalue::Use(Operand::Consume(val)))
|
||||
ok_block.and(Rvalue::Use(Operand::Consume(val)))
|
||||
} else {
|
||||
if ty.is_integral() && (op == BinOp::Div || op == BinOp::Rem) {
|
||||
// Checking division and remainder is more complex, since we 1. always check
|
||||
@ -292,10 +290,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
self.cfg.push_assign(block, scope_id, span, &is_zero,
|
||||
Rvalue::BinaryOp(BinOp::Eq, rhs.clone(), zero));
|
||||
|
||||
block = self.with_cond(block, span, Operand::Consume(is_zero), |this, block| {
|
||||
this.panic(block, zero_msg, span);
|
||||
block
|
||||
});
|
||||
let (zero_block, ok_block) = self.build_cond_br(block, span,
|
||||
Operand::Consume(is_zero));
|
||||
self.panic(zero_block, zero_msg, span);
|
||||
|
||||
block = ok_block;
|
||||
|
||||
// We only need to check for the overflow in one case:
|
||||
// MIN / -1, and only for signed values.
|
||||
@ -319,10 +318,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
self.cfg.push_assign(block, scope_id, span, &of,
|
||||
Rvalue::BinaryOp(BinOp::BitAnd, is_neg_1, is_min));
|
||||
|
||||
block = self.with_cond(block, span, Operand::Consume(of), |this, block| {
|
||||
this.panic(block, overflow_msg, span);
|
||||
block
|
||||
});
|
||||
let (of_block, ok_block) = self.build_cond_br(block, span,
|
||||
Operand::Consume(of));
|
||||
self.panic(of_block, overflow_msg, span);
|
||||
|
||||
block = ok_block;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user