Commit 10e71628 authored by Robert Bradshaw's avatar Robert Bradshaw

Overflow initialization checking

also adds error checking for init utility code blocks
parent e8bb8ff0
......@@ -68,10 +68,18 @@ class UtilityCodeBase(object):
Code sections in the file can be specified as follows:
##### MyUtility.proto #####
[proto declarations]
##### MyUtility.init #####
[code run at module initialization]
##### MyUtility #####
#@requires: MyOtherUtility
#@substitute: naming
[definitions]
for prototypes and implementation respectively. For non-python or
-cython files backslashes should be used instead. 5 to 30 comment
......@@ -374,10 +382,13 @@ class UtilityCode(UtilityCodeBase):
output['utility_code_def'].put(self.format_code(self.impl))
if self.init:
writer = output['init_globals']
writer.putln("/* %s.init */" % self.name)
if isinstance(self.init, basestring):
writer.put(self.format_code(self.init))
else:
self.init(writer, output.module_pos)
writer.putln(writer.error_goto_if_PyErr(output.module_pos))
writer.putln()
if self.cleanup and Options.generate_cleanup_code:
writer = output['cleanup_globals']
if isinstance(self.cleanup, basestring):
......@@ -400,13 +411,14 @@ def sub_tempita(s, context, file=None, name=None):
return sub(s, **context)
class TempitaUtilityCode(UtilityCode):
def __init__(self, name=None, proto=None, impl=None, file=None, context=None, **kwargs):
def __init__(self, name=None, proto=None, impl=None, init=None, file=None, context=None, **kwargs):
if context is None:
context = {}
proto = sub_tempita(proto, context, file, name)
impl = sub_tempita(impl, context, file, name)
init = sub_tempita(init, context, file, name)
super(TempitaUtilityCode, self).__init__(
proto, impl, name=name, file=file, **kwargs)
proto, impl, init=init, name=name, file=file, **kwargs)
def none_or_sub(self, s, context):
"""
......
......@@ -402,6 +402,15 @@ class CTypedefType(BaseType):
# delegation
return self.typedef_base_type.create_from_py_utility_code(env)
def overflow_check_binop(self, binop, env):
env.use_utility_code(UtilityCode.load("Common", "Overflow.c"))
type = self.declaration_code("")
name = self.specialization_name()
_load_overflow_base(env)
env.use_utility_code(TempitaUtilityCode.load("SizeCheck", "Overflow.c", context={'TYPE': type, 'NAME': name}))
env.use_utility_code(TempitaUtilityCode.load("Binop", "Overflow.c", context={'TYPE': type, 'NAME': name, 'BINOP': binop}))
return "__Pyx_%s_%s_checking_overflow" % (binop, name)
def error_condition(self, result_code):
if self.typedef_is_external:
if self.exception_value:
......@@ -1546,7 +1555,7 @@ class CIntType(CNumericType):
# We do not really know the size of the type, so return
# a 32-bit literal and rely on casting to final type. It will
# be negative for signed ints, which is good.
return "0xbad0bad0";
return "0xbad0bad0"
def overflow_check_binop(self, binop, env):
env.use_utility_code(UtilityCode.load("Common", "Overflow.c"))
......@@ -1561,6 +1570,7 @@ class CIntType(CNumericType):
return "__Pyx_%s_%s_no_overflow" % (binop, name)
else:
_load_overflow_base(env)
env.use_utility_code(TempitaUtilityCode.load("SizeCheck", "Overflow.c", context={'TYPE': type, 'NAME': name}))
env.use_utility_code(TempitaUtilityCode.load("Binop", "Overflow.c", context={'TYPE': type, 'NAME': name, 'BINOP': binop}))
return "__Pyx_%s_%s_checking_overflow" % (binop, name)
......
......@@ -46,7 +46,9 @@ static int __Pyx_check_twos_complement() {
#define __Pyx_div_no_overflow(a, b, overflow) ((a) / (b))
#define __Pyx_div_const_no_overflow(a, b, overflow) ((a) / (b))
/////////////// Common.init ///////////////
__Pyx_check_twos_complement();
/////////////// BaseCaseUnsigned.proto ///////////////
......@@ -217,10 +219,14 @@ static CYTHON_INLINE {{INT}} __Pyx_div_{{NAME}}_checking_overflow({{INT}} a, {{I
}
/////////////// SizeCheck.init ///////////////
__Pyx_check_sane_{{NAME}}();
/////////////// SizeCheck.proto ///////////////
static int __Pyx_check_sane_{{TYPE}}() {
if (sizeof({{TYPE}}) == sizeof(int) ||
static int __Pyx_check_sane_{{NAME}}() {
if (sizeof({{TYPE}}) <= sizeof(int) ||
sizeof({{TYPE}}) == sizeof(long) ||
sizeof({{TYPE}}) == sizeof(long long)) {
return 0;
......
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