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

- `__is_move_assignable`
- `__is_nothrow_move_assignable`
- `__is_trivially_move_assignable`

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.

Similarly to `__is_move_construcitble`, etc., these traits can't be
implemented using `__is_assignable`, etc., because we can't form
references to void, and references are a fundamental part of move
assignment.

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

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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D135338

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
@@ -3937,6 +3937,732 @@
   static_assert(!__is_trivially_copy_assignable(const volatile CVCopyAssign_QualCV), "");
 }
 
+struct MoveAssign_QualNone {
+  MoveAssign_QualNone &operator=(MoveAssign_QualNone &&);
+};
+struct MoveAssign_QualConst {
+  MoveAssign_QualConst &operator=(MoveAssign_QualConst &&) const;
+};
+struct MoveAssign_QualVolatile {
+  MoveAssign_QualVolatile &operator=(MoveAssign_QualVolatile &&) volatile;
+};
+struct MoveAssign_QualCV {
+  MoveAssign_QualCV &operator=(MoveAssign_QualCV &&) const volatile;
+};
+struct MoveAssign_QualLvalue {
+  MoveAssign_QualLvalue &operator=(MoveAssign_QualLvalue &&) &;
+};
+struct MoveAssign_QualConstLvalue {
+  MoveAssign_QualConstLvalue &operator=(MoveAssign_QualConstLvalue &&) const &;
+};
+struct MoveAssign_QualVolatileLvalue {
+  MoveAssign_QualVolatileLvalue &operator=(MoveAssign_QualVolatileLvalue &&) volatile &;
+};
+struct MoveAssign_QualCVLvalue {
+  MoveAssign_QualCVLvalue &operator=(MoveAssign_QualCVLvalue &&) const volatile &;
+};
+struct MoveAssign_QualRvalue {
+  MoveAssign_QualRvalue &operator=(MoveAssign_QualRvalue &&) &&;
+};
+struct MoveAssign_QualConstRvalue {
+  MoveAssign_QualConstRvalue &operator=(MoveAssign_QualConstRvalue &&) const &&;
+};
+struct MoveAssign_QualVolatileRvalue {
+  MoveAssign_QualVolatileRvalue &operator=(MoveAssign_QualVolatileRvalue &&) volatile &&;
+};
+struct MoveAssign_QualCVRvalue {
+  MoveAssign_QualCVRvalue &operator=(MoveAssign_QualCVRvalue &&) const volatile &&;
+};
+
+struct ConstMoveAssign_QualNone {
+  ConstMoveAssign_QualNone &operator=(const ConstMoveAssign_QualNone &&);
+};
+struct ConstMoveAssign_QualConst {
+  ConstMoveAssign_QualConst &operator=(const ConstMoveAssign_QualConst &&) const;
+};
+struct ConstMoveAssign_QualVolatile {
+  ConstMoveAssign_QualVolatile &operator=(const ConstMoveAssign_QualVolatile &&) volatile;
+};
+struct ConstMoveAssign_QualCV {
+  ConstMoveAssign_QualCV &operator=(const ConstMoveAssign_QualCV &&) const volatile;
+};
+struct ConstMoveAssign_QualLvalue {
+  ConstMoveAssign_QualLvalue &operator=(const ConstMoveAssign_QualLvalue &&) &;
+};
+struct ConstMoveAssign_QualConstLvalue {
+  ConstMoveAssign_QualConstLvalue &operator=(const ConstMoveAssign_QualConstLvalue &&) const &;
+};
+struct ConstMoveAssign_QualVolatileLvalue {
+  ConstMoveAssign_QualVolatileLvalue &operator=(const ConstMoveAssign_QualVolatileLvalue &&) volatile &;
+};
+struct ConstMoveAssign_QualCVLvalue {
+  ConstMoveAssign_QualCVLvalue &operator=(const ConstMoveAssign_QualCVLvalue &&) const volatile &;
+};
+struct ConstMoveAssign_QualRvalue {
+  ConstMoveAssign_QualRvalue &operator=(const ConstMoveAssign_QualRvalue &&) &&;
+};
+struct ConstMoveAssign_QualConstRvalue {
+  ConstMoveAssign_QualConstRvalue &operator=(const ConstMoveAssign_QualConstRvalue &&) const &&;
+};
+struct ConstMoveAssign_QualVolatileRvalue {
+  ConstMoveAssign_QualVolatileRvalue &operator=(const ConstMoveAssign_QualVolatileRvalue &&) volatile &&;
+};
+struct ConstMoveAssign_QualCVRvalue {
+  ConstMoveAssign_QualCVRvalue &operator=(const ConstMoveAssign_QualCVRvalue &&) const volatile &&;
+};
+
+struct VolatileMoveAssign_QualNone {
+  VolatileMoveAssign_QualNone &operator=(volatile VolatileMoveAssign_QualNone &&);
+};
+struct VolatileMoveAssign_QualConst {
+  VolatileMoveAssign_QualConst &operator=(volatile VolatileMoveAssign_QualConst &&) const;
+};
+struct VolatileMoveAssign_QualVolatile {
+  VolatileMoveAssign_QualVolatile &operator=(volatile VolatileMoveAssign_QualVolatile &&) volatile;
+};
+struct VolatileMoveAssign_QualCV {
+  VolatileMoveAssign_QualCV &operator=(volatile VolatileMoveAssign_QualCV &&) const volatile;
+};
+struct VolatileMoveAssign_QualLvalue {
+  VolatileMoveAssign_QualLvalue &operator=(volatile VolatileMoveAssign_QualLvalue &&) &;
+};
+struct VolatileMoveAssign_QualConstLvalue {
+  VolatileMoveAssign_QualConstLvalue &operator=(volatile VolatileMoveAssign_QualConstLvalue &&) const &;
+};
+struct VolatileMoveAssign_QualVolatileLvalue {
+  VolatileMoveAssign_QualVolatileLvalue &operator=(volatile VolatileMoveAssign_QualVolatileLvalue &&) volatile &;
+};
+struct VolatileMoveAssign_QualCVLvalue {
+  VolatileMoveAssign_QualCVLvalue &operator=(volatile VolatileMoveAssign_QualCVLvalue &&) const volatile &;
+};
+struct VolatileMoveAssign_QualRvalue {
+  VolatileMoveAssign_QualRvalue &operator=(volatile VolatileMoveAssign_QualRvalue &&) &&;
+};
+struct VolatileMoveAssign_QualConstRvalue {
+  VolatileMoveAssign_QualConstRvalue &operator=(volatile VolatileMoveAssign_QualConstRvalue &&) const &&;
+};
+struct VolatileMoveAssign_QualVolatileRvalue {
+  VolatileMoveAssign_QualVolatileRvalue &operator=(volatile VolatileMoveAssign_QualVolatileRvalue &&) volatile &&;
+};
+struct VolatileMoveAssign_QualCVRvalue {
+  VolatileMoveAssign_QualCVRvalue &operator=(volatile VolatileMoveAssign_QualCVRvalue &&) const volatile &&;
+};
+
+struct CVMoveAssign_QualNone {
+  CVMoveAssign_QualNone &operator=(const volatile CVMoveAssign_QualNone &&);
+};
+struct CVMoveAssign_QualConst {
+  CVMoveAssign_QualConst &operator=(const volatile CVMoveAssign_QualConst &&) const;
+};
+struct CVMoveAssign_QualVolatile {
+  CVMoveAssign_QualVolatile &operator=(const volatile CVMoveAssign_QualVolatile &&) volatile;
+};
+struct CVMoveAssign_QualCV {
+  CVMoveAssign_QualCV &operator=(const volatile CVMoveAssign_QualCV &&) const volatile;
+};
+struct CVMoveAssign_QualLvalue {
+  CVMoveAssign_QualLvalue &operator=(const volatile CVMoveAssign_QualLvalue &&) &;
+};
+struct CVMoveAssign_QualConstLvalue {
+  CVMoveAssign_QualConstLvalue &operator=(const volatile CVMoveAssign_QualConstLvalue &&) const &;
+};
+struct CVMoveAssign_QualCVLvalue {
+  CVMoveAssign_QualCVLvalue &operator=(const volatile CVMoveAssign_QualCVLvalue &&) volatile &;
+};
+struct CVMoveAssign_QualVolatileLvalue {
+  CVMoveAssign_QualVolatileLvalue &operator=(const volatile CVMoveAssign_QualVolatileLvalue &&) const volatile &;
+};
+struct CVMoveAssign_QualRvalue {
+  CVMoveAssign_QualRvalue &operator=(const volatile CVMoveAssign_QualRvalue &&) &&;
+};
+struct CVMoveAssign_QualConstRvalue {
+  CVMoveAssign_QualConstRvalue &operator=(const volatile CVMoveAssign_QualConstRvalue &&) const &&;
+};
+struct CVMoveAssign_QualVolatileRvalue {
+  CVMoveAssign_QualVolatileRvalue &operator=(const volatile CVMoveAssign_QualVolatileRvalue &&) volatile &&;
+};
+struct CVMoveAssign_QualCVRvalue {
+  CVMoveAssign_QualCVRvalue &operator=(const volatile CVMoveAssign_QualCVRvalue &&) const volatile &&;
+};
+struct MoveAssignDeleted {
+  MoveAssignDeleted &operator=(const MoveAssignDeleted &&) = delete;
+};
+struct BaseDeletedMoveAssign : MoveAssignDeleted {};
+struct HasMemberWithDeletedMoveAssign {
+  MoveAssignDeleted x;
+};
+
+void move_assignable_checks() {
+  // Builtin types
+  static_assert(__is_move_assignable(int), "");
+  static_assert(__is_nothrow_move_assignable(int), "");
+  static_assert(__is_trivially_move_assignable(int), "");
+
+  static_assert(__is_move_assignable(int &), "");
+  static_assert(__is_nothrow_move_assignable(int &), "");
+  static_assert(__is_trivially_move_assignable(int &), "");
+
+  static_assert(__is_move_assignable(int &&), "");
+  static_assert(__is_nothrow_move_assignable(int &&), "");
+  static_assert(__is_trivially_move_assignable(int &&), "");
+
+  static_assert(__is_move_assignable(int *), "");
+  static_assert(__is_nothrow_move_assignable(int *), "");
+  static_assert(__is_trivially_move_assignable(int *), "");
+
+  static_assert(!__is_move_assignable(int[5]), "");
+  static_assert(!__is_nothrow_move_assignable(int[5]), "");
+  static_assert(!__is_trivially_move_assignable(int[5]), "");
+
+  static_assert(!__is_move_assignable(int[]), "");
+  static_assert(!__is_nothrow_move_assignable(int[]), "");
+  static_assert(!__is_trivially_move_assignable(int[]), "");
+
+  static_assert(__is_move_assignable(decltype(nullptr)), "");
+  static_assert(__is_nothrow_move_assignable(decltype(nullptr)), "");
+  static_assert(__is_trivially_move_assignable(decltype(nullptr)), "");
+
+  static_assert(__is_move_assignable(void (*)()), "");
+  static_assert(__is_nothrow_move_assignable(void (*)()), "");
+  static_assert(__is_trivially_move_assignable(void (*)()), "");
+
+  static_assert(!__is_move_assignable(void (&)()), "");
+  static_assert(!__is_nothrow_move_assignable(void (&)()), "");
+  static_assert(!__is_trivially_move_assignable(void (&)()), "");
+
+  static_assert(__is_move_assignable(int Empty::*), "");
+  static_assert(__is_nothrow_move_assignable(int Empty::*), "");
+  static_assert(__is_trivially_move_assignable(int Empty::*), "");
+
+  static_assert(__is_move_assignable(int(Empty::*)()), "");
+  static_assert(__is_nothrow_move_assignable(int(Empty::*)()), "");
+  static_assert(__is_trivially_move_assignable(int(Empty::*)()), "");
+
+  static_assert(__is_move_assignable(int(Empty::*)() const), "");
+  static_assert(__is_nothrow_move_assignable(int(Empty::*)() const), "");
+  static_assert(__is_trivially_move_assignable(int(Empty::*)() const), "");
+
+  static_assert(__is_move_assignable(int(Empty::*)() volatile), "");
+  static_assert(__is_nothrow_move_assignable(int(Empty::*)() volatile), "");
+  static_assert(__is_trivially_move_assignable(int(Empty::*)() volatile), "");
+
+  static_assert(__is_move_assignable(int(Empty::*)() const volatile), "");
+  static_assert(__is_nothrow_move_assignable(int(Empty::*)() const volatile), "");
+  static_assert(__is_trivially_move_assignable(int(Empty::*)() const volatile), "");
+
+  static_assert(__is_move_assignable(int(Empty::*)() &), "");
+  static_assert(__is_nothrow_move_assignable(int(Empty::*)() &), "");
+  static_assert(__is_trivially_move_assignable(int(Empty::*)() &), "");
+
+  static_assert(__is_move_assignable(int(Empty::*)() const &), "");
+  static_assert(__is_nothrow_move_assignable(int(Empty::*)() const &), "");
+  static_assert(__is_trivially_move_assignable(int(Empty::*)() const &), "");
+
+  static_assert(__is_move_assignable(int(Empty::*)() volatile &), "");
+  static_assert(__is_nothrow_move_assignable(int(Empty::*)() volatile &), "");
+  static_assert(__is_trivially_move_assignable(int(Empty::*)() volatile &), "");
+
+  static_assert(__is_move_assignable(int(Empty::*)() const volatile &), "");
+  static_assert(__is_nothrow_move_assignable(int(Empty::*)() const volatile &), "");
+  static_assert(__is_trivially_move_assignable(int(Empty::*)() const volatile &), "");
+
+  static_assert(__is_move_assignable(int(Empty::*)() &&), "");
+  static_assert(__is_nothrow_move_assignable(int(Empty::*)() &&), "");
+  static_assert(__is_trivially_move_assignable(int(Empty::*)() &&), "");
+
+  static_assert(__is_move_assignable(int(Empty::*)() const &&), "");
+  static_assert(__is_nothrow_move_assignable(int(Empty::*)() const &&), "");
+  static_assert(__is_trivially_move_assignable(int(Empty::*)() const &&), "");
+
+  static_assert(__is_move_assignable(int(Empty::*)() volatile &&), "");
+  static_assert(__is_nothrow_move_assignable(int(Empty::*)() volatile &&), "");
+  static_assert(__is_trivially_move_assignable(int(Empty::*)() volatile &&), "");
+
+  static_assert(__is_move_assignable(int(Empty::*)() const volatile &&), "");
+  static_assert(__is_nothrow_move_assignable(int(Empty::*)() const volatile &&), "");
+  static_assert(__is_trivially_move_assignable(int(Empty::*)() const volatile &&), "");
+
+  // // User-defined types
+  static_assert(__is_move_assignable(AllDefaulted), "");
+  static_assert(__is_nothrow_move_assignable(AllDefaulted), "");
+  static_assert(__is_trivially_move_assignable(AllDefaulted), "");
+
+  static_assert(__is_move_assignable(BaseDeletedCopyCtor), "");
+  static_assert(__is_nothrow_move_assignable(BaseDeletedCopyCtor), "");
+  static_assert(__is_trivially_move_assignable(BaseDeletedCopyCtor), "");
+
+  static_assert(__is_move_assignable(CEmptyStruct), "");
+  static_assert(__is_nothrow_move_assignable(CEmptyStruct), "");
+  static_assert(__is_trivially_move_assignable(CEmptyStruct), "");
+
+  static_assert(__is_move_assignable(CopyCtorDeleted), "");
+  static_assert(__is_nothrow_move_assignable(CopyCtorDeleted), "");
+  static_assert(__is_trivially_move_assignable(CopyCtorDeleted), "");
+
+  static_assert(__is_move_assignable(CppEmptyStruct), "");
+  static_assert(__is_nothrow_move_assignable(CppEmptyStruct), "");
+  static_assert(__is_trivially_move_assignable(CppEmptyStruct), "");
+
+  static_assert(__is_move_assignable(CppStructNonStandardBy2ndVirtBase), "");
+  static_assert(__is_nothrow_move_assignable(CppStructNonStandardBy2ndVirtBase), "");
+  static_assert(__is_trivially_move_assignable(CppStructNonStandardBy2ndVirtBase), "");
+
+  static_assert(__is_move_assignable(CppStructNonStandardByBase), "");
+  static_assert(__is_nothrow_move_assignable(CppStructNonStandardByBase), "");
+  static_assert(__is_trivially_move_assignable(CppStructNonStandardByBase), "");
+
+  static_assert(__is_move_assignable(CppStructNonStandardByMemb), "");
+  static_assert(__is_nothrow_move_assignable(CppStructNonStandardByMemb), "");
+  static_assert(!__is_trivially_move_assignable(CppStructNonStandardByMemb), "");
+
+  static_assert(__is_move_assignable(CppStructNonStandardByProt), "");
+  static_assert(__is_nothrow_move_assignable(CppStructNonStandardByProt), "");
+  static_assert(__is_trivially_move_assignable(CppStructNonStandardByProt), "");
+
+  static_assert(__is_move_assignable(CppStructNonStandardBySameBase), "");
+  static_assert(__is_nothrow_move_assignable(CppStructNonStandardBySameBase), "");
+  static_assert(__is_trivially_move_assignable(CppStructNonStandardBySameBase), "");
+
+  static_assert(__is_move_assignable(CppStructNonStandardByVirt), "");
+  static_assert(__is_nothrow_move_assignable(CppStructNonStandardByVirt), "");
+  static_assert(!__is_trivially_move_assignable(CppStructNonStandardByVirt), "");
+
+  static_assert(__is_move_assignable(CppStructNonStandardByVirtBase), "");
+  static_assert(__is_nothrow_move_assignable(CppStructNonStandardByVirtBase), "");
+  static_assert(!__is_trivially_move_assignable(CppStructNonStandardByVirtBase), "");
+
+  static_assert(__is_move_assignable(CppStructStandard), "");
+  static_assert(__is_nothrow_move_assignable(CppStructStandard), "");
+  static_assert(__is_trivially_move_assignable(CppStructStandard), "");
+
+  static_assert(__is_move_assignable(CStruct), "");
+  static_assert(__is_nothrow_move_assignable(CStruct), "");
+  static_assert(__is_trivially_move_assignable(CStruct), "");
+
+  static_assert(__is_move_assignable(CVCopyCtor), "");
+  static_assert(__is_nothrow_move_assignable(CVCopyCtor), "");
+  static_assert(__is_trivially_move_assignable(CVCopyCtor), "");
+
+  static_assert(__is_move_assignable(Derives), "");
+  static_assert(__is_nothrow_move_assignable(Derives), "");
+  static_assert(__is_trivially_move_assignable(Derives), "");
+
+  static_assert(__is_move_assignable(DerivesHasCopyAssign), "");
+  static_assert(!__is_nothrow_move_assignable(DerivesHasCopyAssign), "");
+  static_assert(!__is_trivially_move_assignable(DerivesHasCopyAssign), "");
+
+  static_assert(__is_move_assignable(Empty), "");
+  static_assert(__is_nothrow_move_assignable(Empty), "");
+  static_assert(__is_trivially_move_assignable(Empty), "");
+
+  static_assert(__is_move_assignable(EmptyUnion), "");
+  static_assert(__is_nothrow_move_assignable(EmptyUnion), "");
+  static_assert(__is_trivially_move_assignable(EmptyUnion), "");
+
+  static_assert(__is_move_assignable(Enum), "");
+  static_assert(__is_nothrow_move_assignable(Enum), "");
+  static_assert(__is_trivially_move_assignable(Enum), "");
+
+  static_assert(__is_move_assignable(EnumClass), "");
+  static_assert(__is_nothrow_move_assignable(EnumClass), "");
+  static_assert(__is_trivially_move_assignable(EnumClass), "");
+
+  static_assert(__is_move_assignable(ExtDefaulted), "");
+  static_assert(!__is_nothrow_move_assignable(ExtDefaulted), "");
+  static_assert(!__is_trivially_move_assignable(ExtDefaulted), "");
+
+  static_assert(__is_move_assignable(HasCons), "");
+  static_assert(__is_nothrow_move_assignable(HasCons), "");
+  static_assert(__is_trivially_move_assignable(HasCons), "");
+
+  static_assert(__is_move_assignable(HasCopyAssign), "");
+  static_assert(!__is_nothrow_move_assignable(HasCopyAssign), "");
+  static_assert(!__is_trivially_move_assignable(HasCopyAssign), "");
+
+  static_assert(__is_move_assignable(HasDest), "");
+  static_assert(__is_nothrow_move_assignable(HasDest), "");
+  static_assert(__is_trivially_move_assignable(HasDest), "");
+
+  static_assert(__is_move_assignable(HasMutableCopyCtor), "");
+  static_assert(__is_nothrow_move_assignable(HasMutableCopyCtor), "");
+  static_assert(__is_trivially_move_assignable(HasMutableCopyCtor), "");
+
+  static_assert(__is_move_assignable(HasPriv), "");
+  static_assert(__is_nothrow_move_assignable(HasPriv), "");
+  static_assert(__is_trivially_move_assignable(HasPriv), "");
+
+  static_assert(__is_move_assignable(HasMultipleCopyAssign), "");
+  static_assert(__is_nothrow_move_assignable(HasMultipleCopyAssign), "");
+  static_assert(!__is_trivially_move_assignable(HasMultipleCopyAssign), "");
+
+  static_assert(__is_move_assignable(HasTemplateCons), "");
+  static_assert(__is_nothrow_move_assignable(HasTemplateCons), "");
+  static_assert(!__is_trivially_move_assignable(HasTemplateCons), "");
+
+  static_assert(__is_move_assignable(MemberDeletedCopyCtor), "");
+  static_assert(__is_nothrow_move_assignable(MemberDeletedCopyCtor), "");
+  static_assert(__is_trivially_move_assignable(MemberDeletedCopyCtor), "");
+
+  static_assert(__is_move_assignable(NoDefaultMoveAssignDueToDtor), "");
+  static_assert(__is_nothrow_move_assignable(NoDefaultMoveAssignDueToDtor), "");
+  static_assert(__is_trivially_move_assignable(NoDefaultMoveAssignDueToDtor), "");
+
+  static_assert(__is_move_assignable(NoDefaultMoveAssignDueToUDCopyAssign), "");
+  static_assert(!__is_nothrow_move_assignable(NoDefaultMoveAssignDueToUDCopyAssign), "");
+  static_assert(!__is_trivially_move_assignable(NoDefaultMoveAssignDueToUDCopyAssign), "");
+
+  static_assert(__is_move_assignable(NoDefaultMoveAssignDueToUDCopyCtor), "");
+  static_assert(__is_nothrow_move_assignable(NoDefaultMoveAssignDueToUDCopyCtor), "");
+  static_assert(__is_trivially_move_assignable(NoDefaultMoveAssignDueToUDCopyCtor), "");
+
+  static_assert(__is_move_assignable(NonTCStruct), "");
+  static_assert(__is_nothrow_move_assignable(NonTCStruct), "");
+  static_assert(__is_trivially_move_assignable(NonTCStruct), "");
+
+  static_assert(__is_move_assignable(NonTrivialStruct), "");
+  static_assert(__is_nothrow_move_assignable(NonTrivialStruct), "");
+  static_assert(__is_trivially_move_assignable(NonTrivialStruct), "");
+
+  static_assert(__is_move_assignable(POD), "");
+  static_assert(__is_nothrow_move_assignable(POD), "");
+  static_assert(__is_trivially_move_assignable(POD), "");
+
+  static_assert(__is_move_assignable(SuperNonTrivialStruct), "");
+  static_assert(__is_nothrow_move_assignable(SuperNonTrivialStruct), "");
+  static_assert(__is_trivially_move_assignable(SuperNonTrivialStruct), "");
+
+  static_assert(__is_move_assignable(TrivialStruct), "");
+  static_assert(__is_nothrow_move_assignable(TrivialStruct), "");
+  static_assert(__is_trivially_move_assignable(TrivialStruct), "");
+
+  static_assert(__is_move_assignable(Union), "");
+  static_assert(__is_nothrow_move_assignable(Union), "");
+  static_assert(__is_trivially_move_assignable(Union), "");
+
+  static_assert(__is_move_assignable(HasMoveAssign), "");
+  static_assert(!__is_nothrow_move_assignable(HasMoveAssign), "");
+  static_assert(!__is_trivially_move_assignable(HasMoveAssign), "");
+
+  static_assert(__is_move_assignable(HasNoThrowMoveAssign), "");
+  static_assert(__is_nothrow_move_assignable(HasNoThrowMoveAssign), "");
+  static_assert(!__is_trivially_move_assignable(HasNoThrowMoveAssign), "");
+
+  static_assert(!__is_move_assignable(AllDeleted), "");
+  static_assert(!__is_nothrow_move_assignable(AllDeleted), "");
+  static_assert(!__is_trivially_move_assignable(AllDeleted), "");
+
+  static_assert(!__is_move_assignable(AllPrivate), "");
+  static_assert(!__is_nothrow_move_assignable(AllPrivate), "");
+  static_assert(!__is_trivially_move_assignable(AllPrivate), "");
+
+  static_assert(!__is_move_assignable(AnIncompleteType[]), "");
+  static_assert(!__is_nothrow_move_assignable(AnIncompleteType[]), "");
+  static_assert(!__is_trivially_move_assignable(AnIncompleteType[]), "");
+
+  static_assert(!__is_move_assignable(AnIncompleteType), ""); // expected-error{{incomplete type}}
+  static_assert(!__is_nothrow_move_assignable(AnIncompleteType), ""); // expected-error{{incomplete type}}
+  static_assert(!__is_trivially_move_assignable(AnIncompleteType), ""); // expected-error{{incomplete type}}
+
+  static_assert(!__is_move_assignable(DerivesHasRef), "");
+  static_assert(!__is_nothrow_move_assignable(DerivesHasRef), "");
+  static_assert(!__is_trivially_move_assignable(DerivesHasRef), "");
+
+  static_assert(!__is_move_assignable(HasRef), "");
+  static_assert(!__is_nothrow_move_assignable(HasRef), "");
+  static_assert(!__is_trivially_move_assignable(HasRef), "");
+
+  static_assert(!__is_move_assignable(HasMove), "");
+  static_assert(!__is_nothrow_move_assignable(HasMove), "");
+  static_assert(!__is_trivially_move_assignable(HasMove), "");
+
+  static_assert(!__is_move_assignable(VirtAr), "");
+  static_assert(!__is_nothrow_move_assignable(VirtAr), "");
+  static_assert(!__is_trivially_move_assignable(VirtAr), "");
+
+  static_assert(!__is_move_assignable(MoveAssignDeleted), "");
+  static_assert(!__is_nothrow_move_assignable(MoveAssignDeleted), "");
+  static_assert(!__is_trivially_move_assignable(MoveAssignDeleted), "");
+
+  static_assert(!__is_move_assignable(BaseDeletedMoveAssign), "");
+  static_assert(!__is_nothrow_move_assignable(BaseDeletedMoveAssign), "");
+  static_assert(!__is_trivially_move_assignable(BaseDeletedMoveAssign), "");
+
+  static_assert(!__is_move_assignable(HasMemberWithDeletedMoveAssign), "");
+  static_assert(!__is_nothrow_move_assignable(HasMemberWithDeletedMoveAssign), "");
+  static_assert(!__is_trivially_move_assignable(HasMemberWithDeletedMoveAssign), "");
+
+  static_assert(__is_move_assignable(MoveAssign_QualNone), "");
+  static_assert(!__is_nothrow_move_assignable(MoveAssign_QualNone), "");
+  static_assert(!__is_trivially_move_assignable(MoveAssign_QualNone), "");
+
+  static_assert(!__is_move_assignable(MoveAssign_QualConst), "");
+  static_assert(!__is_nothrow_move_assignable(MoveAssign_QualConst), "");
+  static_assert(!__is_trivially_move_assignable(MoveAssign_QualConst), "");
+
+  static_assert(!__is_move_assignable(MoveAssign_QualVolatile), "");
+  static_assert(!__is_nothrow_move_assignable(MoveAssign_QualVolatile), "");
+  static_assert(!__is_trivially_move_assignable(MoveAssign_QualVolatile), "");
+
+  static_assert(!__is_move_assignable(MoveAssign_QualCV), "");
+  static_assert(!__is_nothrow_move_assignable(MoveAssign_QualCV), "");
+  static_assert(!__is_trivially_move_assignable(MoveAssign_QualCV), "");
+
+  static_assert(__is_move_assignable(MoveAssign_QualLvalue), "");
+  static_assert(!__is_nothrow_move_assignable(MoveAssign_QualLvalue), "");
+  static_assert(!__is_trivially_move_assignable(MoveAssign_QualLvalue), "");
+
+  static_assert(!__is_move_assignable(MoveAssign_QualConstLvalue), "");
+  static_assert(!__is_nothrow_move_assignable(MoveAssign_QualConstLvalue), "");
+  static_assert(!__is_trivially_move_assignable(MoveAssign_QualConstLvalue), "");
+
+  static_assert(!__is_move_assignable(MoveAssign_QualVolatileLvalue), "");
+  static_assert(!__is_nothrow_move_assignable(MoveAssign_QualVolatileLvalue), "");
+  static_assert(!__is_trivially_move_assignable(MoveAssign_QualVolatileLvalue), "");
+
+  static_assert(!__is_move_assignable(MoveAssign_QualCVLvalue), "");
+  static_assert(!__is_nothrow_move_assignable(MoveAssign_QualCVLvalue), "");
+  static_assert(!__is_trivially_move_assignable(MoveAssign_QualCVLvalue), "");
+
+  static_assert(!__is_move_assignable(MoveAssign_QualRvalue), "");
+  static_assert(!__is_nothrow_move_assignable(MoveAssign_QualRvalue), "");
+  static_assert(!__is_trivially_move_assignable(MoveAssign_QualRvalue), "");
+
+  static_assert(!__is_move_assignable(MoveAssign_QualConstRvalue), "");
+  static_assert(!__is_nothrow_move_assignable(MoveAssign_QualConstRvalue), "");
+  static_assert(!__is_trivially_move_assignable(MoveAssign_QualConstRvalue), "");
+
+  static_assert(!__is_move_assignable(MoveAssign_QualVolatileRvalue), "");
+  static_assert(!__is_nothrow_move_assignable(MoveAssign_QualVolatileRvalue), "");
+  static_assert(!__is_trivially_move_assignable(MoveAssign_QualVolatileRvalue), "");
+
+  static_assert(!__is_move_assignable(MoveAssign_QualCVRvalue), "");
+  static_assert(!__is_nothrow_move_assignable(MoveAssign_QualCVRvalue), "");
+  static_assert(!__is_trivially_move_assignable(MoveAssign_QualCVRvalue), "");
+
+  static_assert(__is_move_assignable(ConstMoveAssign_QualNone), "");
+  static_assert(!__is_nothrow_move_assignable(ConstMoveAssign_QualNone), "");
+  static_assert(!__is_trivially_move_assignable(ConstMoveAssign_QualNone), "");
+
+  static_assert(!__is_move_assignable(ConstMoveAssign_QualConst), "");
+  static_assert(!__is_nothrow_move_assignable(ConstMoveAssign_QualConst), "");
+  static_assert(!__is_trivially_move_assignable(ConstMoveAssign_QualConst), "");
+
+  static_assert(!__is_move_assignable(ConstMoveAssign_QualVolatile), "");
+  static_assert(!__is_nothrow_move_assignable(ConstMoveAssign_QualVolatile), "");
+  static_assert(!__is_trivially_move_assignable(ConstMoveAssign_QualVolatile), "");
+
+  static_assert(!__is_move_assignable(ConstMoveAssign_QualCV), "");
+  static_assert(!__is_nothrow_move_assignable(ConstMoveAssign_QualCV), "");
+  static_assert(!__is_trivially_move_assignable(ConstMoveAssign_QualCV), "");
+
+  static_assert(__is_move_assignable(ConstMoveAssign_QualLvalue), "");
+  static_assert(!__is_nothrow_move_assignable(ConstMoveAssign_QualLvalue), "");
+  static_assert(!__is_trivially_move_assignable(ConstMoveAssign_QualLvalue), "");
+
+  static_assert(!__is_move_assignable(ConstMoveAssign_QualConstLvalue), "");
+  static_assert(!__is_nothrow_move_assignable(ConstMoveAssign_QualConstLvalue), "");
+  static_assert(!__is_trivially_move_assignable(ConstMoveAssign_QualConstLvalue), "");
+
+  static_assert(!__is_move_assignable(ConstMoveAssign_QualVolatileLvalue), "");
+  static_assert(!__is_nothrow_move_assignable(ConstMoveAssign_QualVolatileLvalue), "");
+  static_assert(!__is_trivially_move_assignable(ConstMoveAssign_QualVolatileLvalue), "");
+
+  static_assert(!__is_move_assignable(ConstMoveAssign_QualCVLvalue), "");
+  static_assert(!__is_nothrow_move_assignable(ConstMoveAssign_QualCVLvalue), "");
+  static_assert(!__is_trivially_move_assignable(ConstMoveAssign_QualCVLvalue), "");
+
+  static_assert(!__is_move_assignable(ConstMoveAssign_QualRvalue), "");
+  static_assert(!__is_nothrow_move_assignable(ConstMoveAssign_QualRvalue), "");
+  static_assert(!__is_trivially_move_assignable(ConstMoveAssign_QualRvalue), "");
+
+  static_assert(!__is_move_assignable(ConstMoveAssign_QualConstRvalue), "");
+  static_assert(!__is_nothrow_move_assignable(ConstMoveAssign_QualConstRvalue), "");
+  static_assert(!__is_trivially_move_assignable(ConstMoveAssign_QualConstRvalue), "");
+
+  static_assert(!__is_move_assignable(ConstMoveAssign_QualVolatileRvalue), "");
+  static_assert(!__is_nothrow_move_assignable(ConstMoveAssign_QualVolatileRvalue), "");
+  static_assert(!__is_trivially_move_assignable(ConstMoveAssign_QualVolatileRvalue), "");
+
+  static_assert(!__is_move_assignable(ConstMoveAssign_QualCVRvalue), "");
+  static_assert(!__is_nothrow_move_assignable(ConstMoveAssign_QualCVRvalue), "");
+  static_assert(!__is_trivially_move_assignable(ConstMoveAssign_QualCVRvalue), "");
+
+  static_assert(__is_move_assignable(VolatileMoveAssign_QualNone), "");
+  static_assert(!__is_nothrow_move_assignable(VolatileMoveAssign_QualNone), "");
+  static_assert(!__is_trivially_move_assignable(VolatileMoveAssign_QualNone), "");
+
+  static_assert(!__is_move_assignable(VolatileMoveAssign_QualConst), "");
+  static_assert(!__is_nothrow_move_assignable(VolatileMoveAssign_QualConst), "");
+  static_assert(!__is_trivially_move_assignable(VolatileMoveAssign_QualConst), "");
+
+  static_assert(!__is_move_assignable(VolatileMoveAssign_QualVolatile), "");
+  static_assert(!__is_nothrow_move_assignable(VolatileMoveAssign_QualVolatile), "");
+  static_assert(!__is_trivially_move_assignable(VolatileMoveAssign_QualVolatile), "");
+
+  static_assert(!__is_move_assignable(VolatileMoveAssign_QualCV), "");
+  static_assert(!__is_nothrow_move_assignable(VolatileMoveAssign_QualCV), "");
+  static_assert(!__is_trivially_move_assignable(VolatileMoveAssign_QualCV), "");
+
+  static_assert(__is_move_assignable(VolatileMoveAssign_QualLvalue), "");
+  static_assert(!__is_nothrow_move_assignable(VolatileMoveAssign_QualLvalue), "");
+  static_assert(!__is_trivially_move_assignable(VolatileMoveAssign_QualLvalue), "");
+
+  static_assert(!__is_move_assignable(VolatileMoveAssign_QualConstLvalue), "");
+  static_assert(!__is_nothrow_move_assignable(VolatileMoveAssign_QualConstLvalue), "");
+  static_assert(!__is_trivially_move_assignable(VolatileMoveAssign_QualConstLvalue), "");
+
+  static_assert(!__is_move_assignable(VolatileMoveAssign_QualVolatileLvalue), "");
+  static_assert(!__is_nothrow_move_assignable(VolatileMoveAssign_QualVolatileLvalue), "");
+  static_assert(!__is_trivially_move_assignable(VolatileMoveAssign_QualVolatileLvalue), "");
+
+  static_assert(!__is_move_assignable(VolatileMoveAssign_QualCVLvalue), "");
+  static_assert(!__is_nothrow_move_assignable(VolatileMoveAssign_QualCVLvalue), "");
+  static_assert(!__is_trivially_move_assignable(VolatileMoveAssign_QualCVLvalue), "");
+
+  static_assert(!__is_move_assignable(VolatileMoveAssign_QualRvalue), "");
+  static_assert(!__is_nothrow_move_assignable(VolatileMoveAssign_QualRvalue), "");
+  static_assert(!__is_trivially_move_assignable(VolatileMoveAssign_QualRvalue), "");
+
+  static_assert(!__is_move_assignable(VolatileMoveAssign_QualConstRvalue), "");
+  static_assert(!__is_nothrow_move_assignable(VolatileMoveAssign_QualConstRvalue), "");
+  static_assert(!__is_trivially_move_assignable(VolatileMoveAssign_QualConstRvalue), "");
+
+  static_assert(!__is_move_assignable(VolatileMoveAssign_QualVolatileRvalue), "");
+  static_assert(!__is_nothrow_move_assignable(VolatileMoveAssign_QualVolatileRvalue), "");
+  static_assert(!__is_trivially_move_assignable(VolatileMoveAssign_QualVolatileRvalue), "");
+
+  static_assert(!__is_move_assignable(VolatileMoveAssign_QualCVRvalue), "");
+  static_assert(!__is_nothrow_move_assignable(VolatileMoveAssign_QualCVRvalue), "");
+  static_assert(!__is_trivially_move_assignable(VolatileMoveAssign_QualCVRvalue), "");
+
+  static_assert(__is_move_assignable(CVMoveAssign_QualNone), "");
+  static_assert(!__is_nothrow_move_assignable(CVMoveAssign_QualNone), "");
+  static_assert(!__is_trivially_move_assignable(CVMoveAssign_QualNone), "");
+
+  static_assert(!__is_move_assignable(CVMoveAssign_QualConst), "");
+  static_assert(!__is_nothrow_move_assignable(CVMoveAssign_QualConst), "");
+  static_assert(!__is_trivially_move_assignable(CVMoveAssign_QualConst), "");
+
+  static_assert(!__is_move_assignable(CVMoveAssign_QualVolatile), "");
+  static_assert(!__is_nothrow_move_assignable(CVMoveAssign_QualVolatile), "");
+  static_assert(!__is_trivially_move_assignable(CVMoveAssign_QualVolatile), "");
+
+  static_assert(!__is_move_assignable(CVMoveAssign_QualCV), "");
+  static_assert(!__is_nothrow_move_assignable(CVMoveAssign_QualCV), "");
+  static_assert(!__is_trivially_move_assignable(CVMoveAssign_QualCV), "");
+
+  static_assert(__is_move_assignable(CVMoveAssign_QualLvalue), "");
+  static_assert(!__is_nothrow_move_assignable(CVMoveAssign_QualLvalue), "");
+  static_assert(!__is_trivially_move_assignable(CVMoveAssign_QualLvalue), "");
+
+  static_assert(!__is_move_assignable(CVMoveAssign_QualConstLvalue), "");
+  static_assert(!__is_nothrow_move_assignable(CVMoveAssign_QualConstLvalue), "");
+  static_assert(!__is_trivially_move_assignable(CVMoveAssign_QualConstLvalue), "");
+
+  static_assert(!__is_move_assignable(CVMoveAssign_QualVolatileLvalue), "");
+  static_assert(!__is_nothrow_move_assignable(CVMoveAssign_QualVolatileLvalue), "");
+  static_assert(!__is_trivially_move_assignable(CVMoveAssign_QualVolatileLvalue), "");
+
+  static_assert(!__is_move_assignable(CVMoveAssign_QualCVLvalue), "");
+  static_assert(!__is_nothrow_move_assignable(CVMoveAssign_QualCVLvalue), "");
+  static_assert(!__is_trivially_move_assignable(CVMoveAssign_QualCVLvalue), "");
+
+  static_assert(!__is_move_assignable(CVMoveAssign_QualRvalue), "");
+  static_assert(!__is_nothrow_move_assignable(CVMoveAssign_QualRvalue), "");
+  static_assert(!__is_trivially_move_assignable(CVMoveAssign_QualRvalue), "");
+
+  static_assert(!__is_move_assignable(CVMoveAssign_QualConstRvalue), "");
+  static_assert(!__is_nothrow_move_assignable(CVMoveAssign_QualConstRvalue), "");
+  static_assert(!__is_trivially_move_assignable(CVMoveAssign_QualConstRvalue), "");
+
+  static_assert(!__is_move_assignable(CVMoveAssign_QualVolatileRvalue), "");
+  static_assert(!__is_nothrow_move_assignable(CVMoveAssign_QualVolatileRvalue), "");
+  static_assert(!__is_trivially_move_assignable(CVMoveAssign_QualVolatileRvalue), "");
+
+  static_assert(!__is_move_assignable(CVMoveAssign_QualCVRvalue), "");
+  static_assert(!__is_nothrow_move_assignable(CVMoveAssign_QualCVRvalue), "");
+  static_assert(!__is_trivially_move_assignable(CVMoveAssign_QualCVRvalue), "");
+
+
+  // Non-referencable types
+  static_assert(!__is_move_assignable(void), "");
+  static_assert(!__is_nothrow_move_assignable(void), "");
+  static_assert(!__is_trivially_move_assignable(void), "");
+
+  static_assert(!__is_move_assignable(void()), "");
+  static_assert(!__is_nothrow_move_assignable(void()), "");
+  static_assert(!__is_trivially_move_assignable(void()), "");
+
+  // cv-qualified types
+  static_assert(!__is_move_assignable(const int), "");
+  static_assert(!__is_nothrow_move_assignable(const int), "");
+  static_assert(!__is_trivially_move_assignable(const int), "");
+
+  static_assert(!__is_move_assignable(const Empty), "");
+  static_assert(!__is_nothrow_move_assignable(const Empty), "");
+  static_assert(!__is_trivially_move_assignable(const Empty), "");
+
+  static_assert(__is_move_assignable(volatile int), "");
+  static_assert(__is_nothrow_move_assignable(volatile int), "");
+  static_assert(__is_trivially_move_assignable(volatile int), "");
+
+  static_assert(!__is_move_assignable(volatile Empty), "");
+  static_assert(!__is_nothrow_move_assignable(volatile Empty), "");
+  static_assert(!__is_trivially_move_assignable(volatile Empty), "");
+
+  static_assert(!__is_move_assignable(const volatile int), "");
+  static_assert(!__is_nothrow_move_assignable(const volatile int), "");
+  static_assert(!__is_trivially_move_assignable(const volatile int), "");
+
+  static_assert(!__is_move_assignable(const volatile Empty), "");
+  static_assert(!__is_nothrow_move_assignable(const volatile Empty), "");
+  static_assert(!__is_trivially_move_assignable(const volatile Empty), "");
+
+  static_assert(!__is_move_assignable(const MoveAssign_QualConst), "");
+  static_assert(!__is_nothrow_move_assignable(const MoveAssign_QualConst), "");
+  static_assert(!__is_trivially_move_assignable(const MoveAssign_QualConst), "");
+
+  static_assert(!__is_move_assignable(volatile MoveAssign_QualConst), "");
+  static_assert(!__is_nothrow_move_assignable(volatile MoveAssign_QualConst), "");
+  static_assert(!__is_trivially_move_assignable(volatile MoveAssign_QualConst), "");
+
+  static_assert(!__is_move_assignable(const volatile MoveAssign_QualConst), "");
+  static_assert(!__is_nothrow_move_assignable(const volatile MoveAssign_QualConst), "");
+  static_assert(!__is_trivially_move_assignable(const volatile MoveAssign_QualConst), "");
+
+  static_assert(!__is_move_assignable(volatile MoveAssign_QualVolatile), "");
+  static_assert(!__is_nothrow_move_assignable(volatile MoveAssign_QualVolatile), "");
+  static_assert(!__is_trivially_move_assignable(volatile MoveAssign_QualVolatile), "");
+
+  static_assert(!__is_move_assignable(const volatile MoveAssign_QualCV), "");
+  static_assert(!__is_nothrow_move_assignable(const volatile MoveAssign_QualCV), "");
+  static_assert(!__is_trivially_move_assignable(const volatile MoveAssign_QualCV), "");
+
+  static_assert(!__is_move_assignable(const VolatileMoveAssign_QualConst), "");
+  static_assert(!__is_nothrow_move_assignable(const VolatileMoveAssign_QualConst), "");
+  static_assert(!__is_trivially_move_assignable(const VolatileMoveAssign_QualConst), "");
+
+  static_assert(__is_move_assignable(volatile VolatileMoveAssign_QualVolatile), "");
+  static_assert(!__is_nothrow_move_assignable(volatile VolatileMoveAssign_QualVolatile), "");
+  static_assert(!__is_trivially_move_assignable(volatile VolatileMoveAssign_QualVolatile), "");
+
+  static_assert(!__is_move_assignable(const volatile VolatileMoveAssign_QualCV), "");
+  static_assert(!__is_nothrow_move_assignable(const volatile VolatileMoveAssign_QualCV), "");
+  static_assert(!__is_trivially_move_assignable(const volatile VolatileMoveAssign_QualCV), "");
+
+  static_assert(__is_move_assignable(const CVMoveAssign_QualConst), "");
+  static_assert(!__is_nothrow_move_assignable(const CVMoveAssign_QualConst), "");
+  static_assert(!__is_trivially_move_assignable(const CVMoveAssign_QualConst), "");
+
+  static_assert(__is_move_assignable(volatile CVMoveAssign_QualVolatile), "");
+  static_assert(!__is_nothrow_move_assignable(volatile CVMoveAssign_QualVolatile), "");
+  static_assert(!__is_trivially_move_assignable(volatile CVMoveAssign_QualVolatile), "");
+
+  static_assert(__is_move_assignable(const volatile CVMoveAssign_QualCV), "");
+  static_assert(!__is_nothrow_move_assignable(const volatile CVMoveAssign_QualCV), "");
+  static_assert(!__is_trivially_move_assignable(const volatile CVMoveAssign_QualCV), "");
+}
+
 // Instantiation of __is_trivially_constructible
 template<typename T, typename ...Args>
 struct is_trivially_constructible {
Index: clang/test/SemaCXX/deprecated-builtins.cpp
===================================================================
--- clang/test/SemaCXX/deprecated-builtins.cpp
+++ clang/test/SemaCXX/deprecated-builtins.cpp
@@ -6,11 +6,11 @@
     bool a;
 
     a = __has_nothrow_assign(A);  // expected-warning-re {{__has_nothrow_assign {{.*}} use __is_nothrow_copy_assignable}}
-    a = __has_nothrow_move_assign(A);  // expected-warning-re {{__has_nothrow_move_assign {{.*}} use __is_nothrow_assignable}}
+    a = __has_nothrow_move_assign(A);  // expected-warning-re {{__has_nothrow_move_assign {{.*}} use __is_nothrow_move_assignable}}
     a = __has_nothrow_copy(A);  // expected-warning-re {{__has_nothrow_copy {{.*}} use __is_nothrow_copy_constructible}}
     a = __has_nothrow_constructor(A);  // expected-warning-re {{__has_nothrow_constructor {{.*}} use __is_nothrow_constructible}}
     a = __has_trivial_assign(A);  // expected-warning-re {{__has_trivial_assign {{.*}} use __is_trivially_copy_assignable}}
-    a = __has_trivial_move_assign(A);  // expected-warning-re {{__has_trivial_move_assign {{.*}} use __is_trivially_assignable}}
+    a = __has_trivial_move_assign(A);  // expected-warning-re {{__has_trivial_move_assign {{.*}} use __is_trivially_move_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_move_constructible}}
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -4857,6 +4857,9 @@
   case UTT_IsMoveConstructible:
   case UTT_IsTriviallyMoveConstructible:
   case UTT_IsNothrowMoveConstructible:
+  case UTT_IsMoveAssignable:
+  case UTT_IsTriviallyMoveAssignable:
+  case UTT_IsNothrowMoveAssignable:
     if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType())
       return true;
 
@@ -5356,7 +5359,10 @@
   }
   case UTT_IsMoveConstructible:
   case UTT_IsTriviallyMoveConstructible:
-  case UTT_IsNothrowMoveConstructible: {
+  case UTT_IsNothrowMoveConstructible:
+  case UTT_IsMoveAssignable:
+  case UTT_IsTriviallyMoveAssignable:
+  case UTT_IsNothrowMoveAssignable: {
     if (T->isIncompleteArrayType())
       return false;
     if (!T.isReferenceable())
@@ -5364,6 +5370,15 @@
 
     QualType AssigneeType = Self.BuiltinAddReference(
         T, UnaryTransformType::AddRvalueReference, KeyLoc);
+    if (UTT == UTT_IsMoveAssignable || UTT == UTT_IsTriviallyMoveAssignable ||
+        UTT == UTT_IsNothrowMoveAssignable)
+      return EvaluateBinaryTypeTrait(
+          Self,
+          UTT == UTT_IsMoveAssignable            ? BTT_IsAssignable
+          : UTT == UTT_IsTriviallyMoveAssignable ? BTT_IsTriviallyAssignable
+                                                 : BTT_IsNothrowAssignable,
+          Self.BuildReferenceType(T, true, KeyLoc, T.getBaseTypeIdentifier()),
+          AssigneeType, KeyLoc);
     llvm::SmallVector<TypeSourceInfo *, 2> Parameters = {
         C.CreateTypeSourceInfo(T), C.CreateTypeSourceInfo(AssigneeType)};
     return evaluateTypeTrait(Self,
@@ -5510,7 +5525,7 @@
     Replacement = UTT_IsNothrowCopyAssignable;
     break;
   case UTT_HasNothrowMoveAssign:
-    Replacement = BTT_IsNothrowAssignable;
+    Replacement = UTT_IsNothrowMoveAssignable;
     break;
   case UTT_HasNothrowCopy:
     Replacement = UTT_IsNothrowCopyConstructible;
@@ -5522,7 +5537,7 @@
     Replacement = UTT_IsTriviallyCopyAssignable;
     break;
   case UTT_HasTrivialMoveAssign:
-    Replacement = BTT_IsTriviallyAssignable;
+    Replacement = UTT_IsTriviallyMoveAssignable;
     break;
   case UTT_HasTrivialCopy:
     Replacement = UTT_IsTriviallyCopyConstructible;
Index: clang/lib/Parse/ParseExpr.cpp
===================================================================
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -1093,11 +1093,13 @@
           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_assignable);
           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_assignable);
           REVERTIBLE_TYPE_TRAIT(__is_nothrow_move_constructible);
           REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible);
           REVERTIBLE_TYPE_TRAIT(__is_nullptr);
@@ -1121,6 +1123,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_assignable);
           REVERTIBLE_TYPE_TRAIT(__is_trivially_move_constructible);
           REVERTIBLE_TYPE_TRAIT(__is_unbounded_array);
           REVERTIBLE_TYPE_TRAIT(__is_union);
Index: clang/lib/Parse/ParseDeclCXX.cpp
===================================================================
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -1604,12 +1604,14 @@
           tok::kw___is_member_function_pointer,
           tok::kw___is_member_object_pointer,
           tok::kw___is_member_pointer,
+          tok::kw___is_move_assignable,
           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_assignable,
           tok::kw___is_nothrow_move_constructible,
           tok::kw___is_nullptr,
           tok::kw___is_object,
@@ -1632,6 +1634,7 @@
           tok::kw___is_trivially_copy_assignable,
           tok::kw___is_trivially_copy_constructible,
           tok::kw___is_trivially_copyable,
+          tok::kw___is_trivially_move_assignable,
           tok::kw___is_trivially_move_constructible,
           tok::kw___is_unbounded_array,
           tok::kw___is_union,
Index: clang/include/clang/Basic/TokenKinds.def
===================================================================
--- clang/include/clang/Basic/TokenKinds.def
+++ clang/include/clang/Basic/TokenKinds.def
@@ -533,6 +533,9 @@
 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)
+TYPE_TRAIT_1(__is_move_assignable, IsMoveAssignable, KEYCXX)
+TYPE_TRAIT_1(__is_nothrow_move_assignable, IsNothrowMoveAssignable, KEYCXX)
+TYPE_TRAIT_1(__is_trivially_move_assignable, IsTriviallyMoveAssignable, 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] D135338: [cla... Christopher Di Bella via Phabricator via cfe-commits

Reply via email to