[pypy-commit] pypy framestate: deal with unreachable END_FINALLY

rlamy noreply at buildbot.pypy.org
Mon Feb 16 20:41:56 CET 2015


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: framestate
Changeset: r75927:feaa2a862f65
Date: 2015-02-16 19:21 +0000
http://bitbucket.org/pypy/pypy/changeset/feaa2a862f65/

Log:	deal with unreachable END_FINALLY

diff --git a/rpython/flowspace/bytecode.py b/rpython/flowspace/bytecode.py
--- a/rpython/flowspace/bytecode.py
+++ b/rpython/flowspace/bytecode.py
@@ -235,7 +235,10 @@
 
     def splice_finally_handler(self, block, context):
         cell = []
+        copied = {}
         def copy_block(handler):
+            if handler in copied:
+                return copied[handler]
             b = handler.copy()
             if handler is context.handler_end:
                 instr = b.operations.pop()
@@ -244,13 +247,17 @@
             else:
                 b.set_exits([copy_block(child) for child in handler._exits])
             self.blocks.append(b)
+            copied[handler] = b
             return b
         block.set_exits([copy_block(context.handler)])
-        copy_of_handler_end, = cell
-        return copy_of_handler_end
+        if cell:
+            copy_of_handler_end, = cell
+            return copy_of_handler_end
+        else:  # END_FINALLY is unreachable
+            return None
 
     def check_graph(self):
-        for b in self.blocks:
+        for b in self.graph.iterblocks():
             if not b._exits:
                 instr = b.operations[-1]
                 assert instr.name in (
@@ -670,7 +677,9 @@
                 block = reader.splice_finally_handler(block, context.block)
                 assert len(block.operations) == 1
                 block.operations = [PUSH_NONE()] + block.operations + [POP_TOP()]
-        block.operations.append(self)
+        if block is not None:
+            block.operations.append(self)
+            block.set_exits([])
 
     def eval(self, ctx):
         ctx.do_return()
diff --git a/rpython/flowspace/test/test_bytecode.py b/rpython/flowspace/test/test_bytecode.py
--- a/rpython/flowspace/test/test_bytecode.py
+++ b/rpython/flowspace/test/test_bytecode.py
@@ -12,7 +12,7 @@
         else:
             return 0
     bc_graph = make_graph(f)
-    assert [lst[0].offset for lst in bc_graph.dump()] == [0, 6, 10, 14]
+    assert [lst[0].offset for lst in bc_graph.dump()] == [0, 6, 10]
     assert bc_graph.dump()[0][0] == bc_reader.new_instr('LOAD_FAST', 0)
 
 def test_blockstack():
diff --git a/rpython/flowspace/test/test_objspace.py b/rpython/flowspace/test/test_objspace.py
--- a/rpython/flowspace/test/test_objspace.py
+++ b/rpython/flowspace/test/test_objspace.py
@@ -263,6 +263,19 @@
     def test_finallys(self):
         x = self.codetest(self.finallys)
 
+    def test_branching_in_finally(self):
+        def f(x, y):
+            try:
+                return x
+            finally:
+                if x:
+                    x = 0
+                if y > 0:
+                    y -= 1
+                return y
+        self.codetest(f)
+
+
     #__________________________________________________________
     def const_pow():
         return 2 ** 5


More information about the pypy-commit mailing list