From 10156f5f1d9c87d2076ebed13aa3e5d75869a8f1 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Fri, 29 Dec 2023 10:06:44 -0500 Subject: [PATCH] posix: mqueue: pop mode as int with va_arg() There was some discussion about whether it was suitable to have an architecture-specific workaround in mqueue.c after that workaround was copied to a different source file in a PR. The original issue was that newlib and picolibc declare mode_t to be unsigned short instead of unsigned long when __svr4__ is not defined along with __sparc__. This is specifically impactful, because va_arg() deals (mainly) with 32-bit and 64-bit values that are all naturally aligned to 4 bytes. #if defined(__sparc__) && !defined(__sparc_v9__) #ifdef __svr4__ typedef unsigned long __mode_t; #else typedef unsigned short __mode_t; #endif A uint16_t is naturally aligned to 2 bytes, so not only would a 16-bit mode_t be corrupted, it would also generate a warning with recent gcc versions which is promoted to error (rightfully so) when run through CI. mqueue.c:61:35: error: 'mode_t' {aka 'short unsigned int'} is promoted to 'int' when passed through '...' [-Werror] 61 | mode = va_arg(va, mode_t); Instead of using an architecture-specific workaround, simply add a build assert that the size of mode_t is less than or equal to the size of an int, and use an int to retrieve it via va_arg(). Signed-off-by: Christopher Friedt # Please enter the commit message for your changes. Lines starting # with '#' will be kept; you may remove them yourself if you want to. # An empty message aborts the commit. # # Date: Fri Dec 29 10:06:44 2023 -0500 # # On branch posix-mqueue-always-use-int-for-mode-t-va-arg # Changes to be committed: # modified: lib/posix/mqueue.c # modified: tests/posix/common/testcase.yaml # --- lib/posix/mqueue.c | 14 ++------------ tests/posix/common/testcase.yaml | 3 --- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/lib/posix/mqueue.c b/lib/posix/mqueue.c index 5c3d5e5e5d9a..47e660111bb1 100644 --- a/lib/posix/mqueue.c +++ b/lib/posix/mqueue.c @@ -38,17 +38,6 @@ static int receive_message(mqueue_desc *mqd, char *msg_ptr, size_t msg_len, k_timeout_t timeout); static void remove_mq(mqueue_object *msg_queue); -#if defined(__sparc__) -/* - * mode_t is defined as "unsigned short" on SPARC newlib. This type is promoted - * to "int" when passed through '...' so we should pass the promoted type to - * va_arg(). - */ -#define PROMOTED_MODE_T int -#else -#define PROMOTED_MODE_T mode_t -#endif - /** * @brief Open a message queue. * @@ -69,7 +58,8 @@ mqd_t mq_open(const char *name, int oflags, ...) va_start(va, oflags); if ((oflags & O_CREAT) != 0) { - mode = va_arg(va, PROMOTED_MODE_T); + BUILD_ASSERT(sizeof(mode_t) <= sizeof(int)); + mode = va_arg(va, unsigned int); attrs = va_arg(va, struct mq_attr*); } va_end(va); diff --git a/tests/posix/common/testcase.yaml b/tests/posix/common/testcase.yaml index cb48095c67cf..03f7ee381ac1 100644 --- a/tests/posix/common/testcase.yaml +++ b/tests/posix/common/testcase.yaml @@ -1,9 +1,6 @@ common: filter: not (CONFIG_NATIVE_BUILD and CONFIG_EXTERNAL_LIBC) - # FIXME: qemu_leon3 is excluded because of the alignment-related failure - # reported in the GitHub issue zephyrproject-rtos/zephyr#48992. platform_exclude: - - qemu_leon3 - native_posix - native_posix_64 tags: posix