On 17.11.18 01:38, Giulio Moro via Xenomai wrote:
I have clang 3.9.1 (on Debian Stretch) on armv7.

the below minimal program clz-test.c:

```
#include <stdlib.h>
#include <arm_acle.h>

int main()
{
     return __clz(0);
}
```

will fail to build when compiled with

`clang -I/usr/xenomai/include/cobalt -I/usr/xenomai/include clz-test.c` , as 
follows:
```
In file included from test-clz.c:2:
/usr/lib/llvm-3.9/bin/../lib/clang/3.9.1/include/arm_acle.h:142:1: error: 
expected identifier or '('
__clz(uint32_t __t) {
^
/usr/xenomai/include/boilerplate/compiler.h:87:3: note: expanded from macro 
'__clz'
         ({                                                              \
          ^
In file included from test-clz.c:2:
/usr/lib/llvm-3.9/bin/../lib/clang/3.9.1/include/arm_acle.h:142:1: error: 
expected ')'
/usr/xenomai/include/boilerplate/compiler.h:87:3: note: expanded from macro 
'__clz'
         ({                                                              \
          ^
/usr/lib/llvm-3.9/bin/../lib/clang/3.9.1/include/arm_acle.h:142:1: note: to 
match this '('
/usr/xenomai/include/boilerplate/compiler.h:87:2: note: expanded from macro 
'__clz'
         ({                                                              \
         ^
2 errors generated.
```

(compiler.h is included indirectly by `stdlib.h`)

This is because clang provides a definition of __clz as an inline function in 
/usr/lib/llvm-3.9/lib/clang/3.9.1/include/arm_acle.h :

static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
__clz(uint32_t __t) {
   return __builtin_clz(__t);
}

however, xenomai-3/include/boilerplate/compiler.h defines __clz() as a macro, 
hence the issue.

Note that compiler.h similarly defines a macro for __ctz , but that is not 
defined in clang's arm_acle.h, so no issue with that one.

The patch below addresses the issue, leveraging clang's `__has_builtin()` 
feature, while keeping things the same for gcc:

diff --git a/include/boilerplate/compiler.h b/include/boilerplate/compiler.h
index bcef7d4cc..8697a24b0 100644
--- a/include/boilerplate/compiler.h
+++ b/include/boilerplate/compiler.h
@@ -83,6 +83,15 @@ void __invalid_operand_size(void);
                 __ret;                                                  \
         })

+#ifdef __clang__
+#if __has_builtin(__builtin_clz)
+#define DONT_DEF_CLZ
+#endif /* has_builtin */
+#endif /* __clang_ */
+
+#ifdef DONT_DEF_CLZ
+#undef DONT_DEF_CLZ
+#else /* DONT_DEF_CLZ */
  #define __clz(__v)                                                     \
         ({                                                              \
                 int __ret;                                              \
@@ -101,6 +110,7 @@ void __invalid_operand_size(void);
                         }                                               \
                 __ret;                                                  \
         })
+#endif /* DONT_DEF_CLZ */

  #ifdef __cplusplus
  }



We should do

#define __clz   __clz

in the clang case and then

#ifndef __clz

That should save some boilerplate code. Could you send a proper patch (see CONTRIBUTING.md)?

Thanks!
Jan

--
Siemens AG, Corporate Technology, CT RDA IOT SES-DE
Corporate Competence Center Embedded Linux

Reply via email to