This is an archive of the discontinued LLVM Phabricator instance.

[libc++] ADL-proof <vector> by adding _VSTD:: qualification on calls.
ClosedPublic

Authored by Quuxplusone on Nov 18 2020, 6:45 AM.

Diff Detail

Event Timeline

Herald added a project: Restricted Project. · View Herald TranscriptNov 18 2020, 6:45 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
Quuxplusone requested review of this revision.Nov 18 2020, 6:45 AM
ldionne accepted this revision.Nov 18 2020, 7:46 AM

Please commit once CI passes. Thanks!

This revision is now accepted and ready to land.Nov 18 2020, 7:46 AM

Sorry, @ldionne, I've got a better test now, and more proposed _VSTDs!

I hacked my local "test_allocator.h" to use this "AdlTrap" trick, and discovered a few more places where ADL calls were being made. I don't propose to commit the test_allocator stuff, because a container using such an allocator breaks all ADL calls, including simple stuff like vec1 == vec2. But it was a fun experiment!

I have this as three commits locally; should I land them as three commits, or as one commit?

commit 57f653ea4d12d97d3a352df253425763da803486 (HEAD -> add-vstd)
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date:   Wed Nov 18 09:00:56 2020 -0500

    [libc++] Add some more missing _VSTD:: to <vector>, with a regression test.
    
    This is cleanup after d9a4f936d05.
    
    Note that a vector whose allocator runs afoul of the unqualified code here, will
    likely also run afoul of simple things like `v1 == v2` (which is also an ADL call).
    
    Relevant blog post: https://quuxplusone.github.io/blog/2019/09/26/uglification-doesnt-stop-adl/
    
    Differential Revision: https://reviews.llvm.org/D91708

commit 53b5db385145ba924db3a0d5d41758e22c288f46
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date:   Wed Nov 18 18:39:14 2020 -0500

    [libc++] Add _VSTD:: qualification to __swap_allocator.
    
    Relevant blog post: https://quuxplusone.github.io/blog/2019/09/26/uglification-doesnt-stop-adl/
    
    Differential Revision: https://reviews.llvm.org/D91708

commit 915d293f0fd6a73dd8daa90b7df5f66d81b54ddd
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date:   Wed Nov 18 18:54:38 2020 -0500

    [libc++] Add _VSTD:: qualification consistently to __to_address.
    
    Relevant blog post: https://quuxplusone.github.io/blog/2019/09/26/uglification-doesnt-stop-adl/
    
    Differential Revision: https://reviews.llvm.org/D91708
ldionne accepted this revision.Nov 19 2020, 4:39 AM

Sorry, @ldionne, I've got a better test now, and more proposed _VSTDs!

I hacked my local "test_allocator.h" to use this "AdlTrap" trick, and discovered a few more places where ADL calls were being made. I don't propose to commit the test_allocator stuff, because a container using such an allocator breaks all ADL calls, including simple stuff like vec1 == vec2. But it was a fun experiment!

I have this as three commits locally; should I land them as three commits, or as one commit?

As you wish. If it were me I might squash them since they are strongly related, but it's as you see fit.

This revision was landed with ongoing or failed builds.Nov 19 2020, 6:19 AM
This revision was automatically updated to reflect the committed changes.

My change to __swap_allocators was bad. Define the helper templates before the template that uses them. (Before, two-phase lookup was letting us get away with the unqualified call. With the qualified call, buildbots were not happy.)

Quuxplusone reopened this revision.Nov 19 2020, 7:59 AM
This revision is now accepted and ready to land.Nov 19 2020, 7:59 AM
Quuxplusone retitled this revision from [libcxx] Add some missing _VSTD:: to <vector>, with a regression test. to [libc++] ADL-proof <vector> by adding _VSTD:: qualification on calls..

In my new test, v.swap(w) is not expected to work before C++14, because before C++14, there was some metaprogramming to make vector<T>::swap noexcept if-and-only-if the allocator was nothrow-swappable, which required looking up an ADL swap for the allocator type, which hit my ADL trap.

In C++14, vector<T>::swap is always noexcept, and so we don't have to look up an ADL swap (unless the allocator is POCS, which my test's MyAlloc is not), and therefore the test passes.

I admit that there is a plausible argument to be made that my new test is too "whitebox" and "overconstrained" and shouldn't even be checked in.

Disable the new test for C++03. It was either that, or add a max_size() member function to MyAlloc.

I see now that when Harbormaster says "Harbormaster completed remote builds in B79288: Diff 306093." with a little green checkmark next to it, that little green checkmark does not mean that the remote build actually succeeded and passed all the tests! It means that the (possibly failing) build results are available to view.

Indeed. This is the thing you want to be looking at:

ldionne accepted this revision.Nov 19 2020, 12:35 PM

Re-updating the patch, as now I'm super paranoid about seeing the tests pass. No (intended) changes since the last update. I'll watch for the buildkite run to be green and then land this.