diff options
-rw-r--r-- | mesonbuild/compilers/c.py | 54 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 10 | ||||
-rw-r--r-- | test cases/common/142 compute int/config.h.in | 2 | ||||
-rw-r--r-- | test cases/common/142 compute int/meson.build | 8 | ||||
-rw-r--r-- | test cases/common/142 compute int/prog.c.in | 9 |
5 files changed, 65 insertions, 18 deletions
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 56b46b4..27cf43a 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -367,24 +367,52 @@ class CCompiler(Compiler): return self.compiles(t.format(**fargs), env, extra_args, dependencies) def cross_compute_int(self, expression, low, high, guess, prefix, env, extra_args, dependencies): + # Try user's guess first if isinstance(guess, int): if self._compile_int('%s == %d' % (expression, guess), prefix, env, extra_args, dependencies): return guess - cur = low - while low < high: - cur = int((low + high) / 2) - if cur == low: - break - - if self._compile_int('%s >= %d' % (expression, cur), prefix, env, extra_args, dependencies): - low = cur + # If no bounds are given, compute them in the limit of int32 + maxint = 0x7fffffff + minint = -0x80000000 + if not isinstance(low, int) or not isinstance(high, int): + if self._compile_int('%s >= 0' % (expression), prefix, env, extra_args, dependencies): + low = cur = 0 + while self._compile_int('%s > %d' % (expression, cur), prefix, env, extra_args, dependencies): + low = cur + 1 + if low > maxint: + raise EnvironmentException('Cross-compile check overflowed') + cur = cur * 2 + 1 + if cur > maxint: + cur = maxint + high = cur else: + low = cur = -1 + while self._compile_int('%s < %d' % (expression, cur), prefix, env, extra_args, dependencies): + high = cur - 1 + if high < minint: + raise EnvironmentException('Cross-compile check overflowed') + cur = cur * 2 + if cur < minint: + cur = minint + low = cur + else: + # Sanity check limits given by user + if high < low: + raise EnvironmentException('high limit smaller than low limit') + condition = '%s <= %d && %s >= %d' % (expression, high, expression, low) + if not self._compile_int(condition, prefix, env, extra_args, dependencies): + raise EnvironmentException('Value out of given range') + + # Binary search + while low != high: + cur = low + int((high - low) / 2) + if self._compile_int('%s <= %d' % (expression, cur), prefix, env, extra_args, dependencies): high = cur + else: + low = cur + 1 - if self._compile_int('%s == %d' % (expression, cur), prefix, env, extra_args, dependencies): - return cur - raise EnvironmentException('Cross-compile check overflowed') + return low def compute_int(self, expression, low, high, guess, prefix, env, extra_args=None, dependencies=None): if extra_args is None: @@ -416,7 +444,7 @@ class CCompiler(Compiler): }}''' if not self.compiles(t.format(**fargs), env, extra_args, dependencies): return -1 - return self.cross_compute_int('sizeof(%s)' % typename, 1, 1024, None, prefix, env, extra_args, dependencies) + return self.cross_compute_int('sizeof(%s)' % typename, None, None, None, prefix, env, extra_args, dependencies) def sizeof(self, typename, prefix, env, extra_args=None, dependencies=None): if extra_args is None: @@ -454,7 +482,7 @@ class CCompiler(Compiler): char c; {type} target; }};''' - return self.cross_compute_int('offsetof(struct tmp, target)', 1, 1024, None, t.format(**fargs), env, extra_args, dependencies) + return self.cross_compute_int('offsetof(struct tmp, target)', None, None, None, t.format(**fargs), env, extra_args, dependencies) def alignment(self, typename, prefix, env, extra_args=None, dependencies=None): if extra_args is None: diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index b04d586..6e3b864 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -984,20 +984,20 @@ class CompilerHolder(InterpreterObject): check_stringlist(args) expression = args[0] prefix = kwargs.get('prefix', '') - l = kwargs.get('low', -1024) - h = kwargs.get('high', 1024) + low = kwargs.get('low', None) + high = kwargs.get('high', None) guess = kwargs.get('guess', None) if not isinstance(prefix, str): raise InterpreterException('Prefix argument of compute_int must be a string.') - if not isinstance(l, int): + if low is not None and not isinstance(low, int): raise InterpreterException('Low argument of compute_int must be an int.') - if not isinstance(h, int): + if high is not None and not isinstance(high, int): raise InterpreterException('High argument of compute_int must be an int.') if guess is not None and not isinstance(guess, int): raise InterpreterException('Guess argument of compute_int must be an int.') extra_args = self.determine_args(kwargs) deps = self.determine_dependencies(kwargs) - res = self.compiler.compute_int(expression, l, h, guess, prefix, self.environment, extra_args, deps) + res = self.compiler.compute_int(expression, low, high, guess, prefix, self.environment, extra_args, deps) mlog.log('Computing int of "%s": %d' % (expression, res)) return res diff --git a/test cases/common/142 compute int/config.h.in b/test cases/common/142 compute int/config.h.in index ad8d077..0de63ab 100644 --- a/test cases/common/142 compute int/config.h.in +++ b/test cases/common/142 compute int/config.h.in @@ -1,2 +1,4 @@ #define INTSIZE @INTSIZE@ #define FOOBAR_IN_CONFIG_H @FOOBAR@ +#define MAXINT @MAXINT@ +#define MININT @MININT@ diff --git a/test cases/common/142 compute int/meson.build b/test cases/common/142 compute int/meson.build index 43553fe..22bd266 100644 --- a/test cases/common/142 compute int/meson.build +++ b/test cases/common/142 compute int/meson.build @@ -7,11 +7,15 @@ cc = meson.get_compiler('c') intsize = cc.compute_int('sizeof(int)', low : 1, high : 16, guess : 4) foobar = cc.compute_int('FOOBAR_IN_FOOBAR_H', prefix : '#include "foobar.h"', include_directories : inc) +maxint = cc.compute_int('INT_MAX', prefix: '#include <limits.h>') +minint = cc.compute_int('INT_MIN', prefix: '#include <limits.h>') cd = configuration_data() cd.set('INTSIZE', intsize) cd.set('FOOBAR', foobar) cd.set('CONFIG', 'config.h') +cd.set('MAXINT', maxint) +cd.set('MININT', minint) configure_file(input : 'config.h.in', output : 'config.h', configuration : cd) s = configure_file(input : 'prog.c.in', output : 'prog.c', configuration : cd) @@ -23,11 +27,15 @@ cpp = meson.get_compiler('cpp') intsize = cpp.compute_int('sizeof(int)') foobar = cpp.compute_int('FOOBAR_IN_FOOBAR_H', prefix : '#include "foobar.h"', include_directories : inc) +maxint = cpp.compute_int('INT_MAX', prefix: '#include <limits.h>') +minint = cpp.compute_int('INT_MIN', prefix: '#include <limits.h>') cdpp = configuration_data() cdpp.set('INTSIZE', intsize) cdpp.set('FOOBAR', foobar) cdpp.set('CONFIG', 'config.hpp') +cdpp.set('MAXINT', maxint) +cdpp.set('MININT', minint) configure_file(input : 'config.h.in', output : 'config.hpp', configuration : cdpp) spp = configure_file(input : 'prog.c.in', output : 'prog.cc', configuration : cdpp) diff --git a/test cases/common/142 compute int/prog.c.in b/test cases/common/142 compute int/prog.c.in index 3ff1463..ff1ad55 100644 --- a/test cases/common/142 compute int/prog.c.in +++ b/test cases/common/142 compute int/prog.c.in @@ -1,6 +1,7 @@ #include "@CONFIG@" #include <stdio.h> #include <wchar.h> +#include <limits.h> #include "foobar.h" int main(int argc, char **argv) { @@ -12,5 +13,13 @@ int main(int argc, char **argv) { fprintf(stderr, "Mismatch: computed int %d, should be %d.\n", FOOBAR_IN_CONFIG_H, FOOBAR_IN_FOOBAR_H); return 1; } + if(MAXINT != INT_MAX) { + fprintf(stderr, "Mismatch: computed max int %d, should be %d.\n", MAXINT, INT_MAX); + return 1; + } + if(MININT != INT_MIN) { + fprintf(stderr, "Mismatch: computed min int %d, should be %d.\n", MININT, INT_MIN); + return 1; + } return 0; } |