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_copy_assignable`
- `__is_nothrow_copy_assignable`
- `__is_trivially_copy_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_copy_construcitble`, etc., these traits can't be
implemented using `__is_assignable`, etc., because we can't form
references to void, which are a fundamental part of copy assignment.

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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D135239

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,675 @@
   static_assert(!__is_trivially_copy_constructible(void()), "");
 }
 
+struct MutableCopyAssign_QualNone {
+  MutableCopyAssign_QualNone &operator=(MutableCopyAssign_QualNone &);
+};
+struct MutableCopyAssign_QualConst {
+  MutableCopyAssign_QualConst &operator=(MutableCopyAssign_QualConst &) const;
+};
+struct MutableCopyAssign_QualVolatile {
+  MutableCopyAssign_QualVolatile &operator=(MutableCopyAssign_QualVolatile &) volatile;
+};
+struct MutableCopyAssign_QualCV {
+  MutableCopyAssign_QualCV &operator=(MutableCopyAssign_QualCV &) const volatile;
+};
+struct MutableCopyAssign_QualLvalue {
+  MutableCopyAssign_QualLvalue &operator=(MutableCopyAssign_QualLvalue &) &;
+};
+struct MutableCopyAssign_QualConstLvalue {
+  MutableCopyAssign_QualConstLvalue &operator=(MutableCopyAssign_QualConstLvalue &) const &;
+};
+struct MutableCopyAssign_QualVolatileLvalue {
+  MutableCopyAssign_QualVolatileLvalue &operator=(MutableCopyAssign_QualVolatileLvalue &) volatile &;
+};
+struct MutableCopyAssign_QualCVLvalue {
+  MutableCopyAssign_QualCVLvalue &operator=(MutableCopyAssign_QualCVLvalue &) const volatile &;
+};
+struct MutableCopyAssign_QualRvalue {
+  MutableCopyAssign_QualRvalue &operator=(MutableCopyAssign_QualRvalue &) &&;
+};
+struct MutableCopyAssign_QualConstRvalue {
+  MutableCopyAssign_QualConstRvalue &operator=(MutableCopyAssign_QualConstRvalue &) const &&;
+};
+struct MutableCopyAssign_QualVolatileRvalue {
+  MutableCopyAssign_QualVolatileRvalue &operator=(MutableCopyAssign_QualVolatileRvalue &) volatile &&;
+};
+struct MutableCopyAssign_QualCVRvalue {
+  MutableCopyAssign_QualCVRvalue &operator=(MutableCopyAssign_QualCVRvalue &) const volatile &&;
+};
+
+struct CopyAssign_QualNone {
+  CopyAssign_QualNone &operator=(const CopyAssign_QualNone &);
+};
+struct CopyAssign_QualConst {
+  CopyAssign_QualConst &operator=(const CopyAssign_QualConst &) const;
+};
+struct CopyAssign_QualVolatile {
+  CopyAssign_QualVolatile &operator=(const CopyAssign_QualVolatile &) volatile;
+};
+struct CopyAssign_QualCV {
+  CopyAssign_QualCV &operator=(const CopyAssign_QualCV &) const volatile;
+};
+struct CopyAssign_QualLvalue {
+  CopyAssign_QualLvalue &operator=(const CopyAssign_QualLvalue &) &;
+};
+struct CopyAssign_QualConstLvalue {
+  CopyAssign_QualConstLvalue &operator=(const CopyAssign_QualConstLvalue &) const &;
+};
+struct CopyAssign_QualVolatileLvalue {
+  CopyAssign_QualVolatileLvalue &operator=(const CopyAssign_QualVolatileLvalue &) volatile &;
+};
+struct CopyAssign_QualCVLvalue {
+  CopyAssign_QualCVLvalue &operator=(const CopyAssign_QualCVLvalue &) const volatile &;
+};
+struct CopyAssign_QualRvalue {
+  CopyAssign_QualRvalue &operator=(const CopyAssign_QualRvalue &) &&;
+};
+struct CopyAssign_QualConstRvalue {
+  CopyAssign_QualConstRvalue &operator=(const CopyAssign_QualConstRvalue &) const &&;
+};
+struct CopyAssign_QualVolatileRvalue {
+  CopyAssign_QualVolatileRvalue &operator=(const CopyAssign_QualVolatileRvalue &) volatile &&;
+};
+struct CopyAssign_QualCVRvalue {
+  CopyAssign_QualCVRvalue &operator=(const CopyAssign_QualCVRvalue &) const volatile &&;
+};
+
+struct VolatileCopyAssign_QualNone {
+  VolatileCopyAssign_QualNone &operator=(volatile VolatileCopyAssign_QualNone &);
+};
+struct VolatileCopyAssign_QualConst {
+  VolatileCopyAssign_QualConst &operator=(volatile VolatileCopyAssign_QualConst &) const;
+};
+struct VolatileCopyAssign_QualVolatile {
+  VolatileCopyAssign_QualVolatile &operator=(volatile VolatileCopyAssign_QualVolatile &) volatile;
+};
+struct VolatileCopyAssign_QualCV {
+  VolatileCopyAssign_QualCV &operator=(volatile VolatileCopyAssign_QualCV &) const volatile;
+};
+struct VolatileCopyAssign_QualLvalue {
+  VolatileCopyAssign_QualLvalue &operator=(volatile VolatileCopyAssign_QualLvalue &) &;
+};
+struct VolatileCopyAssign_QualConstLvalue {
+  VolatileCopyAssign_QualConstLvalue &operator=(volatile VolatileCopyAssign_QualConstLvalue &) const &;
+};
+struct VolatileCopyAssign_QualVolatileLvalue {
+  VolatileCopyAssign_QualVolatileLvalue &operator=(volatile VolatileCopyAssign_QualVolatileLvalue &) volatile &;
+};
+struct VolatileCopyAssign_QualCVLvalue {
+  VolatileCopyAssign_QualCVLvalue &operator=(volatile VolatileCopyAssign_QualCVLvalue &) const volatile &;
+};
+struct VolatileCopyAssign_QualRvalue {
+  VolatileCopyAssign_QualRvalue &operator=(volatile VolatileCopyAssign_QualRvalue &) &&;
+};
+struct VolatileCopyAssign_QualConstRvalue {
+  VolatileCopyAssign_QualConstRvalue &operator=(volatile VolatileCopyAssign_QualConstRvalue &) const &&;
+};
+struct VolatileCopyAssign_QualVolatileRvalue {
+  VolatileCopyAssign_QualVolatileRvalue &operator=(volatile VolatileCopyAssign_QualVolatileRvalue &) volatile &&;
+};
+struct VolatileCopyAssign_QualCVRvalue {
+  VolatileCopyAssign_QualCVRvalue &operator=(volatile VolatileCopyAssign_QualCVRvalue &) const volatile &&;
+};
+
+struct CVCopyAssign_QualNone {
+  CVCopyAssign_QualNone &operator=(const volatile CVCopyAssign_QualNone &);
+};
+struct CVCopyAssign_QualConst {
+  CVCopyAssign_QualConst &operator=(const volatile CVCopyAssign_QualConst &) const;
+};
+struct CVCopyAssign_QualVolatile {
+  CVCopyAssign_QualVolatile &operator=(const volatile CVCopyAssign_QualVolatile &) volatile;
+};
+struct CVCopyAssign_QualCV {
+  CVCopyAssign_QualCV &operator=(const volatile CVCopyAssign_QualCV &) const volatile;
+};
+struct CVCopyAssign_QualLvalue {
+  CVCopyAssign_QualLvalue &operator=(const volatile CVCopyAssign_QualLvalue &) &;
+};
+struct CVCopyAssign_QualConstLvalue {
+  CVCopyAssign_QualConstLvalue &operator=(const volatile CVCopyAssign_QualConstLvalue &) const &;
+};
+struct CVCopyAssign_QualCVLvalue {
+  CVCopyAssign_QualCVLvalue &operator=(const volatile CVCopyAssign_QualCVLvalue &) volatile &;
+};
+struct CVCopyAssign_QualVolatileLvalue {
+  CVCopyAssign_QualVolatileLvalue &operator=(const volatile CVCopyAssign_QualVolatileLvalue &) const volatile &;
+};
+struct CVCopyAssign_QualRvalue {
+  CVCopyAssign_QualRvalue &operator=(const volatile CVCopyAssign_QualRvalue &) &&;
+};
+struct CVCopyAssign_QualConstRvalue {
+  CVCopyAssign_QualConstRvalue &operator=(const volatile CVCopyAssign_QualConstRvalue &) const &&;
+};
+struct CVCopyAssign_QualVolatileRvalue {
+  CVCopyAssign_QualVolatileRvalue &operator=(const volatile CVCopyAssign_QualVolatileRvalue &) volatile &&;
+};
+struct CVCopyAssign_QualCVRvalue {
+  CVCopyAssign_QualCVRvalue &operator=(const volatile CVCopyAssign_QualCVRvalue &) const volatile &&;
+};
+struct CopyAssignDeleted {
+  CopyAssignDeleted &operator=(const CopyAssignDeleted &) = delete;
+};
+struct BaseDeletedCopyAssign : CopyAssignDeleted {};
+struct HasMemberWithDeletedCopyAssign {
+  CopyAssignDeleted x;
+};
+
+void copy_assignable_checks() {
+  // Builtin types
+  static_assert(__is_copy_assignable(int), "");
+  static_assert(__is_nothrow_copy_assignable(int), "");
+  static_assert(__is_trivially_copy_assignable(int), "");
+
+  static_assert(__is_copy_assignable(int &), "");
+  static_assert(__is_nothrow_copy_assignable(int &), "");
+  static_assert(__is_trivially_copy_assignable(int &), "");
+
+  static_assert(__is_copy_assignable(int &&), "");
+  static_assert(__is_nothrow_copy_assignable(int &&), "");
+  static_assert(__is_trivially_copy_assignable(int &&), "");
+
+  static_assert(__is_copy_assignable(int *), "");
+  static_assert(__is_nothrow_copy_assignable(int *), "");
+  static_assert(__is_trivially_copy_assignable(int *), "");
+
+  static_assert(!__is_copy_assignable(int[5]), "");
+  static_assert(!__is_nothrow_copy_assignable(int[5]), "");
+  static_assert(!__is_trivially_copy_assignable(int[5]), "");
+
+  static_assert(!__is_copy_assignable(int[]), "");
+  static_assert(!__is_nothrow_copy_assignable(int[]), "");
+  static_assert(!__is_trivially_copy_assignable(int[]), "");
+
+  static_assert(__is_copy_assignable(decltype(nullptr)), "");
+  static_assert(__is_nothrow_copy_assignable(decltype(nullptr)), "");
+  static_assert(__is_trivially_copy_assignable(decltype(nullptr)), "");
+
+  static_assert(__is_copy_assignable(void (*)()), "");
+  static_assert(__is_nothrow_copy_assignable(void (*)()), "");
+  static_assert(__is_trivially_copy_assignable(void (*)()), "");
+
+  static_assert(!__is_copy_assignable(void (&)()), "");
+  static_assert(!__is_nothrow_copy_assignable(void (&)()), "");
+  static_assert(!__is_trivially_copy_assignable(void (&)()), "");
+
+  static_assert(__is_copy_assignable(int Empty::*), "");
+  static_assert(__is_nothrow_copy_assignable(int Empty::*), "");
+  static_assert(__is_trivially_copy_assignable(int Empty::*), "");
+
+  static_assert(__is_copy_assignable(int (Empty::*)()), "");
+  static_assert(__is_nothrow_copy_assignable(int (Empty::*)()), "");
+  static_assert(__is_trivially_copy_assignable(int (Empty::*)()), "");
+
+  // // User-defined types
+  static_assert(__is_copy_assignable(AllDefaulted), "");
+  static_assert(__is_nothrow_copy_assignable(AllDefaulted), "");
+  static_assert(__is_trivially_copy_assignable(AllDefaulted), "");
+
+  static_assert(__is_copy_assignable(BaseDeletedCopyCtor), "");
+  static_assert(__is_nothrow_copy_assignable(BaseDeletedCopyCtor), "");
+  static_assert(__is_trivially_copy_assignable(BaseDeletedCopyCtor), "");
+
+  static_assert(__is_copy_assignable(CEmptyStruct), "");
+  static_assert(__is_nothrow_copy_assignable(CEmptyStruct), "");
+  static_assert(__is_trivially_copy_assignable(CEmptyStruct), "");
+
+  static_assert(__is_copy_assignable(CopyCtorDeleted), "");
+  static_assert(__is_nothrow_copy_assignable(CopyCtorDeleted), "");
+  static_assert(__is_trivially_copy_assignable(CopyCtorDeleted), "");
+
+  static_assert(__is_copy_assignable(CppEmptyStruct), "");
+  static_assert(__is_nothrow_copy_assignable(CppEmptyStruct), "");
+  static_assert(__is_trivially_copy_assignable(CppEmptyStruct), "");
+
+  static_assert(__is_copy_assignable(CppStructNonStandardBy2ndVirtBase), "");
+  static_assert(__is_nothrow_copy_assignable(CppStructNonStandardBy2ndVirtBase), "");
+  static_assert(__is_trivially_copy_assignable(CppStructNonStandardBy2ndVirtBase), "");
+
+  static_assert(__is_copy_assignable(CppStructNonStandardByBase), "");
+  static_assert(__is_nothrow_copy_assignable(CppStructNonStandardByBase), "");
+  static_assert(__is_trivially_copy_assignable(CppStructNonStandardByBase), "");
+
+  static_assert(__is_copy_assignable(CppStructNonStandardByMemb), "");
+  static_assert(__is_nothrow_copy_assignable(CppStructNonStandardByMemb), "");
+  static_assert(!__is_trivially_copy_assignable(CppStructNonStandardByMemb), "");
+
+  static_assert(__is_copy_assignable(CppStructNonStandardByProt), "");
+  static_assert(__is_nothrow_copy_assignable(CppStructNonStandardByProt), "");
+  static_assert(__is_trivially_copy_assignable(CppStructNonStandardByProt), "");
+
+  static_assert(__is_copy_assignable(CppStructNonStandardBySameBase), "");
+  static_assert(__is_nothrow_copy_assignable(CppStructNonStandardBySameBase), "");
+  static_assert(__is_trivially_copy_assignable(CppStructNonStandardBySameBase), "");
+
+  static_assert(__is_copy_assignable(CppStructNonStandardByVirt), "");
+  static_assert(__is_nothrow_copy_assignable(CppStructNonStandardByVirt), "");
+  static_assert(!__is_trivially_copy_assignable(CppStructNonStandardByVirt), "");
+
+  static_assert(__is_copy_assignable(CppStructNonStandardByVirtBase), "");
+  static_assert(__is_nothrow_copy_assignable(CppStructNonStandardByVirtBase), "");
+  static_assert(!__is_trivially_copy_assignable(CppStructNonStandardByVirtBase), "");
+
+  static_assert(__is_copy_assignable(CppStructStandard), "");
+  static_assert(__is_nothrow_copy_assignable(CppStructStandard), "");
+  static_assert(__is_trivially_copy_assignable(CppStructStandard), "");
+
+  static_assert(__is_copy_assignable(CStruct), "");
+  static_assert(__is_nothrow_copy_assignable(CStruct), "");
+  static_assert(__is_trivially_copy_assignable(CStruct), "");
+
+  static_assert(__is_copy_assignable(CVCopyCtor), "");
+  static_assert(__is_nothrow_copy_assignable(CVCopyCtor), "");
+  static_assert(__is_trivially_copy_assignable(CVCopyCtor), "");
+
+  static_assert(__is_copy_assignable(Derives), "");
+  static_assert(__is_nothrow_copy_assignable(Derives), "");
+  static_assert(__is_trivially_copy_assignable(Derives), "");
+
+  static_assert(__is_copy_assignable(DerivesHasCopyAssign), "");
+  static_assert(!__is_nothrow_copy_assignable(DerivesHasCopyAssign), "");
+  static_assert(!__is_trivially_copy_assignable(DerivesHasCopyAssign), "");
+
+  static_assert(__is_copy_assignable(Empty), "");
+  static_assert(__is_nothrow_copy_assignable(Empty), "");
+  static_assert(__is_trivially_copy_assignable(Empty), "");
+
+  static_assert(__is_copy_assignable(EmptyUnion), "");
+  static_assert(__is_nothrow_copy_assignable(EmptyUnion), "");
+  static_assert(__is_trivially_copy_assignable(EmptyUnion), "");
+
+  static_assert(__is_copy_assignable(Enum), "");
+  static_assert(__is_nothrow_copy_assignable(Enum), "");
+  static_assert(__is_trivially_copy_assignable(Enum), "");
+
+  static_assert(__is_copy_assignable(EnumClass), "");
+  static_assert(__is_nothrow_copy_assignable(EnumClass), "");
+  static_assert(__is_trivially_copy_assignable(EnumClass), "");
+
+  static_assert(__is_copy_assignable(ExtDefaulted), "");
+  static_assert(!__is_nothrow_copy_assignable(ExtDefaulted), "");
+  static_assert(!__is_trivially_copy_assignable(ExtDefaulted), "");
+
+  static_assert(__is_copy_assignable(HasCons), "");
+  static_assert(__is_nothrow_copy_assignable(HasCons), "");
+  static_assert(__is_trivially_copy_assignable(HasCons), "");
+
+  static_assert(__is_copy_assignable(HasCopyAssign), "");
+  static_assert(!__is_nothrow_copy_assignable(HasCopyAssign), "");
+  static_assert(!__is_trivially_copy_assignable(HasCopyAssign), "");
+
+  static_assert(__is_copy_assignable(HasDest), "");
+  static_assert(__is_nothrow_copy_assignable(HasDest), "");
+  static_assert(__is_trivially_copy_assignable(HasDest), "");
+
+  static_assert(__is_copy_assignable(HasMutableCopyCtor), "");
+  static_assert(__is_nothrow_copy_assignable(HasMutableCopyCtor), "");
+  static_assert(__is_trivially_copy_assignable(HasMutableCopyCtor), "");
+
+  static_assert(__is_copy_assignable(HasPriv), "");
+  static_assert(__is_nothrow_copy_assignable(HasPriv), "");
+  static_assert(__is_trivially_copy_assignable(HasPriv), "");
+
+  static_assert(__is_copy_assignable(HasMultipleCopyAssign), "");
+  static_assert(__is_nothrow_copy_assignable(HasMultipleCopyAssign), "");
+  static_assert(!__is_trivially_copy_assignable(HasMultipleCopyAssign), "");
+
+  static_assert(__is_copy_assignable(HasTemplateCons), "");
+  static_assert(__is_nothrow_copy_assignable(HasTemplateCons), "");
+  static_assert(!__is_trivially_copy_assignable(HasTemplateCons), "");
+
+  static_assert(__is_copy_assignable(MemberDeletedCopyCtor), "");
+  static_assert(__is_nothrow_copy_assignable(MemberDeletedCopyCtor), "");
+  static_assert(__is_trivially_copy_assignable(MemberDeletedCopyCtor), "");
+
+  static_assert(__is_copy_assignable(NoDefaultMoveAssignDueToDtor), "");
+  static_assert(__is_nothrow_copy_assignable(NoDefaultMoveAssignDueToDtor), "");
+  static_assert(__is_trivially_copy_assignable(NoDefaultMoveAssignDueToDtor), "");
+
+  static_assert(__is_copy_assignable(NoDefaultMoveAssignDueToUDCopyAssign), "");
+  static_assert(!__is_nothrow_copy_assignable(NoDefaultMoveAssignDueToUDCopyAssign), "");
+  static_assert(!__is_trivially_copy_assignable(NoDefaultMoveAssignDueToUDCopyAssign), "");
+
+  static_assert(__is_copy_assignable(NoDefaultMoveAssignDueToUDCopyCtor), "");
+  static_assert(__is_nothrow_copy_assignable(NoDefaultMoveAssignDueToUDCopyCtor), "");
+  static_assert(__is_trivially_copy_assignable(NoDefaultMoveAssignDueToUDCopyCtor), "");
+
+  static_assert(__is_copy_assignable(NonTCStruct), "");
+  static_assert(__is_nothrow_copy_assignable(NonTCStruct), "");
+  static_assert(__is_trivially_copy_assignable(NonTCStruct), "");
+
+  static_assert(__is_copy_assignable(NonTrivialStruct), "");
+  static_assert(__is_nothrow_copy_assignable(NonTrivialStruct), "");
+  static_assert(__is_trivially_copy_assignable(NonTrivialStruct), "");
+
+  static_assert(__is_copy_assignable(POD), "");
+  static_assert(__is_nothrow_copy_assignable(POD), "");
+  static_assert(__is_trivially_copy_assignable(POD), "");
+
+  static_assert(__is_copy_assignable(SuperNonTrivialStruct), "");
+  static_assert(__is_nothrow_copy_assignable(SuperNonTrivialStruct), "");
+  static_assert(__is_trivially_copy_assignable(SuperNonTrivialStruct), "");
+
+  static_assert(__is_copy_assignable(TrivialStruct), "");
+  static_assert(__is_nothrow_copy_assignable(TrivialStruct), "");
+  static_assert(__is_trivially_copy_assignable(TrivialStruct), "");
+
+  static_assert(__is_copy_assignable(Union), "");
+  static_assert(__is_nothrow_copy_assignable(Union), "");
+  static_assert(__is_trivially_copy_assignable(Union), "");
+
+  static_assert(!__is_copy_assignable(AllDeleted), "");
+  static_assert(!__is_nothrow_copy_assignable(AllDeleted), "");
+  static_assert(!__is_trivially_copy_assignable(AllDeleted), "");
+
+  static_assert(!__is_copy_assignable(AllPrivate), "");
+  static_assert(!__is_nothrow_copy_assignable(AllPrivate), "");
+  static_assert(!__is_trivially_copy_assignable(AllPrivate), "");
+
+  static_assert(!__is_copy_assignable(AnIncompleteType[]), "");
+  static_assert(!__is_nothrow_copy_assignable(AnIncompleteType[]), "");
+  static_assert(!__is_trivially_copy_assignable(AnIncompleteType[]), "");
+
+  static_assert(!__is_copy_assignable(AnIncompleteType), ""); // expected-error{{incomplete type}}
+  static_assert(!__is_nothrow_copy_assignable(AnIncompleteType), ""); // expected-error{{incomplete type}}
+  static_assert(!__is_trivially_copy_assignable(AnIncompleteType), ""); // expected-error{{incomplete type}}
+
+  static_assert(!__is_copy_assignable(DerivesHasRef), "");
+  static_assert(!__is_nothrow_copy_assignable(DerivesHasRef), "");
+  static_assert(!__is_trivially_copy_assignable(DerivesHasRef), "");
+
+  static_assert(!__is_copy_assignable(HasRef), "");
+  static_assert(!__is_nothrow_copy_assignable(HasRef), "");
+  static_assert(!__is_trivially_copy_assignable(HasRef), "");
+
+  static_assert(!__is_copy_assignable(HasMove), "");
+  static_assert(!__is_nothrow_copy_assignable(HasMove), "");
+  static_assert(!__is_trivially_copy_assignable(HasMove), "");
+
+  static_assert(!__is_copy_assignable(HasMoveAssign), "");
+  static_assert(!__is_nothrow_copy_assignable(HasMoveAssign), "");
+  static_assert(!__is_trivially_copy_assignable(HasMoveAssign), "");
+
+  static_assert(!__is_copy_assignable(VirtAr), "");
+  static_assert(!__is_nothrow_copy_assignable(VirtAr), "");
+  static_assert(!__is_trivially_copy_assignable(VirtAr), "");
+
+  static_assert(!__is_copy_assignable(CopyAssignDeleted), "");
+  static_assert(!__is_nothrow_copy_assignable(CopyAssignDeleted), "");
+  static_assert(!__is_trivially_copy_assignable(CopyAssignDeleted), "");
+
+  static_assert(!__is_copy_assignable(BaseDeletedCopyAssign), "");
+  static_assert(!__is_nothrow_copy_assignable(BaseDeletedCopyAssign), "");
+  static_assert(!__is_trivially_copy_assignable(BaseDeletedCopyAssign), "");
+
+  static_assert(!__is_copy_assignable(HasMemberWithDeletedCopyAssign), "");
+  static_assert(!__is_nothrow_copy_assignable(HasMemberWithDeletedCopyAssign), "");
+  static_assert(!__is_trivially_copy_assignable(HasMemberWithDeletedCopyAssign), "");
+
+  static_assert(!__is_copy_assignable(MutableCopyAssign_QualNone), "");
+  static_assert(!__is_nothrow_copy_assignable(MutableCopyAssign_QualNone), "");
+  static_assert(!__is_trivially_copy_assignable(MutableCopyAssign_QualNone), "");
+
+  static_assert(!__is_copy_assignable(MutableCopyAssign_QualConst), "");
+  static_assert(!__is_nothrow_copy_assignable(MutableCopyAssign_QualConst), "");
+  static_assert(!__is_trivially_copy_assignable(MutableCopyAssign_QualConst), "");
+
+  static_assert(!__is_copy_assignable(MutableCopyAssign_QualVolatile), "");
+  static_assert(!__is_nothrow_copy_assignable(MutableCopyAssign_QualVolatile), "");
+  static_assert(!__is_trivially_copy_assignable(MutableCopyAssign_QualVolatile), "");
+
+  static_assert(!__is_copy_assignable(MutableCopyAssign_QualCV), "");
+  static_assert(!__is_nothrow_copy_assignable(MutableCopyAssign_QualCV), "");
+  static_assert(!__is_trivially_copy_assignable(MutableCopyAssign_QualCV), "");
+
+  static_assert(!__is_copy_assignable(MutableCopyAssign_QualLvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(MutableCopyAssign_QualLvalue), "");
+  static_assert(!__is_trivially_copy_assignable(MutableCopyAssign_QualLvalue), "");
+
+  static_assert(!__is_copy_assignable(MutableCopyAssign_QualConstLvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(MutableCopyAssign_QualConstLvalue), "");
+  static_assert(!__is_trivially_copy_assignable(MutableCopyAssign_QualConstLvalue), "");
+
+  static_assert(!__is_copy_assignable(MutableCopyAssign_QualVolatileLvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(MutableCopyAssign_QualVolatileLvalue), "");
+  static_assert(!__is_trivially_copy_assignable(MutableCopyAssign_QualVolatileLvalue), "");
+
+  static_assert(!__is_copy_assignable(MutableCopyAssign_QualCVLvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(MutableCopyAssign_QualCVLvalue), "");
+  static_assert(!__is_trivially_copy_assignable(MutableCopyAssign_QualCVLvalue), "");
+
+  static_assert(!__is_copy_assignable(MutableCopyAssign_QualRvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(MutableCopyAssign_QualRvalue), "");
+  static_assert(!__is_trivially_copy_assignable(MutableCopyAssign_QualRvalue), "");
+
+  static_assert(!__is_copy_assignable(MutableCopyAssign_QualConstRvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(MutableCopyAssign_QualConstRvalue), "");
+  static_assert(!__is_trivially_copy_assignable(MutableCopyAssign_QualConstRvalue), "");
+
+  static_assert(!__is_copy_assignable(MutableCopyAssign_QualVolatileRvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(MutableCopyAssign_QualVolatileRvalue), "");
+  static_assert(!__is_trivially_copy_assignable(MutableCopyAssign_QualVolatileRvalue), "");
+
+  static_assert(!__is_copy_assignable(MutableCopyAssign_QualCVRvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(MutableCopyAssign_QualCVRvalue), "");
+  static_assert(!__is_trivially_copy_assignable(MutableCopyAssign_QualCVRvalue), "");
+
+  static_assert(__is_copy_assignable(CopyAssign_QualNone), "");
+  static_assert(!__is_nothrow_copy_assignable(CopyAssign_QualNone), "");
+  static_assert(!__is_trivially_copy_assignable(CopyAssign_QualNone), "");
+
+  static_assert(__is_copy_assignable(CopyAssign_QualConst), "");
+  static_assert(!__is_nothrow_copy_assignable(CopyAssign_QualConst), "");
+  static_assert(!__is_trivially_copy_assignable(CopyAssign_QualConst), "");
+
+  static_assert(__is_copy_assignable(CopyAssign_QualVolatile), "");
+  static_assert(!__is_nothrow_copy_assignable(CopyAssign_QualVolatile), "");
+  static_assert(!__is_trivially_copy_assignable(CopyAssign_QualVolatile), "");
+
+  static_assert(__is_copy_assignable(CopyAssign_QualCV), "");
+  static_assert(!__is_nothrow_copy_assignable(CopyAssign_QualCV), "");
+  static_assert(!__is_trivially_copy_assignable(CopyAssign_QualCV), "");
+
+  static_assert(__is_copy_assignable(CopyAssign_QualLvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(CopyAssign_QualLvalue), "");
+  static_assert(!__is_trivially_copy_assignable(CopyAssign_QualLvalue), "");
+
+  static_assert(__is_copy_assignable(CopyAssign_QualConstLvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(CopyAssign_QualConstLvalue), "");
+  static_assert(!__is_trivially_copy_assignable(CopyAssign_QualConstLvalue), "");
+
+  static_assert(__is_copy_assignable(CopyAssign_QualVolatileLvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(CopyAssign_QualVolatileLvalue), "");
+  static_assert(!__is_trivially_copy_assignable(CopyAssign_QualVolatileLvalue), "");
+
+  static_assert(__is_copy_assignable(CopyAssign_QualCVLvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(CopyAssign_QualCVLvalue), "");
+  static_assert(!__is_trivially_copy_assignable(CopyAssign_QualCVLvalue), "");
+
+  static_assert(!__is_copy_assignable(CopyAssign_QualRvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(CopyAssign_QualRvalue), "");
+  static_assert(!__is_trivially_copy_assignable(CopyAssign_QualRvalue), "");
+
+  static_assert(!__is_copy_assignable(CopyAssign_QualConstRvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(CopyAssign_QualConstRvalue), "");
+  static_assert(!__is_trivially_copy_assignable(CopyAssign_QualConstRvalue), "");
+
+  static_assert(!__is_copy_assignable(CopyAssign_QualVolatileRvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(CopyAssign_QualVolatileRvalue), "");
+  static_assert(!__is_trivially_copy_assignable(CopyAssign_QualVolatileRvalue), "");
+
+  static_assert(!__is_copy_assignable(CopyAssign_QualCVRvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(CopyAssign_QualCVRvalue), "");
+  static_assert(!__is_trivially_copy_assignable(CopyAssign_QualCVRvalue), "");
+
+  static_assert(!__is_copy_assignable(VolatileCopyAssign_QualNone), "");
+  static_assert(!__is_nothrow_copy_assignable(VolatileCopyAssign_QualNone), "");
+  static_assert(!__is_trivially_copy_assignable(VolatileCopyAssign_QualNone), "");
+
+  static_assert(!__is_copy_assignable(VolatileCopyAssign_QualConst), "");
+  static_assert(!__is_nothrow_copy_assignable(VolatileCopyAssign_QualConst), "");
+  static_assert(!__is_trivially_copy_assignable(VolatileCopyAssign_QualConst), "");
+
+  static_assert(!__is_copy_assignable(VolatileCopyAssign_QualVolatile), "");
+  static_assert(!__is_nothrow_copy_assignable(VolatileCopyAssign_QualVolatile), "");
+  static_assert(!__is_trivially_copy_assignable(VolatileCopyAssign_QualVolatile), "");
+
+  static_assert(!__is_copy_assignable(VolatileCopyAssign_QualCV), "");
+  static_assert(!__is_nothrow_copy_assignable(VolatileCopyAssign_QualCV), "");
+  static_assert(!__is_trivially_copy_assignable(VolatileCopyAssign_QualCV), "");
+
+  static_assert(!__is_copy_assignable(VolatileCopyAssign_QualLvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(VolatileCopyAssign_QualLvalue), "");
+  static_assert(!__is_trivially_copy_assignable(VolatileCopyAssign_QualLvalue), "");
+
+  static_assert(!__is_copy_assignable(VolatileCopyAssign_QualConstLvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(VolatileCopyAssign_QualConstLvalue), "");
+  static_assert(!__is_trivially_copy_assignable(VolatileCopyAssign_QualConstLvalue), "");
+
+  static_assert(!__is_copy_assignable(VolatileCopyAssign_QualVolatileLvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(VolatileCopyAssign_QualVolatileLvalue), "");
+  static_assert(!__is_trivially_copy_assignable(VolatileCopyAssign_QualVolatileLvalue), "");
+
+  static_assert(!__is_copy_assignable(VolatileCopyAssign_QualCVLvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(VolatileCopyAssign_QualCVLvalue), "");
+  static_assert(!__is_trivially_copy_assignable(VolatileCopyAssign_QualCVLvalue), "");
+
+  static_assert(!__is_copy_assignable(VolatileCopyAssign_QualRvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(VolatileCopyAssign_QualRvalue), "");
+  static_assert(!__is_trivially_copy_assignable(VolatileCopyAssign_QualRvalue), "");
+
+  static_assert(!__is_copy_assignable(VolatileCopyAssign_QualConstRvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(VolatileCopyAssign_QualConstRvalue), "");
+  static_assert(!__is_trivially_copy_assignable(VolatileCopyAssign_QualConstRvalue), "");
+
+  static_assert(!__is_copy_assignable(VolatileCopyAssign_QualVolatileRvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(VolatileCopyAssign_QualVolatileRvalue), "");
+  static_assert(!__is_trivially_copy_assignable(VolatileCopyAssign_QualVolatileRvalue), "");
+
+  static_assert(!__is_copy_assignable(VolatileCopyAssign_QualCVRvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(VolatileCopyAssign_QualCVRvalue), "");
+  static_assert(!__is_trivially_copy_assignable(VolatileCopyAssign_QualCVRvalue), "");
+
+  static_assert(__is_copy_assignable(CVCopyAssign_QualNone), "");
+  static_assert(!__is_nothrow_copy_assignable(CVCopyAssign_QualNone), "");
+  static_assert(!__is_trivially_copy_assignable(CVCopyAssign_QualNone), "");
+
+  static_assert(__is_copy_assignable(CVCopyAssign_QualConst), "");
+  static_assert(!__is_nothrow_copy_assignable(CVCopyAssign_QualConst), "");
+  static_assert(!__is_trivially_copy_assignable(CVCopyAssign_QualConst), "");
+
+  static_assert(__is_copy_assignable(CVCopyAssign_QualVolatile), "");
+  static_assert(!__is_nothrow_copy_assignable(CVCopyAssign_QualVolatile), "");
+  static_assert(!__is_trivially_copy_assignable(CVCopyAssign_QualVolatile), "");
+
+  static_assert(__is_copy_assignable(CVCopyAssign_QualCV), "");
+  static_assert(!__is_nothrow_copy_assignable(CVCopyAssign_QualCV), "");
+  static_assert(!__is_trivially_copy_assignable(CVCopyAssign_QualCV), "");
+
+  static_assert(__is_copy_assignable(CVCopyAssign_QualLvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(CVCopyAssign_QualLvalue), "");
+  static_assert(!__is_trivially_copy_assignable(CVCopyAssign_QualLvalue), "");
+
+  static_assert(__is_copy_assignable(CVCopyAssign_QualConstLvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(CVCopyAssign_QualConstLvalue), "");
+  static_assert(!__is_trivially_copy_assignable(CVCopyAssign_QualConstLvalue), "");
+
+  static_assert(__is_copy_assignable(CVCopyAssign_QualVolatileLvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(CVCopyAssign_QualVolatileLvalue), "");
+  static_assert(!__is_trivially_copy_assignable(CVCopyAssign_QualVolatileLvalue), "");
+
+  static_assert(__is_copy_assignable(CVCopyAssign_QualCVLvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(CVCopyAssign_QualCVLvalue), "");
+  static_assert(!__is_trivially_copy_assignable(CVCopyAssign_QualCVLvalue), "");
+
+  static_assert(!__is_copy_assignable(CVCopyAssign_QualRvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(CVCopyAssign_QualRvalue), "");
+  static_assert(!__is_trivially_copy_assignable(CVCopyAssign_QualRvalue), "");
+
+  static_assert(!__is_copy_assignable(CVCopyAssign_QualConstRvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(CVCopyAssign_QualConstRvalue), "");
+  static_assert(!__is_trivially_copy_assignable(CVCopyAssign_QualConstRvalue), "");
+
+  static_assert(!__is_copy_assignable(CVCopyAssign_QualVolatileRvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(CVCopyAssign_QualVolatileRvalue), "");
+  static_assert(!__is_trivially_copy_assignable(CVCopyAssign_QualVolatileRvalue), "");
+
+  static_assert(!__is_copy_assignable(CVCopyAssign_QualCVRvalue), "");
+  static_assert(!__is_nothrow_copy_assignable(CVCopyAssign_QualCVRvalue), "");
+  static_assert(!__is_trivially_copy_assignable(CVCopyAssign_QualCVRvalue), "");
+
+  // Non-referencable types
+  static_assert(!__is_copy_assignable(void), "");
+  static_assert(!__is_nothrow_copy_assignable(void), "");
+  static_assert(!__is_trivially_copy_assignable(void), "");
+
+  static_assert(!__is_copy_assignable(void()), "");
+  static_assert(!__is_nothrow_copy_assignable(void()), "");
+  static_assert(!__is_trivially_copy_assignable(void()), "");
+
+  // cv-qualified types
+  static_assert(!__is_copy_assignable(const int), "");
+  static_assert(!__is_nothrow_copy_assignable(const int), "");
+  static_assert(!__is_trivially_copy_assignable(const int), "");
+
+  static_assert(!__is_copy_assignable(const Empty), "");
+  static_assert(!__is_nothrow_copy_assignable(const Empty), "");
+  static_assert(!__is_trivially_copy_assignable(const Empty), "");
+
+  static_assert(__is_copy_assignable(volatile int), "");
+  static_assert(__is_nothrow_copy_assignable(volatile int), "");
+  static_assert(__is_trivially_copy_assignable(volatile int), "");
+
+  static_assert(!__is_copy_assignable(volatile Empty), "");
+  static_assert(!__is_nothrow_copy_assignable(volatile Empty), "");
+  static_assert(!__is_trivially_copy_assignable(volatile Empty), "");
+
+  static_assert(!__is_copy_assignable(const volatile int), "");
+  static_assert(!__is_nothrow_copy_assignable(const volatile int), "");
+  static_assert(!__is_trivially_copy_assignable(const volatile int), "");
+
+  static_assert(!__is_copy_assignable(const volatile Empty), "");
+  static_assert(!__is_nothrow_copy_assignable(const volatile Empty), "");
+  static_assert(!__is_trivially_copy_assignable(const volatile Empty), "");
+
+  static_assert(__is_copy_assignable(const CopyAssign_QualConst), "");
+  static_assert(!__is_nothrow_copy_assignable(const CopyAssign_QualConst), "");
+  static_assert(!__is_trivially_copy_assignable(const CopyAssign_QualConst), "");
+
+  static_assert(!__is_copy_assignable(volatile CopyAssign_QualVolatile), "");
+  static_assert(!__is_nothrow_copy_assignable(volatile CopyAssign_QualVolatile), "");
+  static_assert(!__is_trivially_copy_assignable(volatile CopyAssign_QualVolatile), "");
+
+  static_assert(!__is_copy_assignable(const volatile CopyAssign_QualCV), "");
+  static_assert(!__is_nothrow_copy_assignable(const volatile CopyAssign_QualCV), "");
+  static_assert(!__is_trivially_copy_assignable(const volatile CopyAssign_QualCV), "");
+
+  static_assert(!__is_copy_assignable(const VolatileCopyAssign_QualConst), "");
+  static_assert(!__is_nothrow_copy_assignable(const VolatileCopyAssign_QualConst), "");
+  static_assert(!__is_trivially_copy_assignable(const VolatileCopyAssign_QualConst), "");
+
+  static_assert(!__is_copy_assignable(volatile VolatileCopyAssign_QualVolatile), "");
+  static_assert(!__is_nothrow_copy_assignable(volatile VolatileCopyAssign_QualVolatile), "");
+  static_assert(!__is_trivially_copy_assignable(volatile VolatileCopyAssign_QualVolatile), "");
+
+  static_assert(!__is_copy_assignable(const volatile VolatileCopyAssign_QualCV), "");
+  static_assert(!__is_nothrow_copy_assignable(const volatile VolatileCopyAssign_QualCV), "");
+  static_assert(!__is_trivially_copy_assignable(const volatile VolatileCopyAssign_QualCV), "");
+
+  static_assert(__is_copy_assignable(const CVCopyAssign_QualConst), "");
+  static_assert(!__is_nothrow_copy_assignable(const CVCopyAssign_QualConst), "");
+  static_assert(!__is_trivially_copy_assignable(const CVCopyAssign_QualConst), "");
+
+  static_assert(__is_copy_assignable(volatile CVCopyAssign_QualVolatile), "");
+  static_assert(!__is_nothrow_copy_assignable(volatile CVCopyAssign_QualVolatile), "");
+  static_assert(!__is_trivially_copy_assignable(volatile CVCopyAssign_QualVolatile), "");
+
+  static_assert(__is_copy_assignable(const volatile CVCopyAssign_QualCV), "");
+  static_assert(!__is_nothrow_copy_assignable(const volatile CVCopyAssign_QualCV), "");
+  static_assert(!__is_trivially_copy_assignable(const volatile CVCopyAssign_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
@@ -5,11 +5,11 @@
 void f() {
     bool a;
 
-    a = __has_nothrow_assign(A);  // expected-warning-re {{__has_nothrow_assign {{.*}} use __is_nothrow_assignable}}
+    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_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_assignable}}
+    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_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}}
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -4851,6 +4851,9 @@
   case UTT_IsCopyConstructible:
   case UTT_IsTriviallyCopyConstructible:
   case UTT_IsNothrowCopyConstructible:
+  case UTT_IsCopyAssignable:
+  case UTT_IsTriviallyCopyAssignable:
+  case UTT_IsNothrowCopyAssignable:
     if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType())
       return true;
 
@@ -5316,7 +5319,10 @@
     return T.isTriviallyRelocatableType(C);
   case UTT_IsCopyConstructible:
   case UTT_IsTriviallyCopyConstructible:
-  case UTT_IsNothrowCopyConstructible: {
+  case UTT_IsNothrowCopyConstructible:
+  case UTT_IsCopyAssignable:
+  case UTT_IsTriviallyCopyAssignable:
+  case UTT_IsNothrowCopyAssignable: {
     if (T->isIncompleteArrayType())
       return false;
     if (!T.isReferenceable())
@@ -5326,6 +5332,16 @@
     AssigneeType.addConst();
     AssigneeType = Self.BuiltinAddReference(
         AssigneeType, UnaryTransformType::AddLvalueReference, KeyLoc);
+    if (UTT == UTT_IsCopyAssignable || UTT == UTT_IsTriviallyCopyAssignable ||
+        UTT == UTT_IsNothrowCopyAssignable) {
+      return EvaluateBinaryTypeTrait(
+          Self,
+          UTT == UTT_IsCopyAssignable            ? BTT_IsAssignable
+          : UTT == UTT_IsTriviallyCopyAssignable ? 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,
@@ -5468,32 +5484,36 @@
                                 SourceLocation KWLoc) {
   TypeTrait Replacement;
   switch (Kind) {
-    case UTT_HasNothrowAssign:
-    case UTT_HasNothrowMoveAssign:
-      Replacement = BTT_IsNothrowAssignable;
-      break;
-    case UTT_HasNothrowCopy:
-      Replacement = UTT_IsNothrowCopyConstructible;
-      break;
-    case UTT_HasNothrowConstructor:
-      Replacement = TT_IsNothrowConstructible;
-      break;
-    case UTT_HasTrivialAssign:
-    case UTT_HasTrivialMoveAssign:
-      Replacement = BTT_IsTriviallyAssignable;
-      break;
-    case UTT_HasTrivialCopy:
-      Replacement = UTT_IsTriviallyCopyConstructible;
-      break;
-    case UTT_HasTrivialDefaultConstructor:
-    case UTT_HasTrivialMoveConstructor:
-      Replacement = TT_IsTriviallyConstructible;
-      break;
-    case UTT_HasTrivialDestructor:
-      Replacement = UTT_IsTriviallyDestructible;
-      break;
-    default:
-      return;
+  case UTT_HasNothrowAssign: // despite its name, this checks copy assignment
+    Replacement = UTT_IsNothrowCopyAssignable;
+    break;
+  case UTT_HasNothrowMoveAssign:
+    Replacement = BTT_IsNothrowAssignable;
+    break;
+  case UTT_HasNothrowCopy:
+    Replacement = UTT_IsNothrowCopyConstructible;
+    break;
+  case UTT_HasNothrowConstructor:
+    Replacement = TT_IsNothrowConstructible;
+    break;
+  case UTT_HasTrivialAssign: // despite its name, this checks copy assignment
+    Replacement = UTT_IsTriviallyCopyAssignable;
+    break;
+  case UTT_HasTrivialMoveAssign:
+    Replacement = BTT_IsTriviallyAssignable;
+    break;
+  case UTT_HasTrivialCopy:
+    Replacement = UTT_IsTriviallyCopyConstructible;
+    break;
+  case UTT_HasTrivialDefaultConstructor:
+  case UTT_HasTrivialMoveConstructor:
+    Replacement = TT_IsTriviallyConstructible;
+    break;
+  case UTT_HasTrivialDestructor:
+    Replacement = UTT_IsTriviallyDestructible;
+    break;
+  default:
+    return;
   }
   S.Diag(KWLoc, diag::warn_deprecated_builtin)
     << getTraitSpelling(Kind) << getTraitSpelling(Replacement);
Index: clang/lib/Parse/ParseExpr.cpp
===================================================================
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -1076,6 +1076,7 @@
           REVERTIBLE_TYPE_TRAIT(__is_constructible);
           REVERTIBLE_TYPE_TRAIT(__is_convertible_to);
           REVERTIBLE_TYPE_TRAIT(__is_convertible);
+          REVERTIBLE_TYPE_TRAIT(__is_copy_assignable);
           REVERTIBLE_TYPE_TRAIT(__is_copy_constructible);
           REVERTIBLE_TYPE_TRAIT(__is_destructible);
           REVERTIBLE_TYPE_TRAIT(__is_empty);
@@ -1094,6 +1095,7 @@
           REVERTIBLE_TYPE_TRAIT(__is_member_pointer);
           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_destructible);
           REVERTIBLE_TYPE_TRAIT(__is_nullptr);
@@ -1114,6 +1116,7 @@
           REVERTIBLE_TYPE_TRAIT(__is_trivial);
           REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable);
           REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible);
+          REVERTIBLE_TYPE_TRAIT(__is_trivially_copy_assignable);
           REVERTIBLE_TYPE_TRAIT(__is_trivially_copy_constructible);
           REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable);
           REVERTIBLE_TYPE_TRAIT(__is_unbounded_array);
Index: clang/lib/Parse/ParseDeclCXX.cpp
===================================================================
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -1586,6 +1586,7 @@
           tok::kw___is_const,
           tok::kw___is_constructible,
           tok::kw___is_copy_constructible,
+          tok::kw___is_copy_assignable,
           tok::kw___is_convertible,
           tok::kw___is_convertible_to,
           tok::kw___is_destructible,
@@ -1605,6 +1606,7 @@
           tok::kw___is_member_pointer,
           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_nullptr,
@@ -1625,6 +1627,7 @@
           tok::kw___is_trivial,
           tok::kw___is_trivially_assignable,
           tok::kw___is_trivially_constructible,
+          tok::kw___is_trivially_copy_assignable,
           tok::kw___is_trivially_copy_constructible,
           tok::kw___is_trivially_copyable,
           tok::kw___is_unbounded_array,
Index: clang/include/clang/Basic/TokenKinds.def
===================================================================
--- clang/include/clang/Basic/TokenKinds.def
+++ clang/include/clang/Basic/TokenKinds.def
@@ -526,6 +526,9 @@
 TYPE_TRAIT_1(__is_copy_constructible, IsCopyConstructible, KEYCXX)
 TYPE_TRAIT_1(__is_nothrow_copy_constructible, IsNothrowCopyConstructible, KEYCXX)
 TYPE_TRAIT_1(__is_trivially_copy_constructible, IsTriviallyCopyConstructible, KEYCXX)
+TYPE_TRAIT_1(__is_copy_assignable, IsCopyAssignable, KEYCXX)
+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)
 
 // Embarcadero Expression Traits
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D135239: [cla... Christopher Di Bella via Phabricator via cfe-commits

Reply via email to