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.