diff options
author | Nirbheek Chauhan <nirbheek@centricular.com> | 2017-01-26 09:27:47 +0530 |
---|---|---|
committer | Nirbheek Chauhan <nirbheek@centricular.com> | 2017-01-26 12:36:47 +0530 |
commit | 85b8e92bc447a13a19d42bc9ebe8758cd05be463 (patch) | |
tree | e03a3b98e698890a0ee2064163f3ce05b8fb1275 /mesonbuild/compilers.py | |
parent | 748fe80423b56ea52a5dbb26f84cfedd5b416b8e (diff) | |
download | meson-85b8e92bc447a13a19d42bc9ebe8758cd05be463.zip meson-85b8e92bc447a13a19d42bc9ebe8758cd05be463.tar.gz meson-85b8e92bc447a13a19d42bc9ebe8758cd05be463.tar.bz2 |
compilers: Fix has_function check for builtins
Use a single check for both cases when we have includes and when we
don't. This way we ensure three things:
1. Built-in checks are 100% reliable with clang and on macOS since clang
implements __has_builtin
2. When the #include is present, this ensures that __builtin_func is not
checked for (because of MSYS, and because it is faster)
3. We fallback to checking __builtin_func when all else fails
Diffstat (limited to 'mesonbuild/compilers.py')
-rw-r--r-- | mesonbuild/compilers.py | 49 |
1 files changed, 25 insertions, 24 deletions
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index 6e60ba1..c800bbe 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -1045,33 +1045,34 @@ class CCompiler(Compiler): if self.links(templ.format(**fargs), env, extra_args, dependencies): return True + + # Detect function as a built-in + # # Some functions like alloca() are defined as compiler built-ins which - # are inlined by the compiler, so look for __builtin_symbol in the libc - # if there's no #include-s in prefix which would've #define-d the - # symbol correctly. If there is a #include, just check for the symbol - # directly. This is needed because the above #undef fancy footwork - # doesn't work for builtins. - # This fixes instances such as #1083 where MSYS2 defines - # __builtin_posix_memalign in the C library but doesn't define - # posix_memalign in the headers to point to that builtin which results - # in an invalid detection. - if '#include' not in prefix: - # Detect function as a built-in - fargs['func'] = '__builtin_' + fargs['func'] - code = ''' - int main() {{ - #ifdef __has_builtin - #if !__has_builtin({func}) - #error "built-in {func} not found" - #endif + # are inlined by the compiler and you can't take their address, so we + # need to look for them differently. On nice compilers like clang, we + # can just directly use the __has_builtin() macro. + fargs['no_includes'] = '#include' not in prefix + t = '''{prefix} + int main() {{ + #ifdef __has_builtin + #if !__has_builtin(__builtin_{func}) + #error "__builtin_{func} not found" + #endif + #elif ! defined({func}) + /* Check for __builtin_{func} only if no includes were added to the + * prefix above, which means no definition of {func} can be found. + * We would always check for this, but we get false positives on + * MSYS2 if we do. Their toolchain is broken, but we can at least + * give them a workaround. */ + #if {no_includes:d} + __builtin_{func}; #else - {func}; + #error "No definition for __builtin_{func} found in the prefix" #endif - }}''' - else: - # Directly look for the function itself - code = '{prefix}\n' + stubs_fail + '\nint main() {{ {func}; }}' - return self.links(code.format(**fargs), env, extra_args, dependencies) + #endif + }}''' + return self.links(t.format(**fargs), env, extra_args, dependencies) def has_members(self, typename, membernames, prefix, env, extra_args=None, dependencies=None): if extra_args is None: |