From: Stefan Behnel Date: Thu, 25 Apr 2013 13:47:26 +0000 (+0200) Subject: add visible warning when negative indices are used in wraparound=False sections X-Git-Tag: 0.19.1~40 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f72eb8966ac1816279c81c01d721f0d4d795509b;p=platform%2Fupstream%2Fpython-cython.git add visible warning when negative indices are used in wraparound=False sections --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 2ef2ce6..d8f153b 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -91,6 +91,7 @@ def find_coercion_error(type_tuple, default, env): else: return err + def default_str_type(env): return { 'bytes': bytes_type, @@ -99,6 +100,22 @@ def default_str_type(env): }.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 @@ -2762,6 +2779,12 @@ class IndexNode(ExprNode): 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) @@ -3550,6 +3573,10 @@ class SliceIndexNode(ExprNode): 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) diff --git a/tests/errors/wraparound_warnings.pyx b/tests/errors/wraparound_warnings.pyx new file mode 100644 index 0000000..5d88bed --- /dev/null +++ b/tests/errors/wraparound_warnings.pyx @@ -0,0 +1,47 @@ +# 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 +"""