fix ticket #654: fix function argument evaluation order when some are simple and...
authorStefan Behnel <scoder@users.berlios.de>
Wed, 26 Jan 2011 20:41:52 +0000 (21:41 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Wed, 26 Jan 2011 20:41:52 +0000 (21:41 +0100)
Cython/Compiler/ExprNodes.py

index 93eba7cc2eb07e4583e5926cfdeccfaba01e35c8..273bf53a0023371766e9e0974f8851709786d487 100755 (executable)
@@ -2951,6 +2951,7 @@ class SimpleCallNode(CallNode):
             self.has_optional_args = 1
             self.is_temp = 1
         # Coerce arguments
+        some_args_in_temps = False
         for i in range(min(max_nargs, actual_nargs)):
             formal_type = func_type.args[i].type
             arg = self.args[i].coerce_to(formal_type, env)
@@ -2959,8 +2960,22 @@ class SimpleCallNode(CallNode):
                 # make sure it cannot be collected before we return
                 # from the function, so we create an owned temp
                 # reference to it
+                some_args_in_temps = True
                 arg = arg.coerce_to_temp(env)
+            elif arg.is_temp:
+                some_args_in_temps = True
             self.args[i] = arg
+        if some_args_in_temps:
+            # if some args are temps and others are not, they may get
+            # constructed in the wrong order (temps first) => make
+            # sure they are either all temps or all not temps
+            for i in range(min(max_nargs, actual_nargs)):
+                arg = self.args[i]
+                # can't copy a Python reference into a temp in nogil
+                # env (this is safe: a construction would fail in
+                # nogil anyway)
+                if not (env.nogil and arg.type.is_pyobject):
+                    self.args[i] = arg.coerce_to_temp(env)
         for i in range(max_nargs, actual_nargs):
             arg = self.args[i]
             if arg.type.is_pyobject: