This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Fixes thread::id's operator<<.
ClosedPublic

Authored by Mordante on Jun 20 2023, 6:25 AM.

Details

Reviewers
ldionne
Group Reviewers
Restricted Project
Commits
rG1c1edd1b5d00: [libc++] Fixes thread::id's operator<<.
Summary

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

Diff Detail

Event Timeline

Mordante created this revision.Jun 20 2023, 6:25 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 20 2023, 6:25 AM
Mordante updated this revision to Diff 532917.Jun 20 2023, 7:22 AM

CI fixes.

Mordante updated this revision to Diff 532934.Jun 20 2023, 7:54 AM

Fixes C++03 compatibility of the test.

Mordante added inline comments.
libcxx/include/__thread/thread.h
133–158

@ldionne This fails with localization disabled. To old operator<< would also fail but was not "removed" when localization was disabled. I can put to old code in the #else branch, but I wonder whether that is useful.

Note that we normally not comment out operator<<. Maybe we can discuss whether we should do that. I expect it "works" in our tests since they are disabled and these operators are templated on the _CharT of the basic_ostream thus not instantiated automatically.

Mordante published this revision for review.Jun 21 2023, 3:46 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 21 2023, 3:46 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
ldionne added inline comments.Jul 4 2023, 12:55 PM
libcxx/include/__thread/thread.h
28

Is there any reason why we need <ios> and not just <iosfwd>? It would be really nice to try to avoid including <ios> from here since that's kind of a heavy header (especially with backward compatibility transitive includes enabled).

133–158

I think you did the right thing in this patch. These operator<< should be #ifdef'd out, and if they are not then it's just an oversight that happens not to trigger any issue. We probably forward declare basic_ostream somewhere and it all "works" as long as you don't actually instantiate the operator<<.

152–153

I don't understand that sentence. Do you mean that fill, align and width can or can't affect the data in the stream?

155–157
168–184

Is it ever possible for a thread id to be a negative number? If not, am I right that this isn't required?

JMazurkiewicz added inline comments.
libcxx/include/__thread/thread.h
186

Should we should use C locale while printing? Values from std::numpunct (thousands_sep and grouping) may affect text representation when type of __id.__id_ is integral.

I've mentioned it in this issue too: https://github.com/llvm/llvm-project/issues/62073.

Mordante marked 5 inline comments as done.Jul 8 2023, 5:43 AM
Mordante added inline comments.
libcxx/include/__thread/thread.h
28

Good point, I need locale too. However adding these two headers does not change the transitive includes.

152–153

They can since they affect text.

168–184

I don't know, depends on what the platform does.

186

Good point, I overlooked the locale part in the bug report. I already felt the original patch was a bit ugly saving and restoring locale seems even worse. Instead of that approach I now create a new stream in a known state with a known locale and output that stream. This might be a bit more expensive, but I don't expect people not to try to use logging unconditionally in expensive parts of their code.

Mordante updated this revision to Diff 538360.Jul 8 2023, 5:55 AM
Mordante marked 4 inline comments as done.

Addresses review comments.

ldionne accepted this revision.Jul 11 2023, 10:51 AM

Thanks for fixing this! LGTM w/ comments applied and green CI. Also make sure to rebase cause I made some changes to __thread/.

libcxx/include/__thread/thread.h
137

I think this whole comment could actually be changed to:

// [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.
161
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
84–85
This revision is now accepted and ready to land.Jul 11 2023, 10:51 AM
Mordante updated this revision to Diff 540090.Jul 13 2023, 9:49 AM

Rebased and addresses review comments.

Mordante marked 2 inline comments as done.Jul 13 2023, 9:55 AM

Thanks for fixing this! LGTM w/ comments applied and green CI. Also make sure to rebase cause I made some changes to __thread/.

The rebase when smooth not git issues, however is it intended that thread::id's operator<< is moved to the id.h header?

This revision was automatically updated to reflect the committed changes.
Mordante added inline comments.Jul 15 2023, 7:31 AM
libcxx/include/__thread/thread.h
28

@ldionne it seems there were additional includes needed after all.