Commit 1657608e authored by Robert Bradshaw's avatar Robert Bradshaw

Implement overflow check for abs(int).

parent f05f6164
......@@ -5510,6 +5510,8 @@ class SimpleCallNode(CallNode):
if func_type.exception_value is None:
env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
self.overflowcheck = env.directives['overflowcheck']
def calculate_result_code(self):
return self.c_call_code()
......@@ -5620,7 +5622,12 @@ class SimpleCallNode(CallNode):
translate_cpp_exception(code, self.pos, '%s%s;' % (lhs, rhs),
func_type.exception_value, self.nogil)
else:
if exc_checks:
if (self.overflowcheck
and self.type.is_int
and self.type.signed
and self.function.result() in ('abs', 'labs', '__Pyx_abs_longlong')):
goto_error = 'if (%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)
else:
goto_error = ""
......
......@@ -41,6 +41,7 @@ def sub_abs(int a):
"""
return -abs(a), 100 - abs(a)
@cython.overflowcheck(True)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = 'abs']")
def int_abs(int a):
......@@ -49,12 +50,10 @@ def int_abs(int a):
True
>>> int_abs(-5.1) == 5
True
"""
# >>> int_abs(-max_int-1) > 0
# True
# >>> int_abs(-max_int-1) == abs(-max_int-1) or (max_int, int_abs(-max_int-1), abs(-max_int-1))
# True
"""
>>> int_abs(-max_int-1) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
OverflowError: ...
>>> int_abs(max_int) == abs(max_int) or (max_int, int_abs(max_int), abs(max_int))
True
"""
......@@ -70,6 +69,7 @@ def uint_abs(unsigned int a):
"""
return abs(a)
@cython.overflowcheck(True)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = 'labs']")
def long_abs(long a):
......@@ -78,12 +78,10 @@ def long_abs(long a):
True
>>> long_abs(-5.1) == 5
True
"""
# >>> long_abs(-max_long-1) > 0
# True
# >>> long_abs(-max_long-1) == abs(-max_long-1) or (max_long, long_abs(-max_long-1), abs(-max_long-1))
# True
"""
>>> long_abs(-max_long-1) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
OverflowError: ...
>>> long_abs(max_long) == abs(max_long) or (max_long, long_abs(max_long), abs(max_long))
True
"""
......@@ -101,18 +99,17 @@ def ulong_abs(unsigned long a):
"""
return abs(a)
@cython.overflowcheck(True)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_longlong']")
def long_long_abs(long long a):
"""
>>> long_long_abs(-(2**33)) == 2**33
True
"""
# >>> long_long_abs(-max_long_long-1) > 0
# True
# >>> long_long_abs(-max_long_long-1) == abs(-max_long_long-1) or (max_long_long, long_long_abs(-max_long_long-1), abs(-max_long_long-1))
# True
"""
>>> long_long_abs(-max_long_long-1) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
OverflowError: ...
>>> long_long_abs(max_long_long) == abs(max_long_long) or (max_long_long, long_long_abs(max_long_long), abs(max_long_long))
True
"""
......
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