diff options
| author | Felix S. Klock II <pnkfelix@pnkfx.org> | 2014-05-20 18:49:19 +0200 |
|---|---|---|
| committer | Felix S. Klock II <pnkfelix@pnkfx.org> | 2014-06-18 16:36:25 +0200 |
| commit | be9c2d13815eb9aa1b6213a46542aa4262127643 (patch) | |
| tree | 6ceb40fff1fe88e11b9483c98ac4df04bfe18456 /src | |
| parent | 34e3232705539e4506ceb4c19944f7d894413fca (diff) | |
Bug fixes for flowgraph construction.
1. After recursively processing an ExprWhile, need to pop loop_scopes the same way we do for ExprLoop. 2. Proposed fix for flowgraph handling of ExprInlineAsm: we need to represent the flow into the subexpressions of an `asm!` block.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/middle/cfg/construct.rs | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index f855ca37597..0d8729071ef 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -254,6 +254,7 @@ impl<'a> CFGBuilder<'a> { }); let body_exit = self.block(&**body, cond_exit); // 4 self.add_contained_edge(body_exit, loopback); // 5 + self.loop_scopes.pop(); expr_exit } @@ -427,8 +428,22 @@ impl<'a> CFGBuilder<'a> { self.straightline(expr, pred, [e]) } + ast::ExprInlineAsm(ref inline_asm) => { + let inputs = inline_asm.inputs.iter(); + let outputs = inline_asm.outputs.iter(); + fn extract_expr<A>(&(_, expr): &(A, Gc<ast::Expr>)) -> Gc<ast::Expr> { expr } + let post_inputs = self.exprs(inputs.map(|a| { + debug!("cfg::construct InlineAsm id:{} input:{:?}", expr.id, a); + extract_expr(a) + }), pred); + let post_outputs = self.exprs(outputs.map(|a| { + debug!("cfg::construct InlineAsm id:{} output:{:?}", expr.id, a); + extract_expr(a) + }), post_inputs); + self.add_node(expr.id, [post_outputs]) + } + ast::ExprMac(..) | - ast::ExprInlineAsm(..) | ast::ExprFnBlock(..) | ast::ExprProc(..) | ast::ExprLit(..) | @@ -444,15 +459,22 @@ impl<'a> CFGBuilder<'a> { func_or_rcvr: Gc<ast::Expr>, args: &[Gc<ast::Expr>]) -> CFGIndex { let func_or_rcvr_exit = self.expr(func_or_rcvr, pred); - self.straightline(call_expr, func_or_rcvr_exit, args) + let ret = self.straightline(call_expr, func_or_rcvr_exit, args); + + let return_ty = ty::node_id_to_type(self.tcx, call_expr.id); + let fails = ty::type_is_bot(return_ty); + if fails { + self.add_node(ast::DUMMY_NODE_ID, []) + } else { + ret + } } - fn exprs(&mut self, - exprs: &[Gc<ast::Expr>], - pred: CFGIndex) -> CFGIndex { + fn exprs<I:Iterator<Gc<ast::Expr>>>(&mut self, + mut exprs: I, + pred: CFGIndex) -> CFGIndex { //! Constructs graph for `exprs` evaluated in order - - exprs.iter().fold(pred, |p, &e| self.expr(e, p)) + exprs.fold(pred, |p, e| self.expr(e, p)) } fn opt_expr(&mut self, @@ -469,7 +491,7 @@ impl<'a> CFGBuilder<'a> { subexprs: &[Gc<ast::Expr>]) -> CFGIndex { //! Handles case of an expression that evaluates `subexprs` in order - let subexprs_exit = self.exprs(subexprs, pred); + let subexprs_exit = self.exprs(subexprs.iter().map(|&e|e), pred); self.add_node(expr.id, [subexprs_exit]) } |
