From 087bce43020d2b45dab2dd8ecd6b0d6949c626f3 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 13 Sep 2021 16:57:02 -0400 Subject: [PATCH] Fix: powerpc32: transparent unions alter calling convention 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 [1] Signed-off-by: Mathieu Desnoyers Change-Id: I07182dd4ed37a3f61a226fb199bc98c95f83bd37 --- include/urcu/compiler.h | 6 ------ include/urcu/lfstack.h | 13 +++++++++++-- include/urcu/wfcqueue.h | 12 +++++++++++- include/urcu/wfstack.h | 12 +++++++++++- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/include/urcu/compiler.h b/include/urcu/compiler.h index 1573467..34eb564 100644 --- a/include/urcu/compiler.h +++ b/include/urcu/compiler.h @@ -119,10 +119,4 @@ + __GNUC_PATCHLEVEL__) #endif -#ifndef __cplusplus -#define caa_c_transparent_union __attribute__((__transparent_union__)) -#else -#define caa_c_transparent_union -#endif - #endif /* _URCU_COMPILER_H */ diff --git a/include/urcu/lfstack.h b/include/urcu/lfstack.h index b994ea6..0f4ee99 100644 --- a/include/urcu/lfstack.h +++ b/include/urcu/lfstack.h @@ -29,7 +29,6 @@ extern "C" { #include #include -#include /* * 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 diff --git a/include/urcu/wfcqueue.h b/include/urcu/wfcqueue.h index 2119e8d..bd920ca 100644 --- a/include/urcu/wfcqueue.h +++ b/include/urcu/wfcqueue.h @@ -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 /* diff --git a/include/urcu/wfstack.h b/include/urcu/wfstack.h index 5d58a91..0890f5c 100644 --- a/include/urcu/wfstack.h +++ b/include/urcu/wfstack.h @@ -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 -- 2.34.1