Fix casts and negations in except clauses.
authorRobert Bradshaw <robertwb@math.washington.edu>
Thu, 22 Oct 2009 09:17:13 +0000 (02:17 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Thu, 22 Oct 2009 09:17:13 +0000 (02:17 -0700)
Cython/Compiler/ExprNodes.py
Cython/Compiler/Nodes.py
Cython/Compiler/PyrexTypes.py
tests/run/exceptionpropagation.pyx

index 9871eda3731bd1f5034105d3f25718fec8ad73ac..284ba7c9a94219a86a5858bb520e188c9325edd7 100644 (file)
@@ -4106,6 +4106,11 @@ class UnaryMinusNode(UnopNode):
         else:
             return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
 
+    def get_constant_c_result_code(self):
+        value = self.operand.get_constant_c_result_code()
+        if value:
+            return "(-%s)" % (value)
+
 class TildeNode(UnopNode):
     #  unary '~' operator
 
@@ -4251,6 +4256,11 @@ class TypecastNode(ExprNode):
         opnd = self.operand
         return self.type.cast_code(opnd.result())
     
+    def get_constant_c_result_code(self):
+        operand_result = self.operand.get_constant_c_result_code()
+        if operand_result:
+            return self.type.cast_code(operand_result)
+    
     def result_as(self, type):
         if self.type.is_pyobject and not self.is_temp:
             #  Optimise away some unnecessary casting
index 97ea74613cbc07be7bf0838df85952810ca2f7cd..9144f2282c44940739fb5716a1add2af2b518951 100644 (file)
@@ -546,7 +546,6 @@ class CFuncDeclaratorNode(CDeclaratorNode):
         else:
             if self.exception_value:
                 self.exception_value.analyse_const_expression(env)
-                exc_val = self.exception_value.get_constant_c_result_code()
                 if self.exception_check == '+':
                     exc_val_type = self.exception_value.type
                     if not exc_val_type.is_error and \
@@ -555,6 +554,7 @@ class CFuncDeclaratorNode(CDeclaratorNode):
                         error(self.exception_value.pos,
                             "Exception value must be a Python exception or cdef function with no arguments.")
                 else:
+                    exc_val = self.exception_value.get_constant_c_result_code()
                     if not return_type.assignable_from(self.exception_value.type):
                         error(self.exception_value.pos,
                               "Exception value incompatible with function return type")
index 4a0dc00bff64c1bf54cde6ad572755cab9ba084d..574096e11ded8ad046bb9cc92d28cbadf1e28cb2 100644 (file)
@@ -1282,10 +1282,17 @@ class CFuncType(CType):
         arg_reprs = map(repr, self.args)
         if self.has_varargs:
             arg_reprs.append("...")
-        return "<CFuncType %s %s[%s]>" % (
+        if self.exception_value:
+            except_clause = " %r" % self.exception_value
+        else:
+            except_clause = ""
+        if self.exception_check:
+            except_clause += "?"
+        return "<CFuncType %s %s[%s]%s>" % (
             repr(self.return_type),
             self.calling_convention_prefix(),
-            ",".join(arg_reprs))
+            ",".join(arg_reprs),
+            except_clause)
     
     def calling_convention_prefix(self):
         cc = self.calling_convention
index e324a70a40269f65a3ed23fd664526442a99a2f5..eb157b86af948ca1731c333d43f2ed230ff74ac2 100644 (file)
@@ -15,3 +15,17 @@ cdef int obj2int(object ob) except *:
 def foo(a):
     cdef int i = obj2int(a)
     CHKERR(i)
+
+cdef int* except_expr(bint fire) except <int*>-1:
+    if fire:
+        raise RuntimeError
+
+def test_except_expr(bint fire):
+    """
+    >>> test_except_expr(False)
+    >>> test_except_expr(True)
+    Traceback (most recent call last):
+    ...
+    RuntimeError
+    """
+    except_expr(fire)