Repository: mesonbuild/meson

Issue:
cc.has_function fails to detect GCC/Clang __builtin functions
**Describe the bug**
Calls such as `cc.has_function('__builtin_clz')` return false when the function exists as a builtin compiler intrinsic (gcc and clang).

[meson-log.txt for GCC](https://github.com/mesonbuild/meson/files/4418182/meson-log.txt)
[meson-log.txt for Clang](https://github.com/mesonbuild/meson/files/4418184/meson-log.txt)


**To Reproduce**
```meson
project('builtinfail', 'c')
cc = meson.get_compiler('c')
assert(cc.has_function('__builtin_clz'), '__builtin_clz not found')
```

**Expected behavior**
`cc.has_function` should correctly detect support for compiler builtins.

**system parameters**
* openSUSE Tumbleweed
* Python 3.8.2
* meson 0.54.999 (b9b118b267219e6ac8d6f0d5e5c73152e88b8269)
* ninja 1.10.0





Discussion:

Resolving patch:
diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py
--- a/mesonbuild/compilers/mixins/clike.py
+++ b/mesonbuild/compilers/mixins/clike.py
@@ -727,22 +727,23 @@ def has_function(self, funcname, prefix, env, *, extra_args=None, dependencies=N
         # 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
+        fargs['__builtin_'] = '' if funcname.startswith('__builtin_') else '__builtin_'
         t = '''{prefix}
         int main(void) {{
         #ifdef __has_builtin
-            #if !__has_builtin(__builtin_{func})
-                #error "__builtin_{func} not found"
+            #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
+            /* 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};
+                {__builtin_}{func};
             #else
-                #error "No definition for __builtin_{func} found in the prefix"
+                #error "No definition for {__builtin_}{func} found in the prefix"
             #endif
         #endif
         return 0;


Test patch:
diff --git a/test cases/common/39 has function/meson.build b/test cases/common/39 has function/meson.build
--- a/test cases/common/39 has function/meson.build	
+++ b/test cases/common/39 has function/meson.build	
@@ -88,4 +88,12 @@ foreach cc : compilers
     assert (cc.has_function('sendmmsg', args : unit_test_args),
             'Failed to detect function "sendmmsg" (should always exist).')
   endif
+
+  # We should be able to find GCC and Clang __builtin functions
+  if ['gcc', 'clang'].contains(cc.get_id())
+    # __builtin_constant_p is documented to exist at least as far back as
+    # GCC 2.95.3
+    assert(cc.has_function('__builtin_constant_p', args : unit_test_args),
+           '__builtin_constant_p must be found under gcc and clang')
+  endif
 endforeach