Commit 4a6234d2 authored by Robert Bradshaw's avatar Robert Bradshaw

Fix casts and negations in except clauses.

parent 9cece7db
...@@ -4106,6 +4106,11 @@ class UnaryMinusNode(UnopNode): ...@@ -4106,6 +4106,11 @@ class UnaryMinusNode(UnopNode):
else: else:
return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result()) 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): class TildeNode(UnopNode):
# unary '~' operator # unary '~' operator
...@@ -4251,6 +4256,11 @@ class TypecastNode(ExprNode): ...@@ -4251,6 +4256,11 @@ class TypecastNode(ExprNode):
opnd = self.operand opnd = self.operand
return self.type.cast_code(opnd.result()) 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): def result_as(self, type):
if self.type.is_pyobject and not self.is_temp: if self.type.is_pyobject and not self.is_temp:
# Optimise away some unnecessary casting # Optimise away some unnecessary casting
......
...@@ -546,7 +546,6 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -546,7 +546,6 @@ class CFuncDeclaratorNode(CDeclaratorNode):
else: else:
if self.exception_value: if self.exception_value:
self.exception_value.analyse_const_expression(env) self.exception_value.analyse_const_expression(env)
exc_val = self.exception_value.get_constant_c_result_code()
if self.exception_check == '+': if self.exception_check == '+':
exc_val_type = self.exception_value.type exc_val_type = self.exception_value.type
if not exc_val_type.is_error and \ if not exc_val_type.is_error and \
...@@ -555,6 +554,7 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -555,6 +554,7 @@ class CFuncDeclaratorNode(CDeclaratorNode):
error(self.exception_value.pos, error(self.exception_value.pos,
"Exception value must be a Python exception or cdef function with no arguments.") "Exception value must be a Python exception or cdef function with no arguments.")
else: else:
exc_val = self.exception_value.get_constant_c_result_code()
if not return_type.assignable_from(self.exception_value.type): if not return_type.assignable_from(self.exception_value.type):
error(self.exception_value.pos, error(self.exception_value.pos,
"Exception value incompatible with function return type") "Exception value incompatible with function return type")
......
...@@ -1282,10 +1282,17 @@ class CFuncType(CType): ...@@ -1282,10 +1282,17 @@ class CFuncType(CType):
arg_reprs = map(repr, self.args) arg_reprs = map(repr, self.args)
if self.has_varargs: if self.has_varargs:
arg_reprs.append("...") 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), repr(self.return_type),
self.calling_convention_prefix(), self.calling_convention_prefix(),
",".join(arg_reprs)) ",".join(arg_reprs),
except_clause)
def calling_convention_prefix(self): def calling_convention_prefix(self):
cc = self.calling_convention cc = self.calling_convention
......
...@@ -15,3 +15,17 @@ cdef int obj2int(object ob) except *: ...@@ -15,3 +15,17 @@ cdef int obj2int(object ob) except *:
def foo(a): def foo(a):
cdef int i = obj2int(a) cdef int i = obj2int(a)
CHKERR(i) 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)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment