This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Handle arrays in std::destroy_at
ClosedPublic

Authored by ldionne on Jul 27 2021, 2:15 PM.

Details

Reviewers
Quuxplusone
Group Reviewers
Restricted Project
Commits
rGc99f5b2af1fc: [libc++] Handle arrays in std::destroy_at
Summary

Also, improve tests for std::destroy and std::destroy_n so that they
check for array support.

These changes are part of http://wg21.link/p0896 (the One Ranges proposal).

Diff Detail

Event Timeline

ldionne requested review of this revision.Jul 27 2021, 2:15 PM
ldionne created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptJul 27 2021, 2:15 PM
Herald added a reviewer: Restricted Project. · View Herald Transcript
ldionne added inline comments.Jul 27 2021, 2:17 PM
libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp
127

This is pretty lame, but I couldn't find a way to test array support in constexpr mode before std::construct_at has support for arrays.

The problem is that we run into this kind of issue:

libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp:132:19: error: static_assert expression is not an integral constant expression
    static_assert(test());
                  ^~~~~~
build/default/include/c++/v1/__memory/construct_at.h:40:12: note: construction of subobject of object outside its lifetime is not allowed in a constant expression
    return ::new ((void*)__location) _Tp(_VSTD::forward<_Args>(__args)...);
           ^
build/default/include/c++/v1/__memory/allocator_traits.h:298:9: note: in call to 'construct_at(&{*new Counted [5][3]#2}[0][0], &counter)'
        _VSTD::construct_at(__p, _VSTD::forward<_Args>(__args)...);
        ^

If std::construct_at had support for arrays, we'd create the array using it and that would do the trick. As it is, I'm not sure how to work around it.

Quuxplusone requested changes to this revision.Jul 27 2021, 8:04 PM
Quuxplusone added a subscriber: Quuxplusone.
Quuxplusone added inline comments.
libcxx/include/__memory/construct_at.h
61

Instead of using this class = void hack, could you just use

template <class _Tp, _EnableIf<!is_array_v<_Tp>, int> = 0>

in the first case and

template <class _Tp, _EnableIf<is_array_v<_Tp>, int> = 0>

in the second case?

libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp
131–134

I'd prefer to wrap each offending block in an if:

if (!std::is_constant_evaluated()) {
    using Array = Counted[3];
    ...
}
if (!std::is_constant_evaluated()) {
    using Array = Counted[3][2];
    ...
}

That way if someone adds to the end of the function, it won't get accidentally nerfed.
Alternatively, probably even better: pull the offending blocks out into a separate function, bool test_arrays(), and just don't test it in constexpr mode yet.

This revision now requires changes to proceed.Jul 27 2021, 8:04 PM
ldionne marked 2 inline comments as done.Jul 28 2021, 7:44 AM
ldionne added inline comments.
libcxx/include/__memory/construct_at.h
61

Indeed. For some reason I've never liked that trick, but it's not a rational preference. Switched.

ldionne updated this revision to Diff 362382.Jul 28 2021, 7:45 AM
ldionne marked an inline comment as done.

Address review comments

ldionne updated this revision to Diff 362465.Jul 28 2021, 11:13 AM

Fix C++17

Quuxplusone accepted this revision.Jul 29 2021, 2:19 PM
Quuxplusone added inline comments.
libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp
92

Could use just constexpr here if you want.

109

FWIW, in my most recent patch I've rekindled my love affair with

ASSERT_SAME_TYPE(decltype(std::destroy(pool, pool + 5)), void);
libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp
97–109

Not blocking, but it would be cleaner to factor these repeated blocks into template<class It> void test1() and then have the body of the top-level test() be just test1<Counted*>(); test1<forward_iterator<Counted*>>();
(Applies equally to all the tests touched in this PR, if you choose to do it at all.)

This revision is now accepted and ready to land.Jul 29 2021, 2:19 PM
ldionne updated this revision to Diff 363061.Jul 30 2021, 6:39 AM
ldionne marked 3 inline comments as done.

Apply review feedback (thanks).

This revision was landed with ongoing or failed builds.Jul 30 2021, 6:40 AM
This revision was automatically updated to reflect the committed changes.