From fc2639822c74abc6a9ed15c3125ed8bc85f1a699 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Fri, 20 Mar 2009 17:36:35 +0100 Subject: [PATCH] patch for ticket 203 by Prajwal Suhas P --- Cython/Compiler/Nodes.py | 24 +++++++---- tests/bugs/rangeOptimization_T203.pyx | 60 +++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 tests/bugs/rangeOptimization_T203.pyx diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index f69cd3a2..757055f7 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -3967,17 +3967,26 @@ class ForFromStatNode(LoopNode, StatNode): decop = "%s=%s" % (decop[0], step) loopvar_name = self.loopvar_node.result() if from_range: + temp_range_bound = code.funcstate.allocate_temp(self.bound2.type, manage_ref=False) + code.putln("%s = %s;" % (temp_range_bound, self.bound2.result())) # Skip the loop entirely (and avoid assigning to the loopvar) if # the loop is empty: code.putln("if (%s%s %s %s) {" % ( - self.bound1.result(), offset, self.relation2, self.bound2.result() + self.bound1.result(), offset, self.relation2, temp_range_bound )) - code.putln( - "for (%s = %s%s; %s %s %s; %s%s) {" % ( - loopvar_name, - self.bound1.result(), offset, - loopvar_name, self.relation2, self.bound2.result(), - loopvar_name, incop)) + code.putln( + "for (%s = %s%s; %s %s %s; %s%s) {" % ( + loopvar_name, + self.bound1.result(), offset, + loopvar_name, self.relation2, temp_range_bound, + loopvar_name, incop)) + else: + code.putln( + "for (%s = %s%s; %s %s %s; %s%s) {" % ( + loopvar_name, + self.bound1.result(), offset, + loopvar_name, self.relation2, self.bound2.result(), + loopvar_name, incop)) if self.py_loopvar_node: self.py_loopvar_node.generate_evaluation_code(code) self.target.generate_assignment_code(self.py_loopvar_node, code) @@ -3988,6 +3997,7 @@ class ForFromStatNode(LoopNode, StatNode): code.putln("} %s%s;" % (loopvar_name, decop)) # End the outer if statement: code.putln("} /* end if */") + code.funcstate.release_temp(temp_range_bound) else: code.putln("}") break_label = code.break_label diff --git a/tests/bugs/rangeOptimization_T203.pyx b/tests/bugs/rangeOptimization_T203.pyx new file mode 100644 index 00000000..3388c2d0 --- /dev/null +++ b/tests/bugs/rangeOptimization_T203.pyx @@ -0,0 +1,60 @@ +__doc__ = u""" +>>> test_var(10, 5) +at 0 +at 1 +at 2 +at 3 +at 4 +5 +>>> test_func(5) +get_bound(5) +at 0 +at 1 +at 2 +at 3 +at 4 +5 +>>> test_f() +9 +>>> f() +g called +0 +1 +2 +2 +""" + +cdef int get_bound(int m): + print "get_bound(%s)"%m + return m + +def test_var(int n, int m): + cdef int i + for i from 0 <= i < n: + print "at", i + n = m + return i + +def test_func(int n): + cdef int i + for i from 0 <= i < get_bound(n): + print "at", i + return i + +def test_f(): + cdef int i,n + n = 10 + for i in range(n): + if i == 5: n *= 2 + print i + +cdef int g(): + print "g called" + return 3 + +def f(): + cdef int i + for i in range(g()): + print i + print i + -- 2.26.2