[PATCH] D93510: Fix llvm::Optional build breaks in MSVC using std::is_trivially_copyable
David Blaikie via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 4 15:29:19 PST 2021
dblaikie added inline comments.
================
Comment at: llvm/include/llvm/ADT/Optional.h:36
/// Storage for any type.
-template <typename T, bool = is_trivially_copyable<T>::value>
+template <typename T, bool = std::is_trivially_copyable<T>::value
+ &&std::is_trivially_copy_constructible<T>::value
----------------
jplayer-nv wrote:
> dblaikie wrote:
> > jplayer-nv wrote:
> > > dblaikie wrote:
> > > > Is the "is_trivially_copyable" useful/necessary anymore? Would it be better to remove it (perhaps we need "is_trivially_destructible" in its place)?
> > > Yes I think it is. It covers the `is_trivially_destructible` conditon, but it also covers non-trivial move assignment / constructor. Pretty sure in the case of a deleted move constructor / assignment, we would fall back to the copy constructor / assignment (so current conditions should be sufficient to avoid build break). At the same time, we want to honor any non-trivial move assignment / constructor that may exist.
> > Fair enough - so what would the fully expanded check look like? is_trivially_copy_constructible + is_trivially_copy_assignable + is_trivially_move_constructible + is_trivially_move_assignable + is_trivially_destructible? That might be more clear than as its written, even though it's more verbose.
> You don't need a class to be trivially movable or trivially move assignable in order to use the trivial `OptionalStorage` specialization. The move constructor / assignment can be deleted, and the compiler will fall back to the copy constructor / assignment.
>
> We just need to verify that the user hasn't specified a custom move constructor / assignment. This is perfectly captured by `is_trivially_copyable`. That is, if either the move constructor or assignment are deleted, they will not be "eligible" in the spec, and therefore will not disqualify the class from being trivially copyable.
>
> If we were to expand this out, I think it would look like:
> ```
> std::is_trivially_copy_constructible<T>::value
> && std::is_trivially_copy_assignable<T>::value
> && (!std::is_move_constructible<T>::value || std::is_trivially_move_constructible<T>::value)
> && (!std::is_move_assignable<T>::value || std::is_trivially_move_assignable<T>::value)
> ```
That doesn't sound quite right to me. If something isn't move constructible or isn't move assignable, wouldn't that break the places where Optional tries to move them?
> The move constructor / assignment can be deleted, and the compiler will fall back to the copy constructor / assignment.
I don't think that's quite right - if something has an explicitly deleted move constructor, it'll be "!std::is_move_constructible" and move construction expressions will fail to compile, like this: https://godbolt.org/z/36xfb7
So I think your proposed expansion is equivalent to:
```
std::is_trivially_copy_constructible<T>::value
&& std::is_trivially_copy_assignable<T>::value
&& std::is_trivially_move_constructible<T>::value
&& std::is_trivially_move_assignable<T>::value
```
Which seems like it might be nice to have it written out that way?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D93510/new/
https://reviews.llvm.org/D93510
More information about the llvm-commits
mailing list