Commit f72eb896 authored by Stefan Behnel's avatar Stefan Behnel

add visible warning when negative indices are used in wraparound=False sections

parent 2599587c
...@@ -91,6 +91,7 @@ def find_coercion_error(type_tuple, default, env): ...@@ -91,6 +91,7 @@ def find_coercion_error(type_tuple, default, env):
else: else:
return err return err
def default_str_type(env): def default_str_type(env):
return { return {
'bytes': bytes_type, 'bytes': bytes_type,
...@@ -99,6 +100,22 @@ def default_str_type(env): ...@@ -99,6 +100,22 @@ def default_str_type(env):
}.get(env.directives['c_string_type']) }.get(env.directives['c_string_type'])
def check_negative_indices(*nodes):
"""
Raise a warning on nodes that are known to have negative numeric values.
Used to find (potential) bugs inside of "wraparound=False" sections.
"""
for node in nodes:
if not isinstance(node.constant_result, (int, float, long)):
continue
if node.constant_result >= 0:
continue
warning(node.pos,
"the result of using negative indices inside of "
"code sections marked as 'wraparound=False' is "
"undefined", level=1)
class ExprNode(Node): class ExprNode(Node):
# subexprs [string] Class var holding names of subexpr node attrs # subexprs [string] Class var holding names of subexpr node attrs
# type PyrexType Type of the result # type PyrexType Type of the result
...@@ -2762,6 +2779,12 @@ class IndexNode(ExprNode): ...@@ -2762,6 +2779,12 @@ class IndexNode(ExprNode):
is_slice = isinstance(self.index, SliceNode) is_slice = isinstance(self.index, SliceNode)
if not env.directives['wraparound']:
if is_slice:
check_negative_indices(self.index.start, self.index.stop)
else:
check_negative_indices(self.index)
# Potentially overflowing index value. # Potentially overflowing index value.
if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value): if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
self.index = self.index.coerce_to_pyobject(env) self.index = self.index.coerce_to_pyobject(env)
...@@ -3550,6 +3573,10 @@ class SliceIndexNode(ExprNode): ...@@ -3550,6 +3573,10 @@ class SliceIndexNode(ExprNode):
self.start = self.start.analyse_types(env) self.start = self.start.analyse_types(env)
if self.stop: if self.stop:
self.stop = self.stop.analyse_types(env) self.stop = self.stop.analyse_types(env)
if not env.directives['wraparound']:
check_negative_indices(self.start, self.stop)
base_type = self.base.type base_type = self.base.type
if base_type.is_string or base_type.is_cpp_string: if base_type.is_string or base_type.is_cpp_string:
self.type = default_str_type(env) self.type = default_str_type(env)
......
# mode: error
# tag: werror
cimport cython
s = "abc"
l = [1, 2, 3]
def normal_wraparound(int i, bytes B not None, list L not None):
a = s[1:2]
a = s[-2:-1]
a = "abc"[-2:-1]
a = "abc"[-2:i]
a = B[-2:-1]
b = l[1:2]
b = l[-2:-1]
b = [1, 2, 3][-2:-1]
b = [1, 2, 3][-2:i]
b = L[-2:-1]
@cython.wraparound(False)
def no_wraparound(int i, bytes B not None, list L not None):
a = s[1:2]
a = s[-2:-1]
a = "abc"[-2:-1]
a = "abc"[-2:i]
a = B[-2:-1]
b = l[1:2]
b = l[-2:-1]
b = [1, 2, 3][-2:i]
b = L[-2:-1]
_ERRORS = """
25:11: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined
25:14: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined
27:15: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined
28:11: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined
28:14: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined
31:11: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined
31:14: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined
32:19: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined
33:11: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined
33:14: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined
"""
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