This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Define ostream nullptr inserter for >= C++17 only
ClosedPublic

Authored by jloser on Jun 3 2022, 4:10 PM.

Details

Summary

The ostream nullptr inserter implemented in 3c125fe is missing a C++ version
guard. Normally, libc++ takes the stance of backporting LWG issues to older
standards modes as was done in 3c125fe. However, backporting to older standards
modes breaks existing code in popular libraries such as Boost.Test and
Google Test who define their own overload for nullptr_t.

Instead, only apply this operator<< overload in C++17 or later.

Fixes https://github.com/llvm/llvm-project/issues/55861.

Diff Detail

Event Timeline

jloser created this revision.Jun 3 2022, 4:10 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 3 2022, 4:10 PM
jloser requested review of this revision.Jun 3 2022, 4:10 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 3 2022, 4:10 PM
Herald added a reviewer: Restricted Project. · View Herald Transcript
lichray accepted this revision.Jun 3 2022, 4:22 PM
Mordante added 1 blocking reviewer(s): ldionne.Jun 5 2022, 4:43 AM

I see both MSVC STL and libstdc++ have taken the approach to only accept this overload in C++17 and later.
However our general policy is to retro-actively apply LWG issues to older versions of the Standard.
@ldionne what's your opinion?

ldionne requested changes to this revision.Jun 7 2022, 7:02 AM
ldionne added subscribers: jwakely, STL_MSFT.

Normally, we do apply LWG issues retroactively, so I wouldn't change this. @jwakely @STL_MSFT Any insight as to why your respective standard libraries guarded this with C++17?

This revision now requires changes to proceed.Jun 7 2022, 7:02 AM
jwakely added a comment.EditedJun 7 2022, 7:30 AM

Normally, we do apply LWG issues retroactively, so I wouldn't change this. @jwakely @STL_MSFT Any insight as to why your respective standard libraries guarded this with C++17?

I don't remember, sorry. I'm not sure we actually ever discussed that aspect, we spent far more time discussing the content of the NTBS it prints.

Personally, I don't think this should really have been handled as a library issue. It's more of a new feature, like "Printing volatile Pointers" https://wg21.link/p1147r1. And since I'm not aware of anybody actually caring about this feature, I haven't spent much time thinking/caring about it.

If users were requesting it in C++11 and C++14 modes I'd consider enabling it, but I don't think anybody has asked for that.

jwakely added a comment.EditedJun 7 2022, 7:40 AM

I've done some digging. It looks like ostream support for nullptr_t was discussed in August 2011 (thread beginning at c++std-lib-30987) and the outcome was "not a defect, wait for a new standard". That supports my feeling that it never should have been handled as a library issue.

Also, Billy O'Neal reported that the new overload caused ambiguities for some morally questionable code in Google Test, which was trying to define its own overload for this type. Breaking existing code (even if it's bad code) is another reason to not enable it unconditionally. I guess that's no longer an issue, or somebody would have noticed it when using gtest and libc++!

It seems like the only known uses for this operator<< are in Boost.Test, Google Test, and Mozilla's assertion macros ... so I super don't care about it.

lichray added a comment.EditedJun 7 2022, 10:24 AM

Also, Billy O'Neal reported that the new overload caused ambiguities for some morally questionable code in Google Test, which was trying to define it's own overload for this type. Breaking existing code (even if it's bad code) is another reason to not enable it unconditionally. I guess that's no longer an issue, or somebody would have noticed it when using gtest and libc++!

It seems like the only known uses for this operator<< are in Boost.Test, Google Test, and Mozilla's assertion macros ... so I super don't care about it.

I filed https://github.com/llvm/llvm-project/issues/55861 because of a breakage found in Symantec's test code (a header we own added a conflicting overload). I'm requesting the new overload *not* be added to old versions of C++, for portability's sake.

Yep, the Google Test impact was indeed why MSVC's STL had to guard this for C++17 mode (as our default and oldest mode is C++14).

Still pending @ldionne's approval, but based on the feedback I think we should do this. But please add the requested comments. (That will avoid us trying to backport this again in the future.)

libcxx/include/ostream
228

Please add comment this is LWG 2221 and add a rationale why this isn't backported, a link to this review suffices.

libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters/streambuf.pass.cpp
70

Please add comment that this LWG-issue isn't backported.

ldionne accepted this revision.Jul 19 2022, 7:03 AM

LGTM w/ comments applied.

Thanks a lot @jwakely for the additional information.

libcxx/include/ostream
228

+1

This revision is now accepted and ready to land.Jul 19 2022, 7:03 AM
jloser updated this revision to Diff 445886.Jul 19 2022, 11:10 AM
jloser edited the summary of this revision. (Show Details)

Add comment about LWG 2221 not being backported.
Update commit message to provide brief rationale.

If CI passes, I'll ship this.

Mordante accepted this revision.Jul 19 2022, 12:51 PM

Add comment about LWG 2221 not being backported.
Update commit message to provide brief rationale.

Thanks, LGTM!