This is an archive of the discontinued LLVM Phabricator instance.

[libcxx] [test] Don't assert that moved-from containers with non-POCMA allocators are empty.
ClosedPublic

Authored by BillyONeal on May 1 2019, 12:04 AM.

Details

Summary

The standard only requires that moved-from standard library types are in a 'valid but unspecified state', not that any moved-from container is empty. When the container is using a POCMA allocator, asserting that the moved-from container is empty is reasonable because the target container needs to take ownership of the memory buffers allocated from the source container's allocator. However, when the allocator is non-POCMA, the destination container must not take over any buffers, and effectively must copy the contents of the source container.

In the MSVC++ implementation, in this non-POCMA case, we do not clear() the source container, so that subsequent operations can reuse memory if the container is not immediately destroyed.

Diff Detail

Event Timeline

BillyONeal created this revision.May 1 2019, 12:04 AM
BillyONeal updated this revision to Diff 197653.May 1 2019, 3:13 PM

Also fixed vector<bool> test.

EricWF accepted this revision.May 14 2019, 2:42 PM

I'm not sure I agree with your design decision, but this patch LGTM.

Are you not allowed to move the containers elements in this case?

This revision is now accepted and ready to land.May 14 2019, 2:42 PM

I'm not sure I agree with your design decision, but this patch LGTM.

I wouldn't object to a standards change to make this the case; though it is suboptimal to destroy all the elements needlessly.

Are you not allowed to move the containers elements in this case?

Correct. The allocator is not POCMA and not equal, so it's functionally the same as doing assign(make_move_iterator(begin()), make_move_iterator(end())).

Billy3

Are you not allowed to move the containers elements in this case?

Correct. The allocator is not POCMA and not equal, so it's functionally the same as doing assign(make_move_iterator(begin()), make_move_iterator(end())).

In case the clarification helps some reader: When the allocator is not-POCMA-and-not-equal, then you are forbidden to pilfer the pointer from the source container, but you are indeed allowed to move the elements, and that's what Billy is describing. You could finish by having the source container destroy all its elements (those elements being now in a moved-from state) and become empty, but that's less efficient than keeping the moved-from elements around.

Unless of course you know that the element type is trivially relocatable... ;)

you are indeed allowed to move the elements

And indeed we *must* do that :).

Is there a reason this hasn't been committed?

Is there a reason this hasn't been committed?

Because it needs that one change Casey requested I was going to do that next time we take a libcxx test harness update, and I was hoping we'd get some closure on what happens with https://reviews.llvm.org/D61364 before doing that. Would you like me to expedite this change specifically?