summaryrefslogtreecommitdiff
path: root/libcxx/include/__thread
diff options
context:
space:
mode:
authorMark de Wever <koraq@xs4all.nl>2023-06-02 11:25:50 +0200
committerMark de Wever <koraq@xs4all.nl>2023-07-15 11:52:19 +0200
commit1c1edd1b5d00daae2efdfbc5754a9fae77597dd4 (patch)
tree54458931bd17d2c4657005333cd5f205ebf2fd39 /libcxx/include/__thread
parent4675a3261e53edef772932debd8a05eb8ccb61b9 (diff)
[libc++] Fixes thread::id's operator<<.
The output of template<class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& out, thread::id id); is affected by the state of out. The wording states [thread.thread.id]/2 The text representation for the character type charT of an object of type thread::id is an unspecified sequence of charT such that, for two objects of type thread::id x and y, if x == y is true, the thread::id objects have the same text representation, and if x != y is true, the thread::id objects have distinct text representations. [thread.thread.id]/9 template<class charT, class traits> basic_ostream<charT, traits>& operator<< (basic_ostream<charT, traits>& out, thread::id id); Effects: Inserts the text representation for charT of id into out. This wording changed in C++23 due to adding a formatter specialization for thread::id. However the requirement was the same in older versions of C++. This issue is that thread::id is an integral or pointer and affected by the formatting manipulators for them. Thus the text representation can differ if x == y which violates the requirements. The fix has to hard-code some formatting style for the text representation. It uses the Standard specified default values Table 124: basic_ios::init() effects [tab:basic.ios.cons] flags() flags() skipws | dec Fixes PR: https://llvm.org/PR62073 Reviewed By: #libc, ldionne Differential Revision: https://reviews.llvm.org/D153336
Diffstat (limited to 'libcxx/include/__thread')
-rw-r--r--libcxx/include/__thread/thread.h35
1 files changed, 30 insertions, 5 deletions
diff --git a/libcxx/include/__thread/thread.h b/libcxx/include/__thread/thread.h
index 3d52d87f7026..dec40c7dc1f0 100644
--- a/libcxx/include/__thread/thread.h
+++ b/libcxx/include/__thread/thread.h
@@ -24,6 +24,10 @@
#include <iosfwd>
#include <tuple>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+# include <locale>
+#endif
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
@@ -126,11 +130,32 @@ struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>
}
};
-template<class _CharT, class _Traits>
-_LIBCPP_INLINE_VISIBILITY
-basic_ostream<_CharT, _Traits>&
-operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id)
-{return __os << __id.__id_;}
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+template <class _CharT, class _Traits>
+_LIBCPP_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) {
+ // [thread.thread.id]/9
+ // Effects: Inserts the text representation for charT of id into out.
+ //
+ // [thread.thread.id]/2
+ // The text representation for the character type charT of an
+ // object of type thread::id is an unspecified sequence of charT
+ // such that, for two objects of type thread::id x and y, if
+ // x == y is true, the thread::id objects have the same text
+ // representation, and if x != y is true, the thread::id objects
+ // have distinct text representations.
+ //
+ // Since various flags in the output stream can affect how the
+ // thread id is represented (e.g. numpunct or showbase), we
+ // use a temporary stream instead and just output the thread
+ // id representation as a string.
+
+ basic_ostringstream<_CharT, _Traits> __sstr;
+ __sstr.imbue(locale::classic());
+ __sstr << __id.__id_;
+ return __os << __sstr.str();
+}
+#endif // _LIBCPP_HAS_NO_LOCALIZATION
class _LIBCPP_EXPORTED_FROM_ABI thread
{