cjdb created this revision.
cjdb added a reviewer: aaron.ballman.
Herald added a project: All.
cjdb requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

- `__is_move_constructible`
- `__is_nothrow_move_constructible`
- `__is_trivially_move_constructible`

This is information that the compiler already has, and should be exposed
so that the library doesn't need to reimplement the exact same
functionality.

Unlike their default-constructible cousins, the move-constructible
traits can't be implemented using `__is_constructible`, etc., because we
can't form references to `void`, and references are a fundamental part
of move constructors.

This was originally a part of D116280 <https://reviews.llvm.org/D116280>.

Depends on D135239 <https://reviews.llvm.org/D135239>.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D135240

Files:
  clang/include/clang/Basic/TokenKinds.def
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/SemaCXX/deprecated-builtins.cpp
  clang/test/SemaCXX/type-traits.cpp

Index: clang/test/SemaCXX/type-traits.cpp
===================================================================
--- clang/test/SemaCXX/type-traits.cpp
+++ clang/test/SemaCXX/type-traits.cpp
@@ -2865,6 +2865,409 @@
   static_assert(!__is_trivially_copy_constructible(void()), "");
 }
 
+struct ConstMoveCtor {
+  ConstMoveCtor(const ConstMoveCtor &&);
+};
+
+struct VolatileMoveCtor {
+  VolatileMoveCtor(volatile VolatileMoveCtor &&);
+};
+
+struct CVMoveCtor {
+  CVMoveCtor(const volatile CVMoveCtor &&);
+};
+
+struct MoveCtorDeleted {
+  MoveCtorDeleted(MoveCtorDeleted &&) = delete;
+};
+
+struct BaseDeletedMoveCtor : MoveCtorDeleted {};
+
+struct MemberDeletedMoveCtor {
+  MoveCtorDeleted x;
+};
+
+struct HasNothrowMoveCtor {
+  HasNothrowMoveCtor(HasNothrowMoveCtor&&) noexcept;
+};
+
+void move_constructible_checks() {
+  // Builtin types
+  static_assert(__is_move_constructible(int), "");
+  static_assert(__is_nothrow_move_constructible(int), "");
+  static_assert(__is_trivially_move_constructible(int), "");
+
+  static_assert(__is_move_constructible(const int), "");
+  static_assert(__is_nothrow_move_constructible(const int), "");
+  static_assert(__is_trivially_move_constructible(const int), "");
+
+  static_assert(__is_move_constructible(volatile int), "");
+  static_assert(__is_nothrow_move_constructible(volatile int), "");
+  static_assert(__is_trivially_move_constructible(volatile int), "");
+
+  static_assert(__is_move_constructible(const volatile int), "");
+  static_assert(__is_nothrow_move_constructible(const volatile int), "");
+  static_assert(__is_trivially_move_constructible(const volatile int), "");
+
+  static_assert(__is_move_constructible(int&), "");
+  static_assert(__is_nothrow_move_constructible(int&), "");
+  static_assert(__is_trivially_move_constructible(int&), "");
+
+  static_assert(__is_move_constructible(const int&), "");
+  static_assert(__is_nothrow_move_constructible(const int&), "");
+  static_assert(__is_trivially_move_constructible(const int&), "");
+
+  static_assert(__is_move_constructible(volatile int&), "");
+  static_assert(__is_nothrow_move_constructible(volatile int&), "");
+  static_assert(__is_trivially_move_constructible(volatile int&), "");
+
+  static_assert(__is_move_constructible(const volatile int&), "");
+  static_assert(__is_nothrow_move_constructible(const volatile int&), "");
+  static_assert(__is_trivially_move_constructible(const volatile int&), "");
+
+  static_assert(__is_move_constructible(int&&), "");
+  static_assert(__is_nothrow_move_constructible(int&&), "");
+  static_assert(__is_trivially_move_constructible(int&&), "");
+
+  static_assert(__is_move_constructible(const int&&), "");
+  static_assert(__is_nothrow_move_constructible(const int&&), "");
+  static_assert(__is_trivially_move_constructible(const int&&), "");
+
+  static_assert(__is_move_constructible(volatile int&&), "");
+  static_assert(__is_nothrow_move_constructible(volatile int&&), "");
+  static_assert(__is_trivially_move_constructible(volatile int&&), "");
+
+  static_assert(__is_move_constructible(const volatile int&&), "");
+  static_assert(__is_nothrow_move_constructible(const volatile int&&), "");
+  static_assert(__is_trivially_move_constructible(const volatile int&&), "");
+
+  static_assert(__is_move_constructible(int*), "");
+  static_assert(__is_nothrow_move_constructible(int*), "");
+  static_assert(__is_trivially_move_constructible(int*), "");
+
+  static_assert(__is_move_constructible(int* const), "");
+  static_assert(__is_nothrow_move_constructible(int* const), "");
+  static_assert(__is_trivially_move_constructible(int* const), "");
+
+  static_assert(__is_move_constructible(int* volatile), "");
+  static_assert(__is_nothrow_move_constructible(int* volatile), "");
+  static_assert(__is_trivially_move_constructible(int* volatile), "");
+
+  static_assert(__is_move_constructible(int* const volatile), "");
+  static_assert(__is_nothrow_move_constructible(int* const volatile), "");
+  static_assert(__is_trivially_move_constructible(int* const volatile), "");
+
+  static_assert(!__is_move_constructible(int[5]), "");
+  static_assert(!__is_nothrow_move_constructible(int[5]), "");
+  static_assert(!__is_trivially_move_constructible(int[5]), "");
+
+  static_assert(!__is_move_constructible(int[]), "");
+  static_assert(!__is_nothrow_move_constructible(int[]), "");
+  static_assert(!__is_trivially_move_constructible(int[]), "");
+
+  static_assert(__is_move_constructible(decltype(nullptr)), "");
+  static_assert(__is_nothrow_move_constructible(decltype(nullptr)), "");
+  static_assert(__is_trivially_move_constructible(decltype(nullptr)), "");
+
+  static_assert(__is_move_constructible(void (*)()), "");
+  static_assert(__is_nothrow_move_constructible(void (*)()), "");
+  static_assert(__is_trivially_move_constructible(void (*)()), "");
+
+  static_assert(__is_move_constructible(void (&)()), "");
+  static_assert(__is_nothrow_move_constructible(void (&)()), "");
+  static_assert(__is_trivially_move_constructible(void (&)()), "");
+
+  static_assert(__is_move_constructible(int Empty::*), "");
+  static_assert(__is_nothrow_move_constructible(int Empty::*), "");
+  static_assert(__is_trivially_move_constructible(int Empty::*), "");
+
+  // // User-defined types
+  static_assert(__is_move_constructible(AllDefaulted), "");
+  static_assert(__is_nothrow_move_constructible(AllDefaulted), "");
+  static_assert(__is_trivially_move_constructible(AllDefaulted), "");
+
+  static_assert(__is_move_constructible(const AllDefaulted), "");
+  static_assert(__is_nothrow_move_constructible(const AllDefaulted), "");
+  static_assert(__is_trivially_move_constructible(const AllDefaulted), "");
+
+  static_assert(!__is_move_constructible(volatile AllDefaulted), "");
+  static_assert(!__is_nothrow_move_constructible(volatile AllDefaulted), "");
+  static_assert(!__is_trivially_move_constructible(volatile AllDefaulted), "");
+
+  static_assert(!__is_move_constructible(const volatile AllDefaulted), "");
+  static_assert(!__is_nothrow_move_constructible(const volatile AllDefaulted), "");
+  static_assert(!__is_trivially_move_constructible(const volatile AllDefaulted), "");
+
+  static_assert(__is_move_constructible(CEmptyStruct), "");
+  static_assert(__is_nothrow_move_constructible(CEmptyStruct), "");
+  static_assert(__is_trivially_move_constructible(CEmptyStruct), "");
+
+  static_assert(__is_move_constructible(ConstMoveCtor), "");
+  static_assert(!__is_nothrow_move_constructible(ConstMoveCtor), "");
+  static_assert(!__is_trivially_move_constructible(ConstMoveCtor), "");
+
+  static_assert(__is_move_constructible(CppEmptyStruct), "");
+  static_assert(__is_nothrow_move_constructible(CppEmptyStruct), "");
+  static_assert(__is_trivially_move_constructible(CppEmptyStruct), "");
+
+  static_assert(__is_move_constructible(CppStructNonStandardBy2ndVirtBase), "");
+  static_assert(__is_nothrow_move_constructible(CppStructNonStandardBy2ndVirtBase), "");
+  static_assert(__is_trivially_move_constructible(CppStructNonStandardBy2ndVirtBase), "");
+
+  static_assert(__is_move_constructible(CppStructNonStandardByBase), "");
+  static_assert(__is_nothrow_move_constructible(CppStructNonStandardByBase), "");
+  static_assert(__is_trivially_move_constructible(CppStructNonStandardByBase), "");
+
+  static_assert(__is_move_constructible(CppStructNonStandardByMemb), "");
+  static_assert(__is_nothrow_move_constructible(CppStructNonStandardByMemb), "");
+  static_assert(!__is_trivially_move_constructible(CppStructNonStandardByMemb), "");
+
+  static_assert(__is_move_constructible(CppStructNonStandardByProt), "");
+  static_assert(__is_nothrow_move_constructible(CppStructNonStandardByProt), "");
+  static_assert(__is_trivially_move_constructible(CppStructNonStandardByProt), "");
+
+  static_assert(__is_move_constructible(CppStructNonStandardBySameBase), "");
+  static_assert(__is_nothrow_move_constructible(CppStructNonStandardBySameBase), "");
+  static_assert(__is_trivially_move_constructible(CppStructNonStandardBySameBase), "");
+
+  static_assert(__is_move_constructible(CppStructNonStandardByVirt), "");
+  static_assert(__is_nothrow_move_constructible(CppStructNonStandardByVirt), "");
+  static_assert(!__is_trivially_move_constructible(CppStructNonStandardByVirt), "");
+
+  static_assert(__is_move_constructible(CppStructNonStandardByVirtBase), "");
+  static_assert(__is_nothrow_move_constructible(CppStructNonStandardByVirtBase), "");
+  static_assert(!__is_trivially_move_constructible(CppStructNonStandardByVirtBase), "");
+
+  static_assert(__is_move_constructible(CppStructStandard), "");
+  static_assert(__is_nothrow_move_constructible(CppStructStandard), "");
+  static_assert(__is_trivially_move_constructible(CppStructStandard), "");
+
+  static_assert(__is_move_constructible(CStruct), "");
+  static_assert(__is_nothrow_move_constructible(CStruct), "");
+  static_assert(__is_trivially_move_constructible(CStruct), "");
+
+  static_assert(__is_move_constructible(CVMoveCtor), "");
+  static_assert(!__is_nothrow_move_constructible(CVMoveCtor), "");
+  static_assert(!__is_trivially_move_constructible(CVMoveCtor), "");
+
+  static_assert(__is_move_constructible(Derives), "");
+  static_assert(__is_nothrow_move_constructible(Derives), "");
+  static_assert(__is_trivially_move_constructible(Derives), "");
+
+  static_assert(__is_move_constructible(DerivesHasRef), "");
+  static_assert(__is_nothrow_move_constructible(DerivesHasRef), "");
+  static_assert(__is_trivially_move_constructible(DerivesHasRef), "");
+
+  static_assert(__is_move_constructible(Empty), "");
+  static_assert(__is_nothrow_move_constructible(Empty), "");
+  static_assert(__is_trivially_move_constructible(Empty), "");
+
+  static_assert(__is_move_constructible(EmptyUnion), "");
+  static_assert(__is_nothrow_move_constructible(EmptyUnion), "");
+  static_assert(__is_trivially_move_constructible(EmptyUnion), "");
+
+  static_assert(__is_move_constructible(Enum), "");
+  static_assert(__is_nothrow_move_constructible(Enum), "");
+  static_assert(__is_trivially_move_constructible(Enum), "");
+
+  static_assert(__is_move_constructible(const Enum), "");
+  static_assert(__is_nothrow_move_constructible(const Enum), "");
+  static_assert(__is_trivially_move_constructible(const Enum), "");
+
+  static_assert(__is_move_constructible(volatile Enum), "");
+  static_assert(__is_nothrow_move_constructible(volatile Enum), "");
+  static_assert(__is_trivially_move_constructible(volatile Enum), "");
+
+  static_assert(__is_move_constructible(const volatile Enum), "");
+  static_assert(__is_nothrow_move_constructible(const volatile Enum), "");
+  static_assert(__is_trivially_move_constructible(const volatile Enum), "");
+
+  static_assert(__is_move_constructible(EnumClass), "");
+  static_assert(__is_nothrow_move_constructible(EnumClass), "");
+  static_assert(__is_trivially_move_constructible(EnumClass), "");
+
+  static_assert(__is_move_constructible(const EnumClass), "");
+  static_assert(__is_nothrow_move_constructible(const EnumClass), "");
+  static_assert(__is_trivially_move_constructible(const EnumClass), "");
+
+  static_assert(__is_move_constructible(volatile EnumClass), "");
+  static_assert(__is_nothrow_move_constructible(volatile EnumClass), "");
+  static_assert(__is_trivially_move_constructible(volatile EnumClass), "");
+
+  static_assert(__is_move_constructible(const volatile EnumClass), "");
+  static_assert(__is_nothrow_move_constructible(const volatile EnumClass), "");
+  static_assert(__is_trivially_move_constructible(const volatile EnumClass), "");
+
+  static_assert(__is_move_constructible(ExtDefaulted), "");
+  static_assert(!__is_nothrow_move_constructible(ExtDefaulted), "");
+  static_assert(!__is_trivially_move_constructible(ExtDefaulted), "");
+
+  static_assert(__is_move_constructible(HasCons), "");
+  static_assert(__is_nothrow_move_constructible(HasCons), "");
+  static_assert(__is_trivially_move_constructible(HasCons), "");
+
+  static_assert(__is_move_constructible(HasCopyAssign), "");
+  static_assert(__is_nothrow_move_constructible(HasCopyAssign), "");
+  static_assert(__is_trivially_move_constructible(HasCopyAssign), "");
+
+  static_assert(__is_move_constructible(HasDest), "");
+  static_assert(__is_nothrow_move_constructible(HasDest), "");
+  static_assert(!__is_trivially_move_constructible(HasDest), "");
+
+  static_assert(__is_move_constructible(HasMove), "");
+  static_assert(!__is_nothrow_move_constructible(HasMove), "");
+  static_assert(!__is_trivially_move_constructible(HasMove), "");
+
+  static_assert(__is_move_constructible(HasPriv), "");
+  static_assert(__is_nothrow_move_constructible(HasPriv), "");
+  static_assert(__is_trivially_move_constructible(HasPriv), "");
+
+  static_assert(__is_move_constructible(HasRef), "");
+  static_assert(__is_nothrow_move_constructible(HasRef), "");
+  static_assert(__is_trivially_move_constructible(HasRef), "");
+
+  static_assert(__is_move_constructible(HasTemplateCons), "");
+  static_assert(__is_nothrow_move_constructible(HasTemplateCons), "");
+  static_assert(!__is_trivially_move_constructible(HasTemplateCons), "");
+
+  static_assert(__is_move_constructible(NoDefaultMoveAssignDueToDtor), "");
+  static_assert(__is_nothrow_move_constructible(NoDefaultMoveAssignDueToDtor), "");
+  static_assert(!__is_trivially_move_constructible(NoDefaultMoveAssignDueToDtor), "");
+
+  static_assert(__is_move_constructible(NoDefaultMoveAssignDueToUDCopyAssign), "");
+  static_assert(__is_nothrow_move_constructible(NoDefaultMoveAssignDueToUDCopyAssign), "");
+  static_assert(__is_trivially_move_constructible(NoDefaultMoveAssignDueToUDCopyAssign), "");
+
+  static_assert(__is_move_constructible(NoDefaultMoveAssignDueToUDCopyCtor), "");
+  static_assert(!__is_nothrow_move_constructible(NoDefaultMoveAssignDueToUDCopyCtor), "");
+  static_assert(!__is_trivially_move_constructible(NoDefaultMoveAssignDueToUDCopyCtor), "");
+
+  static_assert(__is_move_constructible(NonTCStruct), "");
+  static_assert(!__is_nothrow_move_constructible(NonTCStruct), "");
+  static_assert(!__is_trivially_move_constructible(NonTCStruct), "");
+
+  static_assert(__is_move_constructible(NonTrivialStruct), "");
+  static_assert(__is_nothrow_move_constructible(NonTrivialStruct), "");
+  static_assert(__is_trivially_move_constructible(NonTrivialStruct), "");
+
+  static_assert(__is_move_constructible(POD), "");
+  static_assert(__is_nothrow_move_constructible(POD), "");
+  static_assert(__is_trivially_move_constructible(POD), "");
+
+  static_assert(__is_move_constructible(SuperNonTrivialStruct), "");
+  static_assert(__is_nothrow_move_constructible(SuperNonTrivialStruct), "");
+  static_assert(!__is_trivially_move_constructible(SuperNonTrivialStruct), "");
+
+  static_assert(__is_move_constructible(TrivialStruct), "");
+  static_assert(__is_nothrow_move_constructible(TrivialStruct), "");
+  static_assert(__is_trivially_move_constructible(TrivialStruct), "");
+
+  static_assert(__is_move_constructible(Union), "");
+  static_assert(__is_nothrow_move_constructible(Union), "");
+  static_assert(__is_trivially_move_constructible(Union), "");
+
+  static_assert(__is_move_constructible(HasNothrowMoveCtor), "");
+  static_assert(__is_nothrow_move_constructible(HasNothrowMoveCtor), "");
+  static_assert(!__is_trivially_move_constructible(HasNothrowMoveCtor), "");
+
+  static_assert(__is_move_constructible(VolatileMoveCtor), "");
+  static_assert(!__is_nothrow_move_constructible(VolatileMoveCtor), "");
+  static_assert(!__is_trivially_move_constructible(VolatileMoveCtor), "");
+
+  static_assert(!__is_move_constructible(const VolatileMoveCtor), "");
+  static_assert(!__is_nothrow_move_constructible(const VolatileMoveCtor), "");
+  static_assert(!__is_trivially_move_constructible(const VolatileMoveCtor), "");
+
+  static_assert(__is_move_constructible(volatile VolatileMoveCtor), "");
+  static_assert(!__is_nothrow_move_constructible(volatile VolatileMoveCtor), "");
+  static_assert(!__is_trivially_move_constructible(volatile VolatileMoveCtor), "");
+
+  static_assert(!__is_move_constructible(const volatile VolatileMoveCtor), "");
+  static_assert(!__is_nothrow_move_constructible(const volatile VolatileMoveCtor), "");
+  static_assert(!__is_trivially_move_constructible(const volatile VolatileMoveCtor), "");
+
+  static_assert(!__is_move_constructible(AllDeleted), "");
+  static_assert(!__is_nothrow_move_constructible(AllDeleted), "");
+  static_assert(!__is_trivially_move_constructible(AllDeleted), "");
+
+  static_assert(!__is_move_constructible(AllPrivate), "");
+  static_assert(!__is_nothrow_move_constructible(AllPrivate), "");
+  static_assert(!__is_trivially_move_constructible(AllPrivate), "");
+
+  static_assert(!__is_move_constructible(AnIncompleteType[]), "");
+  static_assert(!__is_nothrow_move_constructible(AnIncompleteType[]), "");
+  static_assert(!__is_trivially_move_constructible(AnIncompleteType[]), "");
+
+  static_assert(!__is_move_constructible(AnIncompleteType), ""); // expected-error{{incomplete type}}
+  static_assert(!__is_nothrow_move_constructible(AnIncompleteType), ""); // expected-error{{incomplete type}}
+  static_assert(!__is_trivially_move_constructible(AnIncompleteType), ""); // expected-error{{incomplete type}}
+
+  static_assert(!__is_move_constructible(BaseDeletedCopyCtor), "");
+  static_assert(!__is_nothrow_move_constructible(BaseDeletedCopyCtor), "");
+  static_assert(!__is_trivially_move_constructible(BaseDeletedCopyCtor), "");
+
+  static_assert(!__is_move_constructible(BaseDeletedCopyCtor), "");
+  static_assert(!__is_nothrow_move_constructible(BaseDeletedCopyCtor), "");
+  static_assert(!__is_trivially_move_constructible(BaseDeletedCopyCtor), "");
+
+  static_assert(!__is_move_constructible(BaseDeletedMoveCtor), "");
+  static_assert(!__is_nothrow_move_constructible(BaseDeletedMoveCtor), "");
+  static_assert(!__is_trivially_move_constructible(BaseDeletedMoveCtor), "");
+
+  static_assert(!__is_move_constructible(CopyCtorDeleted), "");
+  static_assert(!__is_nothrow_move_constructible(CopyCtorDeleted), "");
+  static_assert(!__is_trivially_move_constructible(CopyCtorDeleted), "");
+
+  static_assert(!__is_move_constructible(CopyCtorDeleted), "");
+  static_assert(!__is_nothrow_move_constructible(CopyCtorDeleted), "");
+  static_assert(!__is_trivially_move_constructible(CopyCtorDeleted), "");
+
+  static_assert(!__is_move_constructible(CVCopyCtor), "");
+  static_assert(!__is_nothrow_move_constructible(CVCopyCtor), "");
+  static_assert(!__is_trivially_move_constructible(CVCopyCtor), "");
+
+  static_assert(!__is_move_constructible(HasMutableCopyCtor), "");
+  static_assert(!__is_nothrow_move_constructible(HasMutableCopyCtor), "");
+  static_assert(!__is_trivially_move_constructible(HasMutableCopyCtor), "");
+
+  static_assert(!__is_move_constructible(HasMoveAssign), "");
+  static_assert(!__is_nothrow_move_constructible(HasMoveAssign), "");
+  static_assert(!__is_trivially_move_constructible(HasMoveAssign), "");
+
+  static_assert(!__is_move_constructible(MemberDeletedCopyCtor), "");
+  static_assert(!__is_nothrow_move_constructible(MemberDeletedCopyCtor), "");
+  static_assert(!__is_trivially_move_constructible(MemberDeletedCopyCtor), "");
+
+  static_assert(!__is_move_constructible(MemberDeletedCopyCtor), "");
+  static_assert(!__is_nothrow_move_constructible(MemberDeletedCopyCtor), "");
+  static_assert(!__is_trivially_move_constructible(MemberDeletedCopyCtor), "");
+
+  static_assert(!__is_move_constructible(MemberDeletedMoveCtor), "");
+  static_assert(!__is_nothrow_move_constructible(MemberDeletedMoveCtor), "");
+  static_assert(!__is_trivially_move_constructible(MemberDeletedMoveCtor), "");
+
+  static_assert(!__is_move_constructible(MoveCtorDeleted), "");
+  static_assert(!__is_nothrow_move_constructible(MoveCtorDeleted), "");
+  static_assert(!__is_trivially_move_constructible(MoveCtorDeleted), "");
+
+  static_assert(!__is_move_constructible(VirtAr), "");
+  static_assert(!__is_nothrow_move_constructible(VirtAr), "");
+  static_assert(!__is_trivially_move_constructible(VirtAr), "");
+
+  static_assert(!__is_move_constructible(VolatileCopyCtor), "");
+  static_assert(!__is_nothrow_move_constructible(VolatileCopyCtor), "");
+  static_assert(!__is_trivially_move_constructible(VolatileCopyCtor), "");
+
+  // Non-referencable types
+  static_assert(!__is_move_constructible(void), "");
+  static_assert(!__is_nothrow_move_constructible(void), "");
+  static_assert(!__is_trivially_move_constructible(void), "");
+
+  static_assert(!__is_move_constructible(void()), "");
+  static_assert(!__is_nothrow_move_constructible(void()), "");
+  static_assert(!__is_trivially_move_constructible(void()), "");
+}
+
 struct MutableCopyAssign_QualNone {
   MutableCopyAssign_QualNone &operator=(MutableCopyAssign_QualNone &);
 };
Index: clang/test/SemaCXX/deprecated-builtins.cpp
===================================================================
--- clang/test/SemaCXX/deprecated-builtins.cpp
+++ clang/test/SemaCXX/deprecated-builtins.cpp
@@ -13,7 +13,7 @@
     a = __has_trivial_move_assign(A);  // expected-warning-re {{__has_trivial_move_assign {{.*}} use __is_trivially_assignable}}
     a = __has_trivial_copy(A);  // expected-warning-re {{__has_trivial_copy {{.*}} use __is_trivially_copy_constructible}}
     a = __has_trivial_constructor(A);  // expected-warning-re {{__has_trivial_constructor {{.*}} use __is_trivially_constructible}}
-    a = __has_trivial_move_constructor(A);  // expected-warning-re {{__has_trivial_move_constructor {{.*}} use __is_trivially_constructible}}
+    a = __has_trivial_move_constructor(A);  // expected-warning-re {{__has_trivial_move_constructor {{.*}} use __is_trivially_move_constructible}}
     a = __has_trivial_destructor(A);  // expected-warning-re {{__has_trivial_destructor {{.*}} use __is_trivially_destructible}}
 
 }
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -4854,6 +4854,9 @@
   case UTT_IsCopyAssignable:
   case UTT_IsTriviallyCopyAssignable:
   case UTT_IsNothrowCopyAssignable:
+  case UTT_IsMoveConstructible:
+  case UTT_IsTriviallyMoveConstructible:
+  case UTT_IsNothrowMoveConstructible:
     if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType())
       return true;
 
@@ -5351,6 +5354,25 @@
                                  : TT_IsNothrowConstructible,
                              KeyLoc, Parameters, {});
   }
+  case UTT_IsMoveConstructible:
+  case UTT_IsTriviallyMoveConstructible:
+  case UTT_IsNothrowMoveConstructible: {
+    if (T->isIncompleteArrayType())
+      return false;
+    if (!T.isReferenceable())
+      return false;
+
+    QualType AssigneeType = Self.BuiltinAddReference(
+        T, UnaryTransformType::AddRvalueReference, KeyLoc);
+    llvm::SmallVector<TypeSourceInfo *, 2> Parameters = {
+        C.CreateTypeSourceInfo(T), C.CreateTypeSourceInfo(AssigneeType)};
+    return evaluateTypeTrait(Self,
+                             UTT == UTT_IsMoveConstructible ? TT_IsConstructible
+                             : UTT == UTT_IsTriviallyMoveConstructible
+                                 ? TT_IsTriviallyConstructible
+                                 : TT_IsNothrowConstructible,
+                             KeyLoc, Parameters, {});
+  }
   case UTT_IsReferenceable:
     return T.isReferenceable();
   }
@@ -5506,9 +5528,11 @@
     Replacement = UTT_IsTriviallyCopyConstructible;
     break;
   case UTT_HasTrivialDefaultConstructor:
-  case UTT_HasTrivialMoveConstructor:
     Replacement = TT_IsTriviallyConstructible;
     break;
+  case UTT_HasTrivialMoveConstructor:
+    Replacement = UTT_IsTriviallyMoveConstructible;
+    break;
   case UTT_HasTrivialDestructor:
     Replacement = UTT_IsTriviallyDestructible;
     break;
Index: clang/lib/Parse/ParseExpr.cpp
===================================================================
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -1093,10 +1093,12 @@
           REVERTIBLE_TYPE_TRAIT(__is_member_function_pointer);
           REVERTIBLE_TYPE_TRAIT(__is_member_object_pointer);
           REVERTIBLE_TYPE_TRAIT(__is_member_pointer);
+          REVERTIBLE_TYPE_TRAIT(__is_move_constructible);
           REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable);
           REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible);
           REVERTIBLE_TYPE_TRAIT(__is_nothrow_copy_assignable);
           REVERTIBLE_TYPE_TRAIT(__is_nothrow_copy_constructible);
+          REVERTIBLE_TYPE_TRAIT(__is_nothrow_move_constructible);
           REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible);
           REVERTIBLE_TYPE_TRAIT(__is_nullptr);
           REVERTIBLE_TYPE_TRAIT(__is_object);
@@ -1119,6 +1121,7 @@
           REVERTIBLE_TYPE_TRAIT(__is_trivially_copy_assignable);
           REVERTIBLE_TYPE_TRAIT(__is_trivially_copy_constructible);
           REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable);
+          REVERTIBLE_TYPE_TRAIT(__is_trivially_move_constructible);
           REVERTIBLE_TYPE_TRAIT(__is_unbounded_array);
           REVERTIBLE_TYPE_TRAIT(__is_union);
           REVERTIBLE_TYPE_TRAIT(__is_unsigned);
Index: clang/lib/Parse/ParseDeclCXX.cpp
===================================================================
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -1604,11 +1604,13 @@
           tok::kw___is_member_function_pointer,
           tok::kw___is_member_object_pointer,
           tok::kw___is_member_pointer,
+          tok::kw___is_move_constructible,
           tok::kw___is_nothrow_assignable,
           tok::kw___is_nothrow_constructible,
           tok::kw___is_nothrow_copy_assignable,
           tok::kw___is_nothrow_copy_constructible,
           tok::kw___is_nothrow_destructible,
+          tok::kw___is_nothrow_move_constructible,
           tok::kw___is_nullptr,
           tok::kw___is_object,
           tok::kw___is_pod,
@@ -1630,6 +1632,7 @@
           tok::kw___is_trivially_copy_assignable,
           tok::kw___is_trivially_copy_constructible,
           tok::kw___is_trivially_copyable,
+          tok::kw___is_trivially_move_constructible,
           tok::kw___is_unbounded_array,
           tok::kw___is_union,
           tok::kw___is_unsigned,
Index: clang/include/clang/Basic/TokenKinds.def
===================================================================
--- clang/include/clang/Basic/TokenKinds.def
+++ clang/include/clang/Basic/TokenKinds.def
@@ -530,6 +530,9 @@
 TYPE_TRAIT_1(__is_nothrow_copy_assignable, IsNothrowCopyAssignable, KEYCXX)
 TYPE_TRAIT_1(__is_trivially_copy_assignable, IsTriviallyCopyAssignable, KEYCXX)
 TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
+TYPE_TRAIT_1(__is_move_constructible, IsMoveConstructible, KEYCXX)
+TYPE_TRAIT_1(__is_nothrow_move_constructible, IsNothrowMoveConstructible, KEYCXX)
+TYPE_TRAIT_1(__is_trivially_move_constructible, IsTriviallyMoveConstructible, KEYCXX)
 
 // Embarcadero Expression Traits
 EXPRESSION_TRAIT(__is_lvalue_expr, IsLValueExpr, KEYCXX)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D135240: [cla... Christopher Di Bella via Phabricator via cfe-commits

Reply via email to