Add tests for non-exceptional control flow across finally.

This commit is contained in:
whitequark 2015-07-27 10:13:22 +03:00
parent 7c77dd317a
commit 90be44c596
3 changed files with 71 additions and 2 deletions

View File

@ -292,7 +292,7 @@ class BasicBlock(NamedValue):
def erase(self):
# self.instructions is updated while iterating
for insn in list(self.instructions):
for insn in reversed(self.instructions):
insn.erase()
self.remove_from_parent()
# Check this after erasing instructions in case the block
@ -997,7 +997,8 @@ class Raise(Terminator):
return self.operands[0]
def exception_target(self):
return self.operands[1]
if len(self.operands) > 1:
return self.operands[1]
class Invoke(Terminator):
"""

View File

@ -25,6 +25,10 @@ class DeadCodeEliminator:
use.remove_incoming_block(block)
if not any(use.operands):
self.remove_instruction(use)
elif isinstance(use, ir.SetLocal):
# Setting the target for `finally` resumption, e.g.
# setlocal(.k) %v.4, label %try.doreturn
use.erase()
else:
assert False

View File

@ -0,0 +1,64 @@
# RUN: %python -m artiq.compiler.testbench.jit %s
# RUN: %python %s
# REQUIRES: exceptions
def f():
while True:
try:
print("f-try")
break
finally:
print("f-finally")
print("f-out")
# CHECK-L: f-try
# CHECK-L: f-finally
# CHECK-L: f-out
f()
def g():
x = True
while x:
try:
print("g-try")
x = False
continue
finally:
print("g-finally")
print("g-out")
# CHECK-L: g-try
# CHECK-L: g-finally
# CHECK-L: g-out
g()
def h():
try:
print("h-try")
return 10
finally:
print("h-finally")
print("h-out")
return 20
# CHECK-L: h-try
# CHECK-L: h-finally
# CHECK-NOT-L: h-out
# CHECK-L: h 10
print("h", h())
def i():
try:
print("i-try")
return 10
finally:
print("i-finally")
return 30
print("i-out")
return 20
# CHECK-L: i-try
# CHECK-L: i-finally
# CHECK-NOT-L: i-out
# CHECK-L: i 30
print("i", i())