Skip to content

Conversation

@vonosmas
Copy link
Contributor

@vonosmas vonosmas commented Dec 1, 2025

They are not used anywhere except for the btowc/wctob entrypoints, so just move the implementation there. Internal code should probably be using a safer mbrtowc variants anyway, if applicable.

This allows us to remove the use of wint_t, which is problematic for some uses through libc/shared/ when a host system doesn't have wide-character support (see PR #165884 comments). There's no such problems with wchar_t, since it's a fundamental type in C++.

They are not used anywhere except for the btowc/wctob entrypoints,
so just move the implementation there. Internal code should probably
be using a safer mbrtowc variants anyway, if applicable.

This allows us to remove the use of wint_t, which is problematic
for some uses through `libc/shared/` when a host system doesn't have
wide-character support (see PR llvm#165884 comments). There's no such
problems with `wchar_t`, since it's a fundamental type in C++.
@llvmbot llvmbot added libc bazel "Peripheral" support tier build system: utils/bazel labels Dec 1, 2025
@llvmbot
Copy link
Member

llvmbot commented Dec 1, 2025

@llvm/pr-subscribers-libc

Author: Alexey Samsonov (vonosmas)

Changes

They are not used anywhere except for the btowc/wctob entrypoints, so just move the implementation there. Internal code should probably be using a safer mbrtowc variants anyway, if applicable.

This allows us to remove the use of wint_t, which is problematic for some uses through libc/shared/ when a host system doesn't have wide-character support (see PR #165884 comments). There's no such problems with wchar_t, since it's a fundamental type in C++.


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

6 Files Affected:

  • (modified) libc/src/__support/CMakeLists.txt (-1)
  • (modified) libc/src/__support/wctype_utils.h (-26)
  • (modified) libc/src/wchar/CMakeLists.txt (-2)
  • (modified) libc/src/wchar/btowc.cpp (+2-6)
  • (modified) libc/src/wchar/wctob.cpp (+6-6)
  • (modified) utils/bazel/llvm-project-overlay/libc/BUILD.bazel (-4)
diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt
index d33e7ae45c068..c7f127d6934a0 100644
--- a/libc/src/__support/CMakeLists.txt
+++ b/libc/src/__support/CMakeLists.txt
@@ -162,7 +162,6 @@ add_header_library(
     wctype_utils.h
   DEPENDS
     libc.hdr.types.wchar_t
-    libc.hdr.types.wint_t
 )
 
 add_header_library(
diff --git a/libc/src/__support/wctype_utils.h b/libc/src/__support/wctype_utils.h
index 7041470adc2f4..7f17224104ffb 100644
--- a/libc/src/__support/wctype_utils.h
+++ b/libc/src/__support/wctype_utils.h
@@ -10,8 +10,6 @@
 #define LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_H
 
 #include "hdr/types/wchar_t.h"
-#include "hdr/types/wint_t.h"
-#include "src/__support/CPP/optional.h"
 #include "src/__support/macros/attributes.h" // LIBC_INLINE
 #include "src/__support/macros/config.h"
 
@@ -584,30 +582,6 @@ is_char_or_wchar(wchar_t ch, [[maybe_unused]] char, wchar_t wc_value) {
   return (ch == wc_value);
 }
 
-// ------------------------------------------------------
-// Rationale: Since these classification functions are
-// called in other functions, we will avoid the overhead
-// of a function call by inlining them.
-// ------------------------------------------------------
-
-LIBC_INLINE cpp::optional<int> wctob(wint_t c) {
-  // This needs to be translated to EOF at the callsite. This is to avoid
-  // including stdio.h in this file.
-  // The standard states that wint_t may either be an alias of wchar_t or
-  // an alias of an integer type, different platforms define this type with
-  // different signedness. This is equivalent to `(c > 127) || (c < 0)` but also
-  // works without -Wtype-limits warnings when `wint_t` is unsigned.
-  if ((c & ~127) != 0)
-    return cpp::nullopt;
-  return static_cast<int>(c);
-}
-
-LIBC_INLINE cpp::optional<wint_t> btowc(int c) {
-  if (c > 127 || c < 0)
-    return cpp::nullopt;
-  return static_cast<wint_t>(c);
-}
-
 } // namespace internal
 } // namespace LIBC_NAMESPACE_DECL
 
diff --git a/libc/src/wchar/CMakeLists.txt b/libc/src/wchar/CMakeLists.txt
index 9ca7295118a11..ce57199b0837a 100644
--- a/libc/src/wchar/CMakeLists.txt
+++ b/libc/src/wchar/CMakeLists.txt
@@ -40,7 +40,6 @@ add_entrypoint_object(
   DEPENDS
     libc.hdr.types.wint_t
     libc.hdr.stdio_macros
-    libc.src.__support.wctype_utils
 )
 
 add_entrypoint_object(
@@ -52,7 +51,6 @@ add_entrypoint_object(
   DEPENDS
     libc.hdr.types.wint_t
     libc.hdr.wchar_macros
-    libc.src.__support.wctype_utils
 )
 
 add_entrypoint_object(
diff --git a/libc/src/wchar/btowc.cpp b/libc/src/wchar/btowc.cpp
index c69f77d06c5c5..6bc7526fac164 100644
--- a/libc/src/wchar/btowc.cpp
+++ b/libc/src/wchar/btowc.cpp
@@ -9,7 +9,6 @@
 #include "src/wchar/btowc.h"
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
-#include "src/__support/wctype_utils.h"
 
 #include "hdr/types/wint_t.h"
 #include "hdr/wchar_macros.h" // for WEOF.
@@ -17,12 +16,9 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(wint_t, btowc, (int c)) {
-  auto result = internal::btowc(c);
-  if (result.has_value()) {
-    return result.value();
-  } else {
+  if (c > 127 || c < 0)
     return WEOF;
-  }
+  return static_cast<wint_t>(c);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/wctob.cpp b/libc/src/wchar/wctob.cpp
index 45240d6052eb4..9b6773bf6428e 100644
--- a/libc/src/wchar/wctob.cpp
+++ b/libc/src/wchar/wctob.cpp
@@ -9,7 +9,6 @@
 #include "src/wchar/wctob.h"
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
-#include "src/__support/wctype_utils.h"
 
 #include "hdr/stdio_macros.h" // for EOF.
 #include "hdr/types/wint_t.h"
@@ -17,12 +16,13 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, wctob, (wint_t c)) {
-  auto result = internal::wctob(c);
-  if (result.has_value()) {
-    return result.value();
-  } else {
+  // The standard states that wint_t may either be an alias of wchar_t or
+  // an alias of an integer type, different platforms define this type with
+  // different signedness. This is equivalent to `(c > 127) || (c < 0)` but also
+  // works without -Wtype-limits warnings when `wint_t` is unsigned.
+  if ((c & ~127) != 0)
     return EOF;
-  }
+  return static_cast<int>(c);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index e3962d9b5f95b..e063de015506b 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -1799,11 +1799,9 @@ libc_support_library(
     name = "__support_wctype_utils",
     hdrs = ["src/__support/wctype_utils.h"],
     deps = [
-        ":__support_cpp_optional",
         ":__support_macros_attributes",
         ":__support_macros_config",
         ":types_wchar_t",
-        ":types_wint_t",
     ],
 )
 
@@ -7472,7 +7470,6 @@ libc_function(
     deps = [
         ":__support_common",
         ":__support_macros_config",
-        ":__support_wctype_utils",
         ":hdr_wchar_macros",
         ":types_wint_t",
     ],
@@ -7704,7 +7701,6 @@ libc_function(
         ":__support_common",
         ":__support_macros_config",
         ":__support_macros_null_check",
-        ":__support_wctype_utils",
         ":hdr_stdio_macros",
         ":types_wint_t",
     ],

@ldionne
Copy link
Member

ldionne commented Dec 1, 2025

I pulled down this patch and it does appear to resolve the issue I was seeing. So clearly I'm fine with this patch, thank you!

However, any other patch would come around and legitimately add new mentions of wint_t, which would break libc++ again. So I think we should still discuss the general topic of "carve-out coordination" between LLVM libc and libc++. I'll add that to the libc++ monthly tomorrow, in case you folks can make it.

@vonosmas vonosmas requested a review from lntue December 1, 2025 20:27
@vonosmas
Copy link
Contributor Author

vonosmas commented Dec 1, 2025

Great, I'll merge after receiving approval from anyone.

@vonosmas vonosmas merged commit b545e54 into llvm:main Dec 1, 2025
31 checks passed
@vonosmas vonosmas deleted the wctob-removal branch December 1, 2025 21:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bazel "Peripheral" support tier build system: utils/bazel libc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants