diff options
Diffstat (limited to 'Cython/Compiler/Nodes.py')
-rw-r--r-- | Cython/Compiler/Nodes.py | 23 |
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) |