about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2014-05-20 18:49:19 +0200
committerFelix S. Klock II <pnkfelix@pnkfx.org>2014-06-18 16:36:25 +0200
commitbe9c2d13815eb9aa1b6213a46542aa4262127643 (patch)
tree6ceb40fff1fe88e11b9483c98ac4df04bfe18456 /src
parent34e3232705539e4506ceb4c19944f7d894413fca (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.rs38
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])
     }