else:
return err
+
def default_str_type(env):
return {
'bytes': bytes_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):
# subexprs [string] Class var holding names of subexpr node attrs
# type PyrexType Type of the result
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.
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.start = self.start.analyse_types(env)
if self.stop:
self.stop = self.stop.analyse_types(env)
+
+ if not env.directives['wraparound']:
+ check_negative_indices(self.start, self.stop)
+
base_type = self.base.type
if base_type.is_string or base_type.is_cpp_string:
self.type = default_str_type(env)
--- /dev/null
+# 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
+"""