forked from M-Labs/artiq
Add tests for non-exceptional control flow across finally.
This commit is contained in:
parent
7c77dd317a
commit
90be44c596
|
@ -292,7 +292,7 @@ class BasicBlock(NamedValue):
|
||||||
|
|
||||||
def erase(self):
|
def erase(self):
|
||||||
# self.instructions is updated while iterating
|
# self.instructions is updated while iterating
|
||||||
for insn in list(self.instructions):
|
for insn in reversed(self.instructions):
|
||||||
insn.erase()
|
insn.erase()
|
||||||
self.remove_from_parent()
|
self.remove_from_parent()
|
||||||
# Check this after erasing instructions in case the block
|
# Check this after erasing instructions in case the block
|
||||||
|
@ -997,6 +997,7 @@ class Raise(Terminator):
|
||||||
return self.operands[0]
|
return self.operands[0]
|
||||||
|
|
||||||
def exception_target(self):
|
def exception_target(self):
|
||||||
|
if len(self.operands) > 1:
|
||||||
return self.operands[1]
|
return self.operands[1]
|
||||||
|
|
||||||
class Invoke(Terminator):
|
class Invoke(Terminator):
|
||||||
|
|
|
@ -25,6 +25,10 @@ class DeadCodeEliminator:
|
||||||
use.remove_incoming_block(block)
|
use.remove_incoming_block(block)
|
||||||
if not any(use.operands):
|
if not any(use.operands):
|
||||||
self.remove_instruction(use)
|
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:
|
else:
|
||||||
assert False
|
assert False
|
||||||
|
|
||||||
|
|
|
@ -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())
|
Loading…
Reference in New Issue