Commit d77f79c2 authored by serge-sans-paille's avatar serge-sans-paille Committed by Stefan Behnel

Fix overflow handling for abs() calls on signed integer types (GH-3634)

Fixes #1911
parent 134b5e8f
...@@ -5839,6 +5839,17 @@ class SimpleCallNode(CallNode): ...@@ -5839,6 +5839,17 @@ class SimpleCallNode(CallNode):
if function.is_name or function.is_attribute: if function.is_name or function.is_attribute:
code.globalstate.use_entry_utility_code(function.entry) code.globalstate.use_entry_utility_code(function.entry)
abs_function_cnames = ('abs', 'labs', '__Pyx_abs_longlong')
is_signed_int = self.type.is_int and self.type.signed
if self.overflowcheck and is_signed_int and function.result() in abs_function_cnames:
code.globalstate.use_utility_code(UtilityCode.load_cached("Common", "Overflow.c"))
code.putln('if (unlikely(%s == __PYX_MIN(%s))) {\
PyErr_SetString(PyExc_OverflowError,\
"Trying to take the absolute value of the most negative integer is not defined."); %s; }' % (
self.args[0].result(),
self.args[0].type.empty_declaration_code(),
code.error_goto(self.pos)))
if not function.type.is_pyobject or len(self.arg_tuple.args) > 1 or ( if not function.type.is_pyobject or len(self.arg_tuple.args) > 1 or (
self.arg_tuple.args and self.arg_tuple.is_literal): self.arg_tuple.args and self.arg_tuple.is_literal):
super(SimpleCallNode, self).generate_evaluation_code(code) super(SimpleCallNode, self).generate_evaluation_code(code)
...@@ -5941,13 +5952,7 @@ class SimpleCallNode(CallNode): ...@@ -5941,13 +5952,7 @@ class SimpleCallNode(CallNode):
self.result() if self.type.is_pyobject else None, self.result() if self.type.is_pyobject else None,
func_type.exception_value, self.nogil) func_type.exception_value, self.nogil)
else: else:
if (self.overflowcheck if exc_checks:
and self.type.is_int
and self.type.signed
and self.function.result() in ('abs', 'labs', '__Pyx_abs_longlong')):
goto_error = 'if (unlikely(%s < 0)) { PyErr_SetString(PyExc_OverflowError, "value too large"); %s; }' % (
self.result(), code.error_goto(self.pos))
elif exc_checks:
goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos) goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
else: else:
goto_error = "" goto_error = ""
......
# mode: run # mode: run
# ticket: 698 # ticket: 698
# distutils: extra_compile_args=-fwrapv
cdef extern from *: cdef extern from *:
int INT_MAX int INT_MAX
......
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