[libcxx-commits] [libcxx] [libc++] Fix thread::id stream buffer size for signed thread ids (PR #234683)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Oct 22 09:46:03 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: divya7926
<details>
<summary>Changes</summary>
When printing a `thread::id` with `operator<<`, the buffer size was
`digits10 + 2`. This leaves room for the digits and the `'\0'`, but not
for a `'-'` sign.
On platforms where the thread id is a signed number (for example
`pthread_t` is `long` on Android Bionic), large negative ids do not fit
in the buffer. Then `__to_chars_integral` fails and the hardening
assertion `to_chars failed!` fires.
This adds one extra byte when the type is signed, using
`numeric_limits<__int_type>::is_signed`. Unsigned types (Linux, Apple)
get the same buffer size as the befor
`std::format` is not affected, because the formatter in
`__thread/formatter.h` uses `__format_integer`, which already handles
negative values
`__thread/support/windows.h` also uses a signed `long` for the
thread id, so this can affect windows in principle
-> Testing
- Existing tests in `libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id`
pass, both normally and with `--param hardening_mode=debug`.
- I could not add a regression test, because on Linux `pthread_t` is
unsigned and the `__thread_id` constructor that takes a raw value is
private, so a test cannot easily create a negative id.. I checked the
buffer size logic separately with a small program using `int32_t` and
`int64_t` minimum values. If anyone would like a test in a
particular form.would be happy to add.
Fixes #<!-- -->228441
---
Full diff: https://github.com/llvm/llvm-project/pull/234683.diff
1 Files Affected:
- (modified) libcxx/include/__thread/thread.h (+2-1)
``````````diff
diff --git a/libcxx/include/__thread/thread.h b/libcxx/include/__thread/thread.h
index 750a2d2a59ce72..1bbb657b3f68d0 100644
--- a/libcxx/include/__thread/thread.h
+++ b/libcxx/include/__thread/thread.h
@@ -154,7 +154,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) {
using __int_type = __conditional_t<is_pointer<__libcpp_thread_id>::value, uintptr_t, __libcpp_thread_id>;
- static const size_t __buffer_size = numeric_limits<__int_type>::digits10 + 2;
+ static const size_t __buffer_size =
+ numeric_limits<__int_type>::digits10 + 2 + numeric_limits<__int_type>::is_signed;
char __buffer[__buffer_size];
auto __ret =
std::__to_chars_integral(__buffer, __buffer + __buffer_size - 1, reinterpret_cast<__int_type>(__id.__id_), 10);
``````````
</details>
https://github.com/llvm/llvm-project/pull/234683
More information about the libcxx-commits
mailing list