Commit 3d6033c0 authored by Stefan Behnel's avatar Stefan Behnel

rewrite literal DEF integer coercion to constants:

- append U-suffix only on coercion when the target type is unsigned
- append L/LL-suffix when value looks too large for a smaller constant value type
parent 6af38f93
...@@ -1133,9 +1133,15 @@ class IntNode(ConstNode): ...@@ -1133,9 +1133,15 @@ class IntNode(ConstNode):
return FloatNode(self.pos, value=self.value, type=dst_type, return FloatNode(self.pos, value=self.value, type=dst_type,
constant_result=not_a_constant) constant_result=not_a_constant)
if dst_type.is_numeric and not dst_type.is_complex: if dst_type.is_numeric and not dst_type.is_complex:
unsigned = self.unsigned
if not unsigned and dst_type.is_int and not dst_type.signed:
# mark positive literals as 'U' when coercing them to unsigned integer types
# to extend their potential value range in the C code
if self.has_constant_result() and self.constant_result > 0:
unsigned = 'U'
node = IntNode(self.pos, value=self.value, constant_result=self.constant_result, node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
type = dst_type, is_c_literal = True, type=dst_type, is_c_literal=True,
unsigned=self.unsigned, longness=self.longness) unsigned=unsigned, longness=self.longness)
return node return node
elif dst_type.is_pyobject: elif dst_type.is_pyobject:
node = IntNode(self.pos, value=self.value, constant_result=self.constant_result, node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
......
...@@ -762,7 +762,7 @@ def wrap_compile_time_constant(pos, value): ...@@ -762,7 +762,7 @@ def wrap_compile_time_constant(pos, value):
return ExprNodes.BoolNode(pos, value=value) return ExprNodes.BoolNode(pos, value=value)
elif isinstance(value, int): elif isinstance(value, int):
return ExprNodes.IntNode( return ExprNodes.IntNode(
pos, value=rep, constant_result=value, unsigned='U' if value > 0 else '') pos, value=rep, constant_result=value, longness=Utils.longness_of(value))
elif isinstance(value, float): elif isinstance(value, float):
return ExprNodes.FloatNode(pos, value=rep, constant_result=value) return ExprNodes.FloatNode(pos, value=rep, constant_result=value)
elif isinstance(value, _unicode): elif isinstance(value, _unicode):
...@@ -780,8 +780,7 @@ def wrap_compile_time_constant(pos, value): ...@@ -780,8 +780,7 @@ def wrap_compile_time_constant(pos, value):
return None return None
elif not _IS_PY3 and isinstance(value, long): elif not _IS_PY3 and isinstance(value, long):
return ExprNodes.IntNode( return ExprNodes.IntNode(
pos, value=rep.rstrip('L'), longness="L", constant_result=value, pos, value=rep.rstrip('L'), longness=Utils.longness_of(value), constant_result=value)
unsigned='U' if value > 0 else '')
error(pos, "Invalid type for compile-time constant: %r (type %s)" error(pos, "Invalid type for compile-time constant: %r (type %s)"
% (value, value.__class__.__name__)) % (value, value.__class__.__name__))
return None return None
......
...@@ -319,6 +319,16 @@ def long_literal(value): ...@@ -319,6 +319,16 @@ def long_literal(value):
return not -2**31 <= value < 2**31 return not -2**31 <= value < 2**31
def longness_of(value):
if isinstance(value, basestring):
value = str_to_number(value)
if -2**15 <= value < 2**15:
return ''
if -2**31 <= value < 2**31:
return 'L'
return 'LL'
@cached_function @cached_function
def get_cython_cache_dir(): def get_cython_cache_dir():
"""get the cython cache dir """get the cython cache dir
......
...@@ -94,15 +94,18 @@ def l(): ...@@ -94,15 +94,18 @@ def l():
def large_nums(): def large_nums():
""" """
>>> l32, l64 = large_nums() >>> ul32, ul64, l64 = large_nums()
>>> print_large_number(l32) >>> print_large_number(ul32)
4294967295 4294967295
>>> print_large_number(l64) >>> print_large_number(ul64)
18446744073709551615 18446744073709551615
>>> print_large_number(l64)
4294967295
""" """
cdef unsigned long l32 = LARGE_NUM32 cdef unsigned long ul32 = LARGE_NUM32
cdef unsigned long long l64 = LARGE_NUM64 cdef unsigned long long ul64 = LARGE_NUM64
return l32, l64 cdef long long l64 = LARGE_NUM32
return ul32, ul64, l64
def f(): def f():
""" """
......
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