From 08a3fee6380fe00d5333ff5e7d4ffa5455dbacdf Mon Sep 17 00:00:00 2001 From: "Mikhail R. Gadelha" Date: Thu, 14 Aug 2025 21:30:21 -0300 Subject: [PATCH 1/4] Remove hardcoded sizeof Signed-off-by: Mikhail R. Gadelha --- libc/include/llvm-libc-types/__barrier_type.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libc/include/llvm-libc-types/__barrier_type.h b/libc/include/llvm-libc-types/__barrier_type.h index 59712619e917d..23593372af56e 100644 --- a/libc/include/llvm-libc-types/__barrier_type.h +++ b/libc/include/llvm-libc-types/__barrier_type.h @@ -9,13 +9,16 @@ #ifndef LLVM_LIBC_TYPES__BARRIER_TYPE_H #define LLVM_LIBC_TYPES__BARRIER_TYPE_H +#include "src/__support/threads/CndVar.h" +#include "src/__support/threads/mutex.h" + typedef struct __attribute__((aligned(8 /* alignof (Barrier) */))) { unsigned expected; unsigned waiting; bool blocking; - char entering[24 /* sizeof (CndVar) */]; - char exiting[24 /* sizeof (CndVar) */]; - char mutex[24 /* sizeof (Mutex) */]; + char entering[sizeof(LIBC_NAMESPACE::CndVar)]; + char exiting[sizeof(LIBC_NAMESPACE::CndVar)]; + char mutex[sizeof(LIBC_NAMESPACE::Mutex)]; } __barrier_type; #endif // LLVM_LIBC_TYPES__BARRIER_TYPE_H From 0d1d202f288891ee6fd83ff8e08af6bccfbc2379 Mon Sep 17 00:00:00 2001 From: "Mikhail R. Gadelha" Date: Thu, 14 Aug 2025 21:33:32 -0300 Subject: [PATCH 2/4] Fix test case Signed-off-by: Mikhail R. Gadelha --- libc/test/src/wchar/mbrtowc_test.cpp | 60 ++++++++++++++-------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/libc/test/src/wchar/mbrtowc_test.cpp b/libc/test/src/wchar/mbrtowc_test.cpp index c406300b9ca34..ddf8fc73b055b 100644 --- a/libc/test/src/wchar/mbrtowc_test.cpp +++ b/libc/test/src/wchar/mbrtowc_test.cpp @@ -37,18 +37,18 @@ TEST_F(LlvmLibcMBRToWCTest, TwoByte) { const char ch[2] = {static_cast(0xC2), static_cast(0x8E)}; // Ž car symbol wchar_t dest[2]; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); - size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, &mb); ASSERT_EQ(static_cast(*dest), 142); ASSERT_EQ(static_cast(n), 2); ASSERT_ERRNO_SUCCESS(); // Should fail since we have not read enough - n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, &mb); ASSERT_EQ(static_cast(n), -2); // Should pass after reading one more byte - n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 1, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 1, &mb); ASSERT_EQ(static_cast(n), 1); ASSERT_EQ(static_cast(*dest), 142); ASSERT_ERRNO_SUCCESS(); @@ -58,19 +58,19 @@ TEST_F(LlvmLibcMBRToWCTest, ThreeByte) { const char ch[3] = {static_cast(0xE2), static_cast(0x88), static_cast(0x91)}; // ∑ sigma symbol wchar_t dest[2]; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); - size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 3, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 3, &mb); ASSERT_EQ(static_cast(*dest), 8721); ASSERT_EQ(static_cast(n), 3); ASSERT_ERRNO_SUCCESS(); // Should fail since we have not read enough - n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, &mb); ASSERT_EQ(static_cast(n), -2); ASSERT_ERRNO_SUCCESS(); // Should pass after reading two more bytes - n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 2, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 2, &mb); ASSERT_EQ(static_cast(n), 2); ASSERT_EQ(static_cast(*dest), 8721); ASSERT_ERRNO_SUCCESS(); @@ -81,18 +81,18 @@ TEST_F(LlvmLibcMBRToWCTest, FourByte) { static_cast(0xA4), static_cast(0xA1)}; // 🤡 clown emoji wchar_t dest[2]; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); - size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, &mb); ASSERT_EQ(static_cast(*dest), 129313); ASSERT_EQ(static_cast(n), 4); ASSERT_ERRNO_SUCCESS(); // Should fail since we have not read enough - n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, &mb); ASSERT_EQ(static_cast(n), -2); ASSERT_ERRNO_SUCCESS(); // Should pass after reading two more bytes - n = LIBC_NAMESPACE::mbrtowc(dest, ch + 2, 2, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch + 2, 2, &mb); ASSERT_EQ(static_cast(n), 2); ASSERT_EQ(static_cast(*dest), 129313); ASSERT_ERRNO_SUCCESS(); @@ -101,9 +101,9 @@ TEST_F(LlvmLibcMBRToWCTest, FourByte) { TEST_F(LlvmLibcMBRToWCTest, InvalidByte) { const char ch[1] = {static_cast(0x80)}; wchar_t dest[2]; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); - size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, &mb); ASSERT_EQ(static_cast(n), -1); ASSERT_ERRNO_EQ(EILSEQ); } @@ -113,18 +113,18 @@ TEST_F(LlvmLibcMBRToWCTest, InvalidMultiByte) { static_cast(0x80), static_cast(0x00)}; // invalid sequence of bytes wchar_t dest[2]; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); // Trying to push all 4 should error - size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, &mb); ASSERT_EQ(static_cast(n), -1); ASSERT_ERRNO_EQ(EILSEQ); // Trying to push just the first one should error - n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, &mb); ASSERT_EQ(static_cast(n), -1); ASSERT_ERRNO_EQ(EILSEQ); // Trying to push the second and third should correspond to null wc - n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 2, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 2, &mb); ASSERT_EQ(static_cast(n), 0); ASSERT_TRUE(*dest == L'\0'); ASSERT_ERRNO_SUCCESS(); @@ -136,10 +136,10 @@ TEST_F(LlvmLibcMBRToWCTest, InvalidLastByte) { const char ch[4] = {static_cast(0xF1), static_cast(0x80), static_cast(0x80), static_cast(0xC0)}; wchar_t dest[2]; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); // Trying to push all 4 should error - size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, &mb); ASSERT_EQ(static_cast(n), -1); ASSERT_ERRNO_EQ(EILSEQ); } @@ -148,10 +148,10 @@ TEST_F(LlvmLibcMBRToWCTest, ValidTwoByteWithExtraRead) { const char ch[3] = {static_cast(0xC2), static_cast(0x8E), static_cast(0x80)}; wchar_t dest[2]; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); // Trying to push all 3 should return valid 2 byte - size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 3, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 3, &mb); ASSERT_EQ(static_cast(n), 2); ASSERT_EQ(static_cast(*dest), 142); ASSERT_ERRNO_SUCCESS(); @@ -161,14 +161,14 @@ TEST_F(LlvmLibcMBRToWCTest, TwoValidTwoBytes) { const char ch[4] = {static_cast(0xC2), static_cast(0x8E), static_cast(0xC7), static_cast(0x8C)}; wchar_t dest[2]; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); // mbstate should reset after reading first one - size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, &mb); ASSERT_EQ(static_cast(n), 2); ASSERT_EQ(static_cast(*dest), 142); ASSERT_ERRNO_SUCCESS(); - n = LIBC_NAMESPACE::mbrtowc(dest + 1, ch + 2, 2, mb); + n = LIBC_NAMESPACE::mbrtowc(dest + 1, ch + 2, 2, &mb); ASSERT_EQ(static_cast(n), 2); ASSERT_EQ(static_cast(*(dest + 1)), 460); ASSERT_ERRNO_SUCCESS(); @@ -176,16 +176,16 @@ TEST_F(LlvmLibcMBRToWCTest, TwoValidTwoBytes) { TEST_F(LlvmLibcMBRToWCTest, NullString) { wchar_t dest[2] = {L'O', L'K'}; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); // reading on nullptr should return 0 - size_t n = LIBC_NAMESPACE::mbrtowc(dest, nullptr, 2, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, nullptr, 2, &mb); ASSERT_EQ(static_cast(n), 0); ASSERT_TRUE(dest[0] == L'O'); ASSERT_ERRNO_SUCCESS(); // reading a null terminator should return 0 const char *ch = "\0"; - n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, &mb); ASSERT_EQ(static_cast(n), 0); ASSERT_ERRNO_SUCCESS(); } @@ -194,10 +194,10 @@ TEST_F(LlvmLibcMBRToWCTest, NullDest) { const char ch[4] = {static_cast(0xF0), static_cast(0x9F), static_cast(0xA4), static_cast(0xA1)}; // 🤡 clown emoji - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); // reading nullptr should return correct size - size_t n = LIBC_NAMESPACE::mbrtowc(nullptr, ch, 10, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(nullptr, ch, 10, &mb); ASSERT_EQ(static_cast(n), 4); ASSERT_ERRNO_SUCCESS(); } From 0da48fd3873eeb1c22ca55fe47373ab3189fe460 Mon Sep 17 00:00:00 2001 From: "Mikhail R. Gadelha" Date: Fri, 15 Aug 2025 12:09:34 -0300 Subject: [PATCH 3/4] Changed static_assert Signed-off-by: Mikhail R. Gadelha --- libc/include/llvm-libc-types/__barrier_type.h | 9 +++------ libc/src/__support/threads/linux/barrier.h | 15 ++++++++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/libc/include/llvm-libc-types/__barrier_type.h b/libc/include/llvm-libc-types/__barrier_type.h index 23593372af56e..59712619e917d 100644 --- a/libc/include/llvm-libc-types/__barrier_type.h +++ b/libc/include/llvm-libc-types/__barrier_type.h @@ -9,16 +9,13 @@ #ifndef LLVM_LIBC_TYPES__BARRIER_TYPE_H #define LLVM_LIBC_TYPES__BARRIER_TYPE_H -#include "src/__support/threads/CndVar.h" -#include "src/__support/threads/mutex.h" - typedef struct __attribute__((aligned(8 /* alignof (Barrier) */))) { unsigned expected; unsigned waiting; bool blocking; - char entering[sizeof(LIBC_NAMESPACE::CndVar)]; - char exiting[sizeof(LIBC_NAMESPACE::CndVar)]; - char mutex[sizeof(LIBC_NAMESPACE::Mutex)]; + char entering[24 /* sizeof (CndVar) */]; + char exiting[24 /* sizeof (CndVar) */]; + char mutex[24 /* sizeof (Mutex) */]; } __barrier_type; #endif // LLVM_LIBC_TYPES__BARRIER_TYPE_H diff --git a/libc/src/__support/threads/linux/barrier.h b/libc/src/__support/threads/linux/barrier.h index f0655bfc52a10..d6264f7d631e8 100644 --- a/libc/src/__support/threads/linux/barrier.h +++ b/libc/src/__support/threads/linux/barrier.h @@ -36,15 +36,20 @@ class Barrier { int wait(); }; -static_assert( - sizeof(Barrier) == sizeof(pthread_barrier_t), - "The public pthread_barrier_t type cannot accommodate the internal " - "barrier type."); +static_assert(sizeof(Barrier) <= sizeof(pthread_barrier_t), + "The public pthread_barrier_t type cannot accommodate the " + "internal barrier type."); -static_assert(alignof(Barrier) == alignof(pthread_barrier_t), +static_assert(alignof(Barrier) <= alignof(pthread_barrier_t), "The public pthread_barrier_t type has a different alignment " "than the internal barrier type."); +static_assert(sizeof(CndVar) <= 24, + "CndVar size exceeds the size in __barrier_type.h"); + +static_assert(sizeof(Mutex) <= 24, + "Mutex size exceeds the size in __barrier_type.h"); + } // namespace LIBC_NAMESPACE_DECL #endif // LLVM_LIBC___SUPPORT_SRC_THREADS_LINUX_BARRIER_H From 5844bf7bab0e9e3e36d77b7b25f59efe6aa37a99 Mon Sep 17 00:00:00 2001 From: "Mikhail R. Gadelha" Date: Wed, 20 Aug 2025 19:30:22 -0300 Subject: [PATCH 4/4] Update comment Signed-off-by: Mikhail R. Gadelha --- libc/src/__support/threads/linux/barrier.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libc/src/__support/threads/linux/barrier.h b/libc/src/__support/threads/linux/barrier.h index d6264f7d631e8..a632aa45b2aa2 100644 --- a/libc/src/__support/threads/linux/barrier.h +++ b/libc/src/__support/threads/linux/barrier.h @@ -41,8 +41,8 @@ static_assert(sizeof(Barrier) <= sizeof(pthread_barrier_t), "internal barrier type."); static_assert(alignof(Barrier) <= alignof(pthread_barrier_t), - "The public pthread_barrier_t type has a different alignment " - "than the internal barrier type."); + "The public pthread_barrier_t type has insufficient alignment " + "for the internal barrier type."); static_assert(sizeof(CndVar) <= 24, "CndVar size exceeds the size in __barrier_type.h");