[libcxx-commits] [libcxx] [libcxx][c++26] 2937R0: Freestanding: Remove strtok (PR #146290)

via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jun 30 02:28:14 PDT 2025


https://github.com/dywoq updated https://github.com/llvm/llvm-project/pull/146290

>From 96e28740abe407fc02e17b0e6cbc8f35a3cd0fc4 Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Sun, 29 Jun 2025 21:59:10 +0300
Subject: [PATCH 01/13] [libcxx cstring] make strtok not freestanding

---
 libcxx/include/cstring | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libcxx/include/cstring b/libcxx/include/cstring
index 4aa14feeec280..f7f38d359b602 100644
--- a/libcxx/include/cstring
+++ b/libcxx/include/cstring
@@ -47,7 +47,7 @@ const char* strrchr(const char* s, int c);
 size_t strspn(const char* s1, const char* s2);
 const char* strstr(const char* s1, const char* s2);
       char* strstr(      char* s1, const char* s2);
-char* strtok(char* restrict s1, const char* restrict s2);
+char* strtok(char* restrict s1, const char* restrict s2); // not freestanding in C++
 void* memset(void* s, int c, size_t n);
 char* strerror(int errnum);
 size_t strlen(const char* s);
@@ -97,7 +97,9 @@ using ::strpbrk _LIBCPP_USING_IF_EXISTS;
 using ::strrchr _LIBCPP_USING_IF_EXISTS;
 using ::strspn _LIBCPP_USING_IF_EXISTS;
 using ::strstr _LIBCPP_USING_IF_EXISTS;
+#if __STDC_HOSTED__ == 1
 using ::strtok _LIBCPP_USING_IF_EXISTS;
+#endif
 using ::memset _LIBCPP_USING_IF_EXISTS;
 using ::strerror _LIBCPP_USING_IF_EXISTS;
 using ::strlen _LIBCPP_USING_IF_EXISTS;

>From 311aac1e91dd219e9dd7566be234ee9e7bf50a3b Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Sun, 29 Jun 2025 22:07:38 +0300
Subject: [PATCH 02/13] [libcxx] change the if/endif macro condition in cstring

---
 libcxx/include/cstring                          |  2 +-
 .../freestanding/strtok_removed.fail.cpp        | 17 +++++++++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)
 create mode 100644 libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp

diff --git a/libcxx/include/cstring b/libcxx/include/cstring
index f7f38d359b602..3828b33c9ee8b 100644
--- a/libcxx/include/cstring
+++ b/libcxx/include/cstring
@@ -97,7 +97,7 @@ using ::strpbrk _LIBCPP_USING_IF_EXISTS;
 using ::strrchr _LIBCPP_USING_IF_EXISTS;
 using ::strspn _LIBCPP_USING_IF_EXISTS;
 using ::strstr _LIBCPP_USING_IF_EXISTS;
-#if __STDC_HOSTED__ == 1
+#if __STDC_HOSTED__ == 1 || _LIBCPP_STD_VER < 26
 using ::strtok _LIBCPP_USING_IF_EXISTS;
 #endif
 using ::memset _LIBCPP_USING_IF_EXISTS;
diff --git a/libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp b/libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp
new file mode 100644
index 0000000000000..f4ff87c27f65b
--- /dev/null
+++ b/libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp
@@ -0,0 +1,17 @@
+// this test confirms that std::strtok is not available in a freestanding C++ environment.
+// it is expected to fail compilation when -ffreestanding is enabled.
+
+// UNSUPPORTED: libcpp-has-no-cstring
+// REQUIRES: freestanding
+// XFAIL: *
+
+// RUN: %clang %s -c -o /dev/null -ffreestanding --std=c++20 2>&1 | FileCheck %s
+
+#include <cstring> 
+
+int main() {
+  char s[] = "hello world";
+  char* tok = std::strtok(s, " ");
+  (void)tok;
+  return 0;
+}
\ No newline at end of file

>From b42c795142090ae783b0e1d6b90f19b8f4bd0009 Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Sun, 29 Jun 2025 22:21:20 +0300
Subject: [PATCH 03/13] [libcxx] remove comment in cstring.freestanding test

---
 libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp b/libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp
index f4ff87c27f65b..18c5f069e9a7e 100644
--- a/libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp
+++ b/libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp
@@ -1,6 +1,3 @@
-// this test confirms that std::strtok is not available in a freestanding C++ environment.
-// it is expected to fail compilation when -ffreestanding is enabled.
-
 // UNSUPPORTED: libcpp-has-no-cstring
 // REQUIRES: freestanding
 // XFAIL: *

>From e4d20cec84dd168bdbb6b98caa40000d033af10f Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Sun, 29 Jun 2025 22:41:26 +0300
Subject: [PATCH 04/13] [libcxx] add feature test macro
 __cpp_lib_freestanding_cstring

---
 libcxx/include/version | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libcxx/include/version b/libcxx/include/version
index 91fe48351e161..dafbafefaa2ae 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -534,6 +534,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_to_underlying                        202102L
 // # define __cpp_lib_tuple_like                           202207L
 # define __cpp_lib_unreachable                          202202L
+# define __cpp_lib_freestanding_cstring                 202306L
 #endif
 
 #if _LIBCPP_STD_VER >= 26
@@ -606,6 +607,8 @@ __cpp_lib_void_t                                        201411L <type_traits>
 // # define __cpp_lib_tuple_like                           202311L
 # undef  __cpp_lib_variant
 # define __cpp_lib_variant                              202306L
+# undef __cpp_lib_freestanding_cstring
+# define __cpp_lib_freestanding_cstring                 202306L
 #endif
 
 #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)

>From 10aca15bd636ba926210006a081641e3bfa8671a Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Sun, 29 Jun 2025 22:59:36 +0300
Subject: [PATCH 05/13] [libcxx] update synopsis in <version> header

---
 libcxx/include/version | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libcxx/include/version b/libcxx/include/version
index dafbafefaa2ae..591844bebdeb6 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -116,7 +116,8 @@ __cpp_lib_formatters                                    202302L <stacktrace> <th
 __cpp_lib_forward_like                                  202207L <utility>
 __cpp_lib_freestanding_algorithm                        202311L <algorithm>
 __cpp_lib_freestanding_array                            202311L <array>
-__cpp_lib_freestanding_cstring                          202306L <cstring>
+__cpp_lib_freestanding_cstring                          202306L <cstring> 
+                                                        202306L 
 __cpp_lib_freestanding_expected                         202311L <expected>
 __cpp_lib_freestanding_mdspan                           202311L <mdspan>
 __cpp_lib_freestanding_optional                         202311L <optional>

>From 8631890b76755d4063305d468ec362459a4ace89 Mon Sep 17 00:00:00 2001
From: dywoq <138208549+dywoq at users.noreply.github.com>
Date: Sun, 29 Jun 2025 23:00:15 +0300
Subject: [PATCH 06/13] Update
 libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp

Co-authored-by: Hristo Hristov <zingam at outlook.com>
---
 libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp b/libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp
index 18c5f069e9a7e..32a88b7614cd5 100644
--- a/libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp
+++ b/libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp
@@ -11,4 +11,4 @@ int main() {
   char* tok = std::strtok(s, " ");
   (void)tok;
   return 0;
-}
\ No newline at end of file
+}

>From 5fb0ca580686b08443144c4941042c4893d46d5f Mon Sep 17 00:00:00 2001
From: dywoq <138208549+dywoq at users.noreply.github.com>
Date: Mon, 30 Jun 2025 00:13:27 +0300
Subject: [PATCH 07/13] [libcxx] change c++ standard to c++2c in
 strtok_removed.fail.cpp

---
 libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp b/libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp
index 32a88b7614cd5..0f0869380af99 100644
--- a/libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp
+++ b/libcxx/test/std/cstring/freestanding/strtok_removed.fail.cpp
@@ -2,7 +2,7 @@
 // REQUIRES: freestanding
 // XFAIL: *
 
-// RUN: %clang %s -c -o /dev/null -ffreestanding --std=c++20 2>&1 | FileCheck %s
+// RUN: %clang %s -c -o /dev/null -ffreestanding --std=c++2c 2>&1 | FileCheck %s
 
 #include <cstring> 
 

>From d059b9d7e7a4862a0d4f4c090b69d9adf6036b3e Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 07:06:29 +0300
Subject: [PATCH 08/13] [libcxx] update synopsis in cstring

---
 libcxx/include/cstring | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/cstring b/libcxx/include/cstring
index 3828b33c9ee8b..8ebe9dc6a10fa 100644
--- a/libcxx/include/cstring
+++ b/libcxx/include/cstring
@@ -47,7 +47,7 @@ const char* strrchr(const char* s, int c);
 size_t strspn(const char* s1, const char* s2);
 const char* strstr(const char* s1, const char* s2);
       char* strstr(      char* s1, const char* s2);
-char* strtok(char* restrict s1, const char* restrict s2); // not freestanding in C++
+char* strtok(char* restrict s1, const char* restrict s2); // not freestanding
 void* memset(void* s, int c, size_t n);
 char* strerror(int errnum);
 size_t strlen(const char* s);

>From dba6efa1d9f3d0ba24f1fa5f065bf6a6bb1e0bf8 Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 07:11:26 +0300
Subject: [PATCH 09/13] [libcxx] update
 generate_feature_test_macro_components.py

---
 libcxx/utils/generate_feature_test_macro_components.py | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index edd7b124a1fb3..f0eeef6babba0 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -1473,6 +1473,11 @@ def add_version_header(tc):
             "values": {"c++17": 201411},
             "headers": ["type_traits"],
         },
+		{
+			"name:": "__cpp_lib_freestanding_cstring",
+			"values": {"c++26": 202306L},
+			"headers": ["cstring"],
+		}
     ]
 ]
 

>From 97a7e412b593abd88237cc81b9045cc4607482b5 Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 07:11:56 +0300
Subject: [PATCH 10/13] [libcxx] remove extra colon

---
 libcxx/utils/generate_feature_test_macro_components.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index f0eeef6babba0..0dbeff79fc65b 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -1474,7 +1474,7 @@ def add_version_header(tc):
             "headers": ["type_traits"],
         },
 		{
-			"name:": "__cpp_lib_freestanding_cstring",
+			"name": "__cpp_lib_freestanding_cstring",
 			"values": {"c++26": 202306L},
 			"headers": ["cstring"],
 		}

>From fb1f355acd13379f871e34625ca2a8d3c04f1565 Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 07:14:03 +0300
Subject: [PATCH 11/13] [libcxx] remove L at the end of number

---
 libcxx/utils/generate_feature_test_macro_components.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 0dbeff79fc65b..8cb2ff11b0bf4 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -1475,7 +1475,7 @@ def add_version_header(tc):
         },
 		{
 			"name": "__cpp_lib_freestanding_cstring",
-			"values": {"c++26": 202306L},
+			"values": {"c++26": 202306},
 			"headers": ["cstring"],
 		}
     ]

>From 15ab8ec67af062099c1595a1c0e2f7e692700962 Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 07:34:57 +0300
Subject: [PATCH 12/13] [libcxx] update <verison> header

---
 libcxx/include/version                                    | 8 ++------
 .../cstring.version.compile.pass.cpp                      | 4 ++--
 .../version.version.compile.pass.cpp                      | 4 ++--
 libcxx/utils/generate_feature_test_macro_components.py    | 8 ++------
 4 files changed, 8 insertions(+), 16 deletions(-)

diff --git a/libcxx/include/version b/libcxx/include/version
index 591844bebdeb6..4acc910d50fc3 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -116,8 +116,7 @@ __cpp_lib_formatters                                    202302L <stacktrace> <th
 __cpp_lib_forward_like                                  202207L <utility>
 __cpp_lib_freestanding_algorithm                        202311L <algorithm>
 __cpp_lib_freestanding_array                            202311L <array>
-__cpp_lib_freestanding_cstring                          202306L <cstring> 
-                                                        202306L 
+__cpp_lib_freestanding_cstring                          202307L <cstring>
 __cpp_lib_freestanding_expected                         202311L <expected>
 __cpp_lib_freestanding_mdspan                           202311L <mdspan>
 __cpp_lib_freestanding_optional                         202311L <optional>
@@ -535,7 +534,6 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_to_underlying                        202102L
 // # define __cpp_lib_tuple_like                           202207L
 # define __cpp_lib_unreachable                          202202L
-# define __cpp_lib_freestanding_cstring                 202306L
 #endif
 
 #if _LIBCPP_STD_VER >= 26
@@ -560,7 +558,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 // # define __cpp_lib_format_path                          202403L
 // # define __cpp_lib_freestanding_algorithm               202311L
 // # define __cpp_lib_freestanding_array                   202311L
-// # define __cpp_lib_freestanding_cstring                 202306L
+// # define __cpp_lib_freestanding_cstring                 202307L
 // # define __cpp_lib_freestanding_expected                202311L
 // # define __cpp_lib_freestanding_mdspan                  202311L
 // # define __cpp_lib_freestanding_optional                202311L
@@ -608,8 +606,6 @@ __cpp_lib_void_t                                        201411L <type_traits>
 // # define __cpp_lib_tuple_like                           202311L
 # undef  __cpp_lib_variant
 # define __cpp_lib_variant                              202306L
-# undef __cpp_lib_freestanding_cstring
-# define __cpp_lib_freestanding_cstring                 202306L
 #endif
 
 #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/cstring.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/cstring.version.compile.pass.cpp
index 675c918cac417..625e7b093627f 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/cstring.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/cstring.version.compile.pass.cpp
@@ -54,8 +54,8 @@
 #    ifndef __cpp_lib_freestanding_cstring
 #      error "__cpp_lib_freestanding_cstring should be defined in c++26"
 #    endif
-#    if __cpp_lib_freestanding_cstring != 202306L
-#      error "__cpp_lib_freestanding_cstring should have the value 202306L in c++26"
+#    if __cpp_lib_freestanding_cstring != 202307L
+#      error "__cpp_lib_freestanding_cstring should have the value 202307L in c++26"
 #    endif
 #  else
 #    ifdef __cpp_lib_freestanding_cstring
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index e546719142231..2281942e0d9f1 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -6809,8 +6809,8 @@
 #    ifndef __cpp_lib_freestanding_cstring
 #      error "__cpp_lib_freestanding_cstring should be defined in c++26"
 #    endif
-#    if __cpp_lib_freestanding_cstring != 202306L
-#      error "__cpp_lib_freestanding_cstring should have the value 202306L in c++26"
+#    if __cpp_lib_freestanding_cstring != 202307L
+#      error "__cpp_lib_freestanding_cstring should have the value 202307L in c++26"
 #    endif
 #  else
 #    ifdef __cpp_lib_freestanding_cstring
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 8cb2ff11b0bf4..04d2720ae6dc2 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -615,7 +615,8 @@ def add_version_header(tc):
         {
             "name": "__cpp_lib_freestanding_cstring",
             "values": {
-                "c++26": 202306  # P2338R4 Freestanding Library: Character primitives and the C library
+                "c++26": 202307  # P2937R0 Freestanding: Remove strtok
+                # 		 202306	 # P2338R4 Freestanding Library: Character primitives and the C library
                 #        202311  # P2407R5 Freestanding Library: Partial Classes
             },
             "headers": ["cstring"],
@@ -1473,11 +1474,6 @@ def add_version_header(tc):
             "values": {"c++17": 201411},
             "headers": ["type_traits"],
         },
-		{
-			"name": "__cpp_lib_freestanding_cstring",
-			"values": {"c++26": 202306},
-			"headers": ["cstring"],
-		}
     ]
 ]
 

>From 0a330189a5900a7533f9fd5cc570046ce855e7f7 Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 12:27:20 +0300
Subject: [PATCH 13/13] [libcxx] remove the macro condition in <cstring>

---
 libcxx/include/cstring | 2 --
 1 file changed, 2 deletions(-)

diff --git a/libcxx/include/cstring b/libcxx/include/cstring
index 8ebe9dc6a10fa..5570df680f027 100644
--- a/libcxx/include/cstring
+++ b/libcxx/include/cstring
@@ -97,9 +97,7 @@ using ::strpbrk _LIBCPP_USING_IF_EXISTS;
 using ::strrchr _LIBCPP_USING_IF_EXISTS;
 using ::strspn _LIBCPP_USING_IF_EXISTS;
 using ::strstr _LIBCPP_USING_IF_EXISTS;
-#if __STDC_HOSTED__ == 1 || _LIBCPP_STD_VER < 26
 using ::strtok _LIBCPP_USING_IF_EXISTS;
-#endif
 using ::memset _LIBCPP_USING_IF_EXISTS;
 using ::strerror _LIBCPP_USING_IF_EXISTS;
 using ::strlen _LIBCPP_USING_IF_EXISTS;



More information about the libcxx-commits mailing list