This is an archive of the discontinued LLVM Phabricator instance.

[libc++] [P0966] [C++20] Fix bug PR45368 by correctly implementing P0966: string::reserve should not shrink.
ClosedPublic

Authored by curdeius on Nov 19 2020, 2:42 AM.

Details

Summary

This patch fixes the implementation as well as the tests that didn't actually test the wanted behaviour.
You'll find all the details in the bug report.
It adds as well deprecation warning for reserve() (without argument) and adds a test.

http://wg21.link/P0966R1
https://bugs.llvm.org/show_bug.cgi?id=45368
https://reviews.llvm.org/D54992

Diff Detail

Event Timeline

curdeius created this revision.Nov 19 2020, 2:42 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 19 2020, 2:42 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
curdeius requested review of this revision.Nov 19 2020, 2:42 AM
curdeius updated this revision to Diff 306355.Nov 19 2020, 2:48 AM

Oops. Remove spurious _NOEXCEPT.

FYI, the code handling reallocation etc. that was previously in reserve hasn't been modified, only moved to __shrink_or_extend for reuse.

Again, this change needs the use of C++20 when building libc++, because there are instantiations for char.

curdeius updated this revision to Diff 306399.Nov 19 2020, 6:38 AM

Rebase on top of D91691.

curdeius updated this revision to Diff 306971.Nov 23 2020, 12:42 AM

Rebase to rerun tests

Ready for review!
On BuildKite there are some failures on Apple, but 3/4 concern libcxx/modules/stds_include.sh.cpp which seems (very) flaky.
The fourth one (on Apple back-deployment macosx10.9) looks severe, but I suspect that it doesn't compile src/ with -std=c++20 flag, and so uses instantiation of basic_string<char> as of C++17.

I think I understood the problem with failing Apple back-deployment macosx10.9... I took a look at libcxx/utils/ci/run-buildbot that it invokes. It's not going to work in pre-merge test, because it uses libc++ binaries that it downloads from http://lab.llvm.org:8080/roots/libcxx-roots.tar.gz (obviously not compiled with changes from this patch).
@ldionne, any idea how this should be addressed?

ldionne requested changes to this revision.Nov 24 2020, 7:57 AM

I think I understood the problem with failing Apple back-deployment macosx10.9... I took a look at libcxx/utils/ci/run-buildbot that it invokes. It's not going to work in pre-merge test, because it uses libc++ binaries that it downloads from http://lab.llvm.org:8080/roots/libcxx-roots.tar.gz (obviously not compiled with changes from this patch).
@ldionne, any idea how this should be addressed?

The usual way of handling these test failures caused by a bug being fixed in the dylib is to mark the tests as XFAIL based on the system library being used. The following should work:

// This test relies on https://llvm.org/PR45368 being fixed, which isn't in
// older Apple dylibs
// 
// XFAIL: with_system_cxx_lib=macosx10.15
// XFAIL: with_system_cxx_lib=macosx10.14
// XFAIL: with_system_cxx_lib=macosx10.13
// XFAIL: with_system_cxx_lib=macosx10.12
// XFAIL: with_system_cxx_lib=macosx10.11
// XFAIL: with_system_cxx_lib=macosx10.10
// XFAIL: with_system_cxx_lib=macosx10.9

Regarding the other failures, they do seem flaky indeed. We need to figure out what's wrong with those modules related tests.

libcxx/include/string
3268

I'd be in favour of renaming this to something like __requested_capacity.

3289

Using something like __target_capacity here would convey more IMO.

libcxx/test/std/strings/basic.string/string.capacity/reserve_size.pass.cpp
29

Is there a reason why you're not checking invariants anymore?

libcxx/www/cxx2a_status.html
266 ↗(On Diff #306971)

Typo!

This revision now requires changes to proceed.Nov 24 2020, 7:57 AM
curdeius retitled this revision from [libc++] [C++20] [P0966] Fix bug PR45368 by correctly implementing P0966: string::reserve should not shrink. to [libc++] [P0966] [C++20] Fix bug PR45368 by correctly implementing P0966: string::reserve should not shrink..Nov 24 2020, 11:13 PM
curdeius updated this revision to Diff 307531.Nov 25 2020, 12:31 AM
  • Fix typo and use permalink.
  • Check invariants.
  • Rename.
  • Mark test with XFAIL for macOS.
curdeius marked 4 inline comments as done.Nov 25 2020, 12:32 AM
curdeius added inline comments.
libcxx/test/std/strings/basic.string/string.capacity/reserve_size.pass.cpp
29

I just moved the test for reserve() (without size argument) to the file reserve.pass.cpp and it still checks invariants.
This test (for reserve(size)) didn't check invariants, but I can add it in this test, that seems judicious.

ldionne accepted this revision.Nov 25 2020, 12:11 PM
This revision is now accepted and ready to land.Nov 25 2020, 12:11 PM
This revision was automatically updated to reflect the committed changes.
curdeius marked an inline comment as done.
rsmith added a subscriber: rsmith.Feb 9 2021, 4:41 PM
rsmith added inline comments.
libcxx/include/string
3273–3276

This #if doesn't seem to work: because reserve(size_type) is not inline, we always use the version from the libc++ library, which means we get the C++17 behavior if the library was built in C++17 mode, and we get the C++20 behavior if the library was built in C++20 mode, regardless of the standard mode used by the compilation using libc++.

ldionne added inline comments.Feb 10 2021, 8:52 AM
libcxx/include/string
3273–3276

Oh crap, that's right. Nice catch. But I'm not seeing a way to fix this except to make this function inline, and to keep a definition in the dylib for backwards compatibility (but nobody except already-compiled code would call it). Do you see other ways?

rsmith added inline comments.Feb 10 2021, 1:20 PM
libcxx/include/string
3273–3276

If we could somehow split it into two functions for C++17 and C++20 calls, that might work.

In principle, if we could rely on concepts in C++20 mode, then I think that making the "never shrinks" C++20 overload be requires true + inline and leaving the C++17 version unconstrained and non-inline should do the trick with no ABI impact. But that doesn't compile in Clang and crashes GCC: https://godbolt.org/z/3WEKMa -- looks like neither compiler properly mangles constrained functions yet.

So how about something like this: https://godbolt.org/z/M69EP1

rsmith added inline comments.Jan 12 2022, 4:07 PM
libcxx/include/string
3273–3276

Looks like this was landed without fixing this problem. See https://github.com/llvm/llvm-project/issues/53170