@@ -8919,9 +8919,10 @@ class PrimaryCmpNode(ExprNode, CmpNode):
89198919 # Instead, we override all the framework methods
89208920 # which use it.
89218921
8922- child_attrs = ['operand1' , 'operand2' , 'cascade' ]
8922+ child_attrs = ['operand1' , 'operand2' , 'coerced_operand2' , ' cascade' ]
89238923
89248924 cascade = None
8925+ coerced_operand2 = None
89258926 is_memslice_nonecheck = False
89268927
89278928 def infer_type (self , env ):
@@ -8999,9 +9000,11 @@ def analyse_types(self, env):
89999000 self .coerce_operands_to (common_type , env )
90009001
90019002 if self .cascade :
9002- self .operand2 = self .cascade .optimise_comparison (
9003- self .operand2 .coerce_to_simple (env ), env )
9003+ self .operand2 = self .operand2 .coerce_to_simple (env )
90049004 self .cascade .coerce_cascaded_operands_to_temp (env )
9005+ operand2 = self .cascade .optimise_comparison (self .operand2 , env )
9006+ if operand2 is not self .operand2 :
9007+ self .coerced_operand2 = operand2
90059008 if self .is_python_result ():
90069009 self .type = PyrexTypes .py_object_type
90079010 else :
@@ -9105,8 +9108,9 @@ def generate_evaluation_code(self, code):
91059108 self .generate_operation_code (code , self .result (),
91069109 self .operand1 , self .operator , self .operand2 )
91079110 if self .cascade :
9108- self .cascade .generate_evaluation_code (code ,
9109- self .result (), self .operand2 )
9111+ self .cascade .generate_evaluation_code (
9112+ code , self .result (), self .coerced_operand2 or self .operand2 ,
9113+ needs_evaluation = self .coerced_operand2 is not None )
91109114 self .operand1 .generate_disposal_code (code )
91119115 self .operand1 .free_temps (code )
91129116 self .operand2 .generate_disposal_code (code )
@@ -9141,9 +9145,10 @@ class CascadedCmpNode(Node, CmpNode):
91419145 # operand2 ExprNode
91429146 # cascade CascadedCmpNode
91439147
9144- child_attrs = ['operand2' , 'cascade' ]
9148+ child_attrs = ['operand2' , 'coerced_operand2' , ' cascade' ]
91459149
91469150 cascade = None
9151+ coerced_operand2 = None
91479152 constant_result = constant_value_not_set # FIXME: where to calculate this?
91489153
91499154 def infer_type (self , env ):
@@ -9170,7 +9175,9 @@ def optimise_comparison(self, operand1, env):
91709175 if not operand1 .type .is_pyobject :
91719176 operand1 = operand1 .coerce_to_pyobject (env )
91729177 if self .cascade :
9173- self .operand2 = self .cascade .optimise_comparison (self .operand2 , env )
9178+ operand2 = self .cascade .optimise_comparison (self .operand2 , env )
9179+ if operand2 is not self .operand2 :
9180+ self .coerced_operand2 = operand2
91749181 return operand1
91759182
91769183 def coerce_operands_to_pyobjects (self , env ):
@@ -9186,18 +9193,24 @@ def coerce_cascaded_operands_to_temp(self, env):
91869193 self .operand2 = self .operand2 .coerce_to_simple (env )
91879194 self .cascade .coerce_cascaded_operands_to_temp (env )
91889195
9189- def generate_evaluation_code (self , code , result , operand1 ):
9196+ def generate_evaluation_code (self , code , result , operand1 , needs_evaluation = False ):
91909197 if self .type .is_pyobject :
91919198 code .putln ("if (__Pyx_PyObject_IsTrue(%s)) {" % result )
91929199 code .put_decref (result , self .type )
91939200 else :
91949201 code .putln ("if (%s) {" % result )
9202+ if needs_evaluation :
9203+ operand1 .generate_evaluation_code (code )
91959204 self .operand2 .generate_evaluation_code (code )
91969205 self .generate_operation_code (code , result ,
91979206 operand1 , self .operator , self .operand2 )
91989207 if self .cascade :
91999208 self .cascade .generate_evaluation_code (
9200- code , result , self .operand2 )
9209+ code , result , self .coerced_operand2 or self .operand2 ,
9210+ needs_evaluation = self .coerced_operand2 is not None )
9211+ if needs_evaluation :
9212+ operand1 .generate_disposal_code (code )
9213+ operand1 .free_temps (code )
92019214 # Cascaded cmp result is always temp
92029215 self .operand2 .generate_disposal_code (code )
92039216 self .operand2 .free_temps (code )
0 commit comments