This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Allow __move_constexpr to work with unrelated pointers
ClosedPublic

Authored by philnik on Dec 18 2021, 1:48 AM.

Details

Summary

Allow __move_constexpr to work with unrelated pointers and _LIBCPP_ASSERT that __copy_constexpr, __move_constexpr and __assign_constexpr are only run during constant evaluation

Diff Detail

Event Timeline

philnik requested review of this revision.Dec 18 2021, 1:48 AM
philnik created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptDec 18 2021, 1:48 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript

FWIW, I'm a little leery of how we're making these codepaths more and more complicated. If it wouldn't merge-conflict horribly with the "constexpr std::string" stuff, I would be very tempted to take a close look at all of these codepaths and see how they could be simplified.
For example, __copy_constexpr is an overload set: there's a __copy_constexpr(T*, T*, size_t) here in <__string> but also a __copy_constexpr(In, In, Out) in <__algorithm/copy.h> (which is tied up with all the __unwrap_iter/__rewrap_iter stuff). We don't need that overload set to exist.
For example, __assign_constexpr and this overload of __copy_constexpr are one-liners; they could probably just be inlined into their three callers.

Orthogonally, consider renaming __s1 and __s2 to __src and __dest respectively (or vice versa).

Orthogonally, I wonder if we're 100% sure that constexpr new and delete (as used here) are fully supported in Clang 13. Libc++ 14 will still have to work with Clang 13.

Feel free to change the __{copy, move, assign}_constexpr functions, as long as you make char_traits::move work with unrelated pointers. They aren't used directly in <string>, so I should be able to just drop the changes in <__string>.

ldionne requested changes to this revision.Dec 20 2021, 7:57 AM

What do you mean "with unrelated pointers"? Can you explain what breaks when you use std::copy to implement __move_constexpr?

This revision now requires changes to proceed.Dec 20 2021, 7:57 AM

What do you mean "with unrelated pointers"? Can you explain what breaks when you use std::copy to implement __move_constexpr?

The problem isn't std::copy. The problem is __s1 < __s2, which only works if you have two pointers that were derived by __s2 = __s1 + c. Otherwise the constant evaluator will fail, because there is no rule to determine which pointer is larger.

ldionne accepted this revision.Dec 20 2021, 9:04 AM

As @Quuxplusone mentions, I would really support an effort to clean up our various __foo_constexpr functions.

LGTM with the renaming.

libcxx/include/__string
293

__s1 and __s2 is super confusing, especially since the order is reversed from std::copy_n. Please apply this throughout as a fly-by.

295–297

This is pretty annoying -- if we ever end up calling this function outside of constexpr (by mistake or otherwise), we'll end up with an assertion that fails at runtime. I don't see a way to make this fail at compile-time, since if you use __libcpp_is_constant_evaluated() in a place where a constant expression is required, it'll always return true. There's nothing actionable to this comment, but I thought I'd point out that this is a pretty bad defect of is_constant_evaluated().

This revision is now accepted and ready to land.Dec 20 2021, 9:04 AM
philnik updated this revision to Diff 395623.Dec 21 2021, 2:24 AM
philnik marked an inline comment as done.
  • renamed