Fix: powerpc32: transparent unions alter calling convention
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 13 Sep 2021 20:57:02 +0000 (16:57 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 13 Sep 2021 21:10:08 +0000 (17:10 -0400)
On powerpc32, transparent unions have an impact on the calling
convention used for the argument, as they use the calling convention of
the first field of the union rather than the union itself. On powerpc32,
the calling convention for a union is that the register has a pointer to
the union, which differs from the calling convention of its first field
(which is a pointer in this case).

"[...] the argument is passed to the function using the calling
conventions of the first member of the transparent union, not the
calling conventions of the union itself. All members of the union must
have the same machine representation; this is necessary for this
argument passing to work properly." [1]

Therefore, use a transparent union for c++ so c++ compilers can emit
caller code with a compatible stack layout. The "ignored attribute"
warning emitted by clang appears to be only for architectures where the
calling convention is not affected by the presence of transparent union
attribute. Therefore, simply silence this warning.

Link: https://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Type-Attributes.html
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I07182dd4ed37a3f61a226fb199bc98c95f83bd37

include/urcu/compiler.h
include/urcu/lfstack.h
include/urcu/wfcqueue.h
include/urcu/wfstack.h

index 157346763078a3ec1d73b7c65618ed1bd98b325f..34eb564bb77795e9e77d21983240c3327b3401d1 100644 (file)
                                + __GNUC_PATCHLEVEL__)
 #endif
 
-#ifndef __cplusplus
-#define caa_c_transparent_union        __attribute__((__transparent_union__))
-#else
-#define caa_c_transparent_union
-#endif
-
 #endif /* _URCU_COMPILER_H */
index b994ea6b5385285d7357da5c0a3fb2fc74eea257..0f4ee99d8c92a88d88d51fe47d36eb47275056fb 100644 (file)
@@ -29,7 +29,6 @@ extern "C" {
 
 #include <stdbool.h>
 #include <pthread.h>
-#include <urcu/compiler.h>
 
 /*
  * Lock-free stack.
@@ -87,11 +86,21 @@ struct cds_lfs_stack {
  *
  * In C++, implement static inline wrappers using function overloading
  * to obtain an API similar to C.
+ *
+ * Avoid complaints from clang++ not knowing the transparent union
+ * attribute.
  */
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wignored-attributes"
+#endif
 typedef union {
        struct __cds_lfs_stack *_s;
        struct cds_lfs_stack *s;
-} caa_c_transparent_union cds_lfs_stack_ptr_t;
+} __attribute__((__transparent_union__)) cds_lfs_stack_ptr_t;
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
 
 #ifdef _LGPL_SOURCE
 
index 2119e8d24ce49a431d70e133d5bf766e4eb2cec4..bd920ca488b6b0feedb243383fe641b0741842a2 100644 (file)
@@ -80,11 +80,21 @@ struct cds_wfcq_head {
  *
  * In C++, implement static inline wrappers using function overloading
  * to obtain an API similar to C.
+ *
+ * Avoid complaints from clang++ not knowing the transparent union
+ * attribute.
  */
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wignored-attributes"
+#endif
 typedef union {
        struct __cds_wfcq_head *_h;
        struct cds_wfcq_head *h;
-} caa_c_transparent_union cds_wfcq_head_ptr_t;
+} __attribute__((__transparent_union__)) cds_wfcq_head_ptr_t;
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
 
 #ifndef __cplusplus
 /*
index 5d58a9143ffb49eaaf6f2a1ad491aa34a81048d3..0890f5c1a54b7d8e590196cf6553ce12f5b7e001 100644 (file)
@@ -98,11 +98,21 @@ struct cds_wfs_stack {
  *
  * In C++, implement static inline wrappers using function overloading
  * to obtain an API similar to C.
+ *
+ * Avoid complaints from clang++ not knowing the transparent union
+ * attribute.
  */
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wignored-attributes"
+#endif
 typedef union {
        struct __cds_wfs_stack *_s;
        struct cds_wfs_stack *s;
-} caa_c_transparent_union cds_wfs_stack_ptr_t;
+} __attribute__((__transparent_union__)) cds_wfs_stack_ptr_t;
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
 
 #ifdef _LGPL_SOURCE
 
This page took 0.028057 seconds and 4 git commands to generate.