[libc-commits] [libc] [libc] Refactored internal wcrtomb (PR #145945)

via libc-commits libc-commits at lists.llvm.org
Thu Jun 26 10:55:54 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Uzair Nawaz (uzairnawaz)

<details>
<summary>Changes</summary>

Removed output parameters for internal::wcrtomb and instead returned a struct containing the result of the conversion. 


---
Full diff: https://github.com/llvm/llvm-project/pull/145945.diff


4 Files Affected:

- (modified) libc/src/__support/wchar/wcrtomb.cpp (+5-11) 
- (modified) libc/src/__support/wchar/wcrtomb.h (+6-1) 
- (modified) libc/src/wchar/wcrtomb.cpp (+4-4) 
- (modified) libc/src/wchar/wctomb.cpp (+3-2) 


``````````diff
diff --git a/libc/src/__support/wchar/wcrtomb.cpp b/libc/src/__support/wchar/wcrtomb.cpp
index a74a6f3ec34a6..4a365c84c605c 100644
--- a/libc/src/__support/wchar/wcrtomb.cpp
+++ b/libc/src/__support/wchar/wcrtomb.cpp
@@ -21,32 +21,26 @@
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
 
-ErrorOr<size_t> wcrtomb(char *__restrict s, wchar_t wc,
-                        mbstate *__restrict ps) {
+ErrorOr<wcrtomb_result> wcrtomb(wchar_t wc, mbstate *ps) {
   static_assert(sizeof(wchar_t) == 4);
 
+  wcrtomb_result out;
   CharacterConverter cr(ps);
 
   if (!cr.isValidState())
     return Error(EINVAL);
 
-  if (s == nullptr)
-    return Error(EILSEQ);
-
   int status = cr.push(static_cast<char32_t>(wc));
   if (status != 0)
     return Error(EILSEQ);
 
-  size_t count = 0;
   while (!cr.isEmpty()) {
     auto utf8 = cr.pop_utf8(); // can never fail as long as the push succeeded
     LIBC_ASSERT(utf8.has_value());
-
-    *s = utf8.value();
-    s++;
-    count++;
+    out.mbs[out.count++] = utf8.value();
   }
-  return count;
+
+  return out;
 }
 
 } // namespace internal
diff --git a/libc/src/__support/wchar/wcrtomb.h b/libc/src/__support/wchar/wcrtomb.h
index bcd39a92a3b76..b255fd41d6cc9 100644
--- a/libc/src/__support/wchar/wcrtomb.h
+++ b/libc/src/__support/wchar/wcrtomb.h
@@ -18,7 +18,12 @@
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
 
-ErrorOr<size_t> wcrtomb(char *__restrict s, wchar_t wc, mbstate *__restrict ps);
+struct wcrtomb_result {
+    char mbs[4];
+    size_t count = 0;    
+};
+
+ErrorOr<wcrtomb_result> wcrtomb(wchar_t wc, mbstate* ps);
 
 } // namespace internal
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/wcrtomb.cpp b/libc/src/wchar/wcrtomb.cpp
index 3e9df0599431e..119aa0da8344e 100644
--- a/libc/src/wchar/wcrtomb.cpp
+++ b/libc/src/wchar/wcrtomb.cpp
@@ -30,16 +30,16 @@ LLVM_LIBC_FUNCTION(size_t, wcrtomb,
   }
 
   auto result = internal::wcrtomb(
-      s, wc,
-      ps == nullptr ? &internal_mbstate
-                    : reinterpret_cast<internal::mbstate *>(ps));
+      wc, ps == nullptr ? &internal_mbstate
+                        : reinterpret_cast<internal::mbstate *>(ps));
 
   if (!result.has_value()) {
     libc_errno = result.error();
     return -1;
   }
 
-  return result.value();
+  __builtin_memcpy(s, result.value().mbs, result.value().count);
+  return result.value().count;
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/wctomb.cpp b/libc/src/wchar/wctomb.cpp
index 142302e6ae09b..7dbb5347df5da 100644
--- a/libc/src/wchar/wctomb.cpp
+++ b/libc/src/wchar/wctomb.cpp
@@ -22,14 +22,15 @@ LLVM_LIBC_FUNCTION(int, wctomb, (char *s, wchar_t wc)) {
   if (s == nullptr)
     return 0;
 
-  auto result = internal::wcrtomb(s, wc, &internal_mbstate);
+  auto result = internal::wcrtomb(wc, &internal_mbstate);
 
   if (!result.has_value()) { // invalid wide character
     libc_errno = EILSEQ;
     return -1;
   }
 
-  return static_cast<int>(result.value());
+  __builtin_memcpy(s, result.value().mbs, result.value().count);
+  return static_cast<int>(result.value().count);
 }
 
 } // namespace LIBC_NAMESPACE_DECL

``````````

</details>


https://github.com/llvm/llvm-project/pull/145945


More information about the libc-commits mailing list