Commit 2ac9ffba 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 02807b3c
......@@ -1148,9 +1148,15 @@ class IntNode(ConstNode):
return FloatNode(self.pos, value=self.value, type=dst_type,
constant_result=not_a_constant)
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,
type = dst_type, is_c_literal = True,
unsigned=self.unsigned, longness=self.longness)
type=dst_type, is_c_literal=True,
unsigned=unsigned, longness=self.longness)
return node
elif dst_type.is_pyobject:
node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
......
......@@ -763,7 +763,7 @@ def wrap_compile_time_constant(pos, value):
return ExprNodes.BoolNode(pos, value=value)
elif isinstance(value, int):
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):
return ExprNodes.FloatNode(pos, value=rep, constant_result=value)
elif isinstance(value, _unicode):
......@@ -781,8 +781,7 @@ def wrap_compile_time_constant(pos, value):
return None
elif not _IS_PY3 and isinstance(value, long):
return ExprNodes.IntNode(
pos, value=rep.rstrip('L'), longness="L", constant_result=value,
unsigned='U' if value > 0 else '')
pos, value=rep.rstrip('L'), longness=Utils.longness_of(value), constant_result=value)
error(pos, "Invalid type for compile-time constant: %r (type %s)"
% (value, value.__class__.__name__))
return None
......
......@@ -319,6 +319,16 @@ def long_literal(value):
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
def get_cython_cache_dir():
"""get the cython cache dir
......
......@@ -94,15 +94,18 @@ def l():
def large_nums():
"""
>>> l32, l64 = large_nums()
>>> print_large_number(l32)
>>> ul32, ul64, l64 = large_nums()
>>> print_large_number(ul32)
4294967295
>>> print_large_number(l64)
>>> print_large_number(ul64)
18446744073709551615
>>> print_large_number(l64)
4294967295
"""
cdef unsigned long l32 = LARGE_NUM32
cdef unsigned long long l64 = LARGE_NUM64
return l32, l64
cdef unsigned long ul32 = LARGE_NUM32
cdef unsigned long long ul64 = LARGE_NUM64
cdef long long l64 = LARGE_NUM32
return ul32, ul64, l64
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