summaryrefslogtreecommitdiff
path: root/Cython/Compiler/Nodes.py
diff options
context:
space:
mode:
Diffstat (limited to 'Cython/Compiler/Nodes.py')
-rw-r--r--Cython/Compiler/Nodes.py23
1 files changed, 14 insertions, 9 deletions
diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py
index c5ddad0a6..457ae94ad 100644
--- a/Cython/Compiler/Nodes.py
+++ b/Cython/Compiler/Nodes.py
@@ -6723,23 +6723,28 @@ class _ForInStatNode(LoopNode, StatNode):
code.set_loop_labels(old_loop_labels)
if self.else_clause:
- # in nested loops, the 'else' block can contain a
- # 'continue' statement for the outer loop, but we may need
- # to generate cleanup code before taking that path, so we
- # intercept it here
- orig_continue_label = code.continue_label
+ # In nested loops, the 'else' block can contain 'continue' or 'break'
+ # statements for the outer loop, but we may need to generate cleanup code
+ # before taking those paths, so we intercept them here.
+ orig_exit_labels = (code.continue_label, code.break_label)
code.continue_label = code.new_label('outer_continue')
+ code.break_label = code.new_label('outer_break')
code.putln("/*else*/ {")
self.else_clause.generate_execution_code(code)
code.putln("}")
- if code.label_used(code.continue_label):
- code.put_goto(break_label)
+ needs_goto_end = not self.else_clause.is_terminator
+ for exit_label, orig_exit_label in zip([code.continue_label, code.break_label], orig_exit_labels):
+ if not code.label_used(exit_label):
+ continue
+ if needs_goto_end:
+ code.put_goto(break_label)
+ needs_goto_end = False
code.mark_pos(self.pos)
- code.put_label(code.continue_label)
+ code.put_label(exit_label)
self.iterator.generate_disposal_code(code)
- code.put_goto(orig_continue_label)
+ code.put_goto(orig_exit_label)
code.set_loop_labels(old_loop_labels)
code.mark_pos(self.pos)