compiler: Fix break/continue targets in loop else blocks

Previously, they would still target the respective labels in the
just-exited loop.

Signed-off-by: David Nadlinger <code@klickverbot.at>
This commit is contained in:
David Nadlinger 2016-11-05 02:28:43 +00:00
parent f102f2d4e6
commit 7dcc987dd7
3 changed files with 91 additions and 43 deletions

View File

@ -452,6 +452,9 @@ class ARTIQIRGenerator(algorithm.Visitor):
self.current_block = body
self.visit(node.body)
post_body = self.current_block
finally:
self.break_target = old_break
self.continue_target = old_continue
if any(node.orelse):
else_tail = self.add_block("while.else")
@ -472,9 +475,6 @@ class ARTIQIRGenerator(algorithm.Visitor):
if not post_body.is_terminated():
post_body.append(ir.Branch(head))
break_block.append(ir.Branch(tail))
finally:
self.break_target = old_break
self.continue_target = old_continue
def iterable_len(self, value, typ=_size_type):
if builtins.is_listish(value.type):
@ -541,6 +541,9 @@ class ARTIQIRGenerator(algorithm.Visitor):
self.current_assign = None
self.visit(node.body)
post_body = self.current_block
finally:
self.break_target = old_break
self.continue_target = old_continue
if any(node.orelse):
else_tail = self.add_block("for.else")
@ -564,9 +567,6 @@ class ARTIQIRGenerator(algorithm.Visitor):
if not post_body.is_terminated():
post_body.append(ir.Branch(continue_block))
break_block.append(ir.Branch(tail))
finally:
self.break_target = old_break
self.continue_target = old_continue
def visit_Break(self, node):
self.append(ir.Branch(self.break_target))

View File

@ -27,3 +27,27 @@ for x in range(10):
assert False
else:
assert False
# Verify continue target is reset in else block.
cond = False
while True:
if cond:
break
cond = True
for _ in range(1):
pass
else:
continue
assert False
else:
assert False
# Verify for target is reset in else block.
while True:
for _ in range(1):
pass
else:
break
assert False
else:
assert False

View File

@ -29,3 +29,27 @@ while cond:
cond = False
continue
assert False
# Verify continue target is reset in else block.
cond = False
while True:
if cond:
break
cond = True
while False:
assert False
else:
continue
assert False
else:
assert False
# Verify break target is reset in else block.
while True:
while False:
assert False
else:
break
assert False
else:
assert False