cjdb updated this revision to Diff 455051.
cjdb edited the summary of this revision.
cjdb added a comment.

changes RemoveReference to BuiltinRemoveReference


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116280/new/

https://reviews.llvm.org/D116280

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TokenKinds.def
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaType.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
@@ -345,11 +345,19 @@
 }
 
 typedef Enum EnumType;
+typedef EnumClass EnumClassType;
 
 void is_enum()
 {
   { int arr[T(__is_enum(Enum))]; }
   { int arr[T(__is_enum(EnumType))]; }
+  { int arr[T(__is_enum(SignedEnum))]; }
+  { int arr[T(__is_enum(UnsignedEnum))]; }
+
+  { int arr[T(__is_enum(EnumClass))]; }
+  { int arr[T(__is_enum(EnumClassType))]; }
+  { int arr[T(__is_enum(SignedEnumClass))]; }
+  { int arr[T(__is_enum(UnsignedEnumClass))]; }
 
   { int arr[F(__is_enum(int))]; }
   { int arr[F(__is_enum(Union))]; }
@@ -363,6 +371,29 @@
   { int arr[F(__is_enum(HasAnonymousUnion))]; }
 }
 
+void is_scoped_enum() {
+  { int arr[F(__is_scoped_enum(Enum))]; }
+  { int arr[F(__is_scoped_enum(EnumType))]; }
+  { int arr[F(__is_scoped_enum(SignedEnum))]; }
+  { int arr[F(__is_scoped_enum(UnsignedEnum))]; }
+
+  { int arr[T(__is_scoped_enum(EnumClass))]; }
+  { int arr[T(__is_scoped_enum(EnumClassType))]; }
+  { int arr[T(__is_scoped_enum(SignedEnumClass))]; }
+  { int arr[T(__is_scoped_enum(UnsignedEnumClass))]; }
+
+  { int arr[F(__is_scoped_enum(int))]; }
+  { int arr[F(__is_scoped_enum(Union))]; }
+  { int arr[F(__is_scoped_enum(Int))]; }
+  { int arr[F(__is_scoped_enum(IntAr))]; }
+  { int arr[F(__is_scoped_enum(UnionAr))]; }
+  { int arr[F(__is_scoped_enum(Derives))]; }
+  { int arr[F(__is_scoped_enum(ClassType))]; }
+  { int arr[F(__is_scoped_enum(cvoid))]; }
+  { int arr[F(__is_scoped_enum(IntArNB))]; }
+  { int arr[F(__is_scoped_enum(HasAnonymousUnion))]; }
+}
+
 struct FinalClass final {
 };
 
@@ -702,6 +733,106 @@
   int t31[F(__is_array(cvoid*))];
 }
 
+void is_bounded_array(int n) {
+  int t01[T(__is_bounded_array(IntAr))];
+  int t02[F(__is_bounded_array(IntArNB))];
+  int t03[T(__is_bounded_array(UnionAr))];
+
+  int t10[F(__is_bounded_array(void))];
+  int t11[F(__is_bounded_array(cvoid))];
+  int t12[F(__is_bounded_array(float))];
+  int t13[F(__is_bounded_array(double))];
+  int t14[F(__is_bounded_array(long double))];
+  int t15[F(__is_bounded_array(bool))];
+  int t16[F(__is_bounded_array(char))];
+  int t17[F(__is_bounded_array(signed char))];
+  int t18[F(__is_bounded_array(unsigned char))];
+  int t19[F(__is_bounded_array(wchar_t))];
+  int t20[F(__is_bounded_array(short))];
+  int t21[F(__is_bounded_array(unsigned short))];
+  int t22[F(__is_bounded_array(int))];
+  int t23[F(__is_bounded_array(unsigned int))];
+  int t24[F(__is_bounded_array(long))];
+  int t25[F(__is_bounded_array(unsigned long))];
+  int t26[F(__is_bounded_array(Union))];
+  int t27[F(__is_bounded_array(Derives))];
+  int t28[F(__is_bounded_array(ClassType))];
+  int t29[F(__is_bounded_array(Enum))];
+  int t30[F(__is_bounded_array(void *))];
+  int t31[F(__is_bounded_array(cvoid *))];
+
+  int t32[n];
+  (void)__is_bounded_array(decltype(t32)); // expected-error{{variable length arrays are not supported for '__is_bounded_array'}}
+}
+
+void is_unbounded_array(int n) {
+  int t01[F(__is_unbounded_array(IntAr))];
+  int t02[T(__is_unbounded_array(IntArNB))];
+  int t03[F(__is_unbounded_array(UnionAr))];
+
+  int t10[F(__is_unbounded_array(void))];
+  int t11[F(__is_unbounded_array(cvoid))];
+  int t12[F(__is_unbounded_array(float))];
+  int t13[F(__is_unbounded_array(double))];
+  int t14[F(__is_unbounded_array(long double))];
+  int t15[F(__is_unbounded_array(bool))];
+  int t16[F(__is_unbounded_array(char))];
+  int t17[F(__is_unbounded_array(signed char))];
+  int t18[F(__is_unbounded_array(unsigned char))];
+  int t19[F(__is_unbounded_array(wchar_t))];
+  int t20[F(__is_unbounded_array(short))];
+  int t21[F(__is_unbounded_array(unsigned short))];
+  int t22[F(__is_unbounded_array(int))];
+  int t23[F(__is_unbounded_array(unsigned int))];
+  int t24[F(__is_unbounded_array(long))];
+  int t25[F(__is_unbounded_array(unsigned long))];
+  int t26[F(__is_unbounded_array(Union))];
+  int t27[F(__is_unbounded_array(Derives))];
+  int t28[F(__is_unbounded_array(ClassType))];
+  int t29[F(__is_unbounded_array(Enum))];
+  int t30[F(__is_unbounded_array(void *))];
+  int t31[F(__is_unbounded_array(cvoid *))];
+
+  int t32[n];
+  (void)__is_unbounded_array(decltype(t32)); // expected-error{{variable length arrays are not supported for '__is_unbounded_array'}}
+}
+
+void is_referenceable() {
+  { int a[T(__is_referenceable(int))]; }
+  { int a[T(__is_referenceable(const int))]; }
+  { int a[T(__is_referenceable(volatile int))]; }
+  { int a[T(__is_referenceable(const volatile int))]; }
+  { int a[T(__is_referenceable(int *))]; }
+  { int a[T(__is_referenceable(int &))]; }
+  { int a[T(__is_referenceable(int &&))]; }
+  { int a[T(__is_referenceable(int (*)()))]; }
+  { int a[T(__is_referenceable(int (&)()))]; }
+  { int a[T(__is_referenceable(int(&&)()))]; }
+  { int a[T(__is_referenceable(IntAr))]; }
+  { int a[T(__is_referenceable(IntArNB))]; }
+  { int a[T(__is_referenceable(decltype(nullptr)))]; }
+  { int a[T(__is_referenceable(Empty))]; }
+  { int a[T(__is_referenceable(Union))]; }
+  { int a[T(__is_referenceable(Derives))]; }
+  { int a[T(__is_referenceable(Enum))]; }
+  { int a[T(__is_referenceable(EnumClass))]; }
+  { int a[T(__is_referenceable(int Empty::*))]; }
+  { int a[T(__is_referenceable(int(Empty::*)()))]; }
+  { int a[T(__is_referenceable(int(Empty::*)() const))]; }
+  { int a[T(__is_referenceable(int(Empty::*)() volatile))]; }
+  { int a[T(__is_referenceable(int(Empty::*)() const volatile))]; }
+  { int a[T(__is_referenceable(int(Empty::*)() &))]; }
+  { int a[T(__is_referenceable(int(Empty::*)() const &))]; }
+  { int a[T(__is_referenceable(int(Empty::*)() volatile &))]; }
+  { int a[T(__is_referenceable(int(Empty::*)() const volatile &))]; }
+  { int a[T(__is_referenceable(int(Empty::*)() &&))]; }
+  { int a[T(__is_referenceable(int(Empty::*)() const &&))]; }
+  { int a[T(__is_referenceable(int(Empty::*)() volatile &&))]; }
+  { int a[T(__is_referenceable(int(Empty::*)() const volatile &&))]; }
+
+  { int a[F(__is_referenceable(void))]; }
+}
+
 template <typename T> void tmpl_func(T&) {}
 
 template <typename T> struct type_wrapper {
@@ -934,6 +1065,42 @@
   int t34[F(__is_pointer(void (StructWithMembers::*) ()))];
 }
 
+void is_null_pointer() {
+  StructWithMembers x;
+
+  int t00[T(__is_nullptr(decltype(nullptr)))];
+  int t01[F(__is_nullptr(void *))];
+  int t02[F(__is_nullptr(cvoid *))];
+  int t03[F(__is_nullptr(cvoid *))];
+  int t04[F(__is_nullptr(char *))];
+  int t05[F(__is_nullptr(int *))];
+  int t06[F(__is_nullptr(int **))];
+  int t07[F(__is_nullptr(ClassType *))];
+  int t08[F(__is_nullptr(Derives *))];
+  int t09[F(__is_nullptr(Enum *))];
+  int t10[F(__is_nullptr(IntArNB *))];
+  int t11[F(__is_nullptr(Union *))];
+  int t12[F(__is_nullptr(UnionAr *))];
+  int t13[F(__is_nullptr(StructWithMembers *))];
+  int t14[F(__is_nullptr(void (*)()))];
+
+  int t20[F(__is_nullptr(void))];
+  int t21[F(__is_nullptr(cvoid))];
+  int t22[F(__is_nullptr(cvoid))];
+  int t23[F(__is_nullptr(char))];
+  int t24[F(__is_nullptr(int))];
+  int t25[F(__is_nullptr(int))];
+  int t26[F(__is_nullptr(ClassType))];
+  int t27[F(__is_nullptr(Derives))];
+  int t28[F(__is_nullptr(Enum))];
+  int t29[F(__is_nullptr(IntArNB))];
+  int t30[F(__is_nullptr(Union))];
+  int t31[F(__is_nullptr(UnionAr))];
+  int t32[F(__is_nullptr(StructWithMembers))];
+  int t33[F(__is_nullptr(int StructWithMembers::*))];
+  int t34[F(__is_nullptr(void(StructWithMembers::*)()))];
+}
+
 void is_member_object_pointer()
 {
   StructWithMembers x;
@@ -1481,8 +1648,8 @@
 typedef const IntAr ConstIntAr;
 typedef ConstIntAr ConstIntArAr[4];
 
-struct HasCopy {
-  HasCopy(HasCopy& cp);
+struct HasMutableCopyCtor {
+  HasMutableCopyCtor(HasMutableCopyCtor &cp);
 };
 
 struct HasMove {
@@ -1518,7 +1685,7 @@
   { int arr[F(__has_trivial_constructor(AnIncompleteType[]))]; } // expected-error {{incomplete type}}
   { int arr[F(__has_trivial_constructor(HasCons))]; }
   { int arr[F(__has_trivial_constructor(HasRef))]; }
-  { int arr[F(__has_trivial_constructor(HasCopy))]; }
+  { int arr[F(__has_trivial_constructor(HasMutableCopyCtor))]; }
   { int arr[F(__has_trivial_constructor(IntRef))]; }
   { int arr[F(__has_trivial_constructor(VirtAr))]; }
   { int arr[F(__has_trivial_constructor(void))]; }
@@ -1581,7 +1748,7 @@
   { int arr[T(__has_trivial_copy(ACompleteType[]))]; }
 
   { int arr[F(__has_trivial_copy(AnIncompleteType[]))]; } // expected-error {{incomplete type}}
-  { int arr[F(__has_trivial_copy(HasCopy))]; }
+  { int arr[F(__has_trivial_copy(HasMutableCopyCtor))]; }
   { int arr[F(__has_trivial_copy(HasTemplateCons))]; }
   { int arr[F(__has_trivial_copy(VirtAr))]; }
   { int arr[F(__has_trivial_copy(void))]; }
@@ -1601,7 +1768,7 @@
   { int arr[T(__has_trivial_assign(HasPriv))]; }
   { int arr[T(__has_trivial_assign(HasCons))]; }
   { int arr[T(__has_trivial_assign(HasRef))]; }
-  { int arr[T(__has_trivial_assign(HasCopy))]; }
+  { int arr[T(__has_trivial_assign(HasMutableCopyCtor))]; }
   { int arr[T(__has_trivial_assign(HasMove))]; }
   { int arr[T(__has_trivial_assign(HasMoveAssign))]; }
   { int arr[T(__has_trivial_assign(AllDefaulted))]; }
@@ -1635,7 +1802,7 @@
   { int arr[T(__has_trivial_destructor(HasPriv))]; }
   { int arr[T(__has_trivial_destructor(HasCons))]; }
   { int arr[T(__has_trivial_destructor(HasRef))]; }
-  { int arr[T(__has_trivial_destructor(HasCopy))]; }
+  { int arr[T(__has_trivial_destructor(HasMutableCopyCtor))]; }
   { int arr[T(__has_trivial_destructor(HasMove))]; }
   { int arr[T(__has_trivial_destructor(IntRef))]; }
   { int arr[T(__has_trivial_destructor(HasCopyAssign))]; }
@@ -1692,7 +1859,7 @@
   { int arr[T(__has_nothrow_assign(HasPriv))]; }
   { int arr[T(__has_nothrow_assign(HasCons))]; }
   { int arr[T(__has_nothrow_assign(HasRef))]; }
-  { int arr[T(__has_nothrow_assign(HasCopy))]; }
+  { int arr[T(__has_nothrow_assign(HasMutableCopyCtor))]; }
   { int arr[T(__has_nothrow_assign(HasMove))]; }
   { int arr[T(__has_nothrow_assign(HasMoveAssign))]; }
   { int arr[T(__has_nothrow_assign(HasNoThrowCopyAssign))]; }
@@ -1801,7 +1968,7 @@
   { int arr[T(__has_nothrow_copy(ACompleteType[]))]; }
 
   { int arr[F(__has_nothrow_copy(AnIncompleteType[]))]; } // expected-error {{incomplete type}}
-  { int arr[F(__has_nothrow_copy(HasCopy))]; }
+  { int arr[F(__has_nothrow_copy(HasMutableCopyCtor))]; }
   { int arr[F(__has_nothrow_copy(HasMultipleCopy))]; }
   { int arr[F(__has_nothrow_copy(VirtAr))]; }
   { int arr[F(__has_nothrow_copy(void))]; }
@@ -1831,7 +1998,7 @@
   { int arr[F(__has_nothrow_constructor(AnIncompleteType[]))]; } // expected-error {{incomplete type}}
   { int arr[F(__has_nothrow_constructor(HasCons))]; }
   { int arr[F(__has_nothrow_constructor(HasRef))]; }
-  { int arr[F(__has_nothrow_constructor(HasCopy))]; }
+  { int arr[F(__has_nothrow_constructor(HasMutableCopyCtor))]; }
   { int arr[F(__has_nothrow_constructor(HasMove))]; }
   { int arr[F(__has_nothrow_constructor(HasNoThrowConstructorWithArgs))]; }
   { int arr[F(__has_nothrow_constructor(IntRef))]; }
@@ -1858,7 +2025,7 @@
   { int arr[F(__has_virtual_destructor(HasPriv))]; }
   { int arr[F(__has_virtual_destructor(HasCons))]; }
   { int arr[F(__has_virtual_destructor(HasRef))]; }
-  { int arr[F(__has_virtual_destructor(HasCopy))]; }
+  { int arr[F(__has_virtual_destructor(HasMutableCopyCtor))]; }
   { int arr[F(__has_virtual_destructor(HasMove))]; }
   { int arr[F(__has_virtual_destructor(HasCopyAssign))]; }
   { int arr[F(__has_virtual_destructor(HasMoveAssign))]; }
@@ -2325,6 +2492,876 @@
   { int arr[F(__is_nothrow_constructible(const volatile void))]; }
 }
 
+struct VolatileCopyCtor {
+  VolatileCopyCtor(volatile VolatileCopyCtor &);
+};
+
+struct CVCopyCtor {
+  CVCopyCtor(const volatile CVCopyCtor &);
+};
+
+struct CopyCtorDeleted {
+  CopyCtorDeleted(const CopyCtorDeleted &) = delete;
+};
+
+struct BaseDeletedCopyCtor : CopyCtorDeleted {};
+
+struct MemberDeletedCopyCtor {
+  CopyCtorDeleted x;
+};
+
+template <bool expected, typename T>
+void copy_constructible_checks_impl() {
+  { int arr[T(__is_copy_constructible(T) == expected)]; }                // expected-error{{incomplete type}}
+  { int arr[T(__is_copy_constructible(const T) == expected)]; }          // expected-error{{incomplete type}}
+  { int arr[T(__is_copy_constructible(volatile T) == expected)]; }       // expected-error{{incomplete type}}
+  { int arr[T(__is_copy_constructible(const volatile T) == expected)]; } // expected-error{{incomplete type}}
+}
+
+void copy_constructible_checks() {
+  // Builtin types
+  copy_constructible_checks_impl<true, int>();
+  copy_constructible_checks_impl<false, int &>();
+  copy_constructible_checks_impl<false, int &&>();
+  copy_constructible_checks_impl<true, int *>();
+  copy_constructible_checks_impl<false, int[5]>();
+  copy_constructible_checks_impl<false, int[]>();
+  copy_constructible_checks_impl<true, decltype(nullptr)>();
+  copy_constructible_checks_impl<true, void (*)()>();
+  copy_constructible_checks_impl<false, void (&)()>();
+  copy_constructible_checks_impl<true, int Empty::*>();
+  copy_constructible_checks_impl<true, int (Empty::*)()>();
+  copy_constructible_checks_impl<true, int (Empty::*)() const>();
+  copy_constructible_checks_impl<true, int (Empty::*)() volatile>();
+  copy_constructible_checks_impl<true, int (Empty::*)() const volatile>();
+  copy_constructible_checks_impl<true, int (Empty::*)() &>();
+  copy_constructible_checks_impl<true, int (Empty::*)() const &>();
+  copy_constructible_checks_impl<true, int (Empty::*)() volatile &>();
+  copy_constructible_checks_impl<true, int (Empty::*)() const volatile &>();
+  copy_constructible_checks_impl<true, int (Empty::*)() &&>();
+  copy_constructible_checks_impl<true, int (Empty::*)() const &&>();
+  copy_constructible_checks_impl<true, int (Empty::*)() volatile &&>();
+  copy_constructible_checks_impl<true, int (Empty::*)() const volatile &&>();
+
+  // // User-defined types
+  copy_constructible_checks_impl<true, AllDefaulted>();
+  copy_constructible_checks_impl<true, AllDefaulted>();
+  copy_constructible_checks_impl<true, CEmptyStruct>();
+  copy_constructible_checks_impl<true, CppEmptyStruct>();
+  copy_constructible_checks_impl<true, CppStructNonStandardBy2ndVirtBase>();
+  copy_constructible_checks_impl<true, CppStructNonStandardByBase>();
+  copy_constructible_checks_impl<true, CppStructNonStandardByMemb>();
+  copy_constructible_checks_impl<true, CppStructNonStandardByProt>();
+  copy_constructible_checks_impl<true, CppStructNonStandardBySameBase>();
+  copy_constructible_checks_impl<true, CppStructNonStandardByVirt>();
+  copy_constructible_checks_impl<true, CppStructNonStandardByVirtBase>();
+  copy_constructible_checks_impl<true, CppStructStandard>();
+  copy_constructible_checks_impl<true, CStruct>();
+  copy_constructible_checks_impl<true, CVCopyCtor>();
+  copy_constructible_checks_impl<true, Derives>();
+  copy_constructible_checks_impl<true, DerivesHasRef>();
+  copy_constructible_checks_impl<true, Empty>();
+  copy_constructible_checks_impl<true, EmptyUnion>();
+  copy_constructible_checks_impl<true, Enum>();
+  copy_constructible_checks_impl<true, EnumClass>();
+  copy_constructible_checks_impl<true, ExtDefaulted>();
+  copy_constructible_checks_impl<true, ExtDefaulted>();
+  copy_constructible_checks_impl<true, HasCons>();
+  copy_constructible_checks_impl<true, HasCopyAssign>();
+  copy_constructible_checks_impl<true, HasDest>();
+  copy_constructible_checks_impl<true, HasMultipleCopy>();
+  copy_constructible_checks_impl<true, HasPriv>();
+  copy_constructible_checks_impl<true, HasRef>();
+  copy_constructible_checks_impl<true, HasTemplateCons>();
+  copy_constructible_checks_impl<true, NoDefaultMoveAssignDueToDtor>();
+  copy_constructible_checks_impl<true, NoDefaultMoveAssignDueToUDCopyAssign>();
+  copy_constructible_checks_impl<true, NoDefaultMoveAssignDueToUDCopyCtor>();
+  copy_constructible_checks_impl<true, NonTCStruct>();
+  copy_constructible_checks_impl<true, NonTrivialStruct>();
+  copy_constructible_checks_impl<true, POD>();
+  copy_constructible_checks_impl<true, SuperNonTrivialStruct>();
+  copy_constructible_checks_impl<true, TrivialStruct>();
+  copy_constructible_checks_impl<true, Union>();
+
+  copy_constructible_checks_impl<false, AllDeleted>();
+  copy_constructible_checks_impl<false, AllPrivate>();
+  copy_constructible_checks_impl<false, AnIncompleteType[]>();
+  copy_constructible_checks_impl<false, AnIncompleteType>(); // expected-note{{in instantiation of function template specialization}}
+  copy_constructible_checks_impl<false, BaseDeletedCopyCtor>();
+  copy_constructible_checks_impl<false, CopyCtorDeleted>();
+  copy_constructible_checks_impl<false, HasMutableCopyCtor>();
+  copy_constructible_checks_impl<false, HasMove>();
+  copy_constructible_checks_impl<false, HasMoveAssign>();
+  copy_constructible_checks_impl<false, MemberDeletedCopyCtor>();
+  copy_constructible_checks_impl<false, VirtAr>();
+  copy_constructible_checks_impl<false, VolatileCopyCtor>();
+
+  // Non-referencable types
+  copy_constructible_checks_impl<false, void>();
+  copy_constructible_checks_impl<false, void()>();
+  copy_constructible_checks_impl<false, void() const>();
+  copy_constructible_checks_impl<false, void() volatile>();
+  copy_constructible_checks_impl<false, void() const volatile>();
+  copy_constructible_checks_impl<false, void() &>();
+  copy_constructible_checks_impl<false, void() const &>();
+  copy_constructible_checks_impl<false, void() volatile &>();
+  copy_constructible_checks_impl<false, void() const volatile &>();
+  copy_constructible_checks_impl<false, void() &&>();
+  copy_constructible_checks_impl<false, void() const &&>();
+  copy_constructible_checks_impl<false, void() volatile &&>();
+  copy_constructible_checks_impl<false, void() const volatile &&>();
+}
+
+struct ConstMoveCtor {
+  ConstMoveCtor(const ConstMoveCtor &&);
+};
+
+struct VolatileMoveCtor {
+  VolatileMoveCtor(volatile VolatileMoveCtor &&);
+};
+
+struct CVMoveCtor {
+  CVMoveCtor(const volatile CVMoveCtor &&);
+};
+
+struct MoveCtorDeleted {
+  MoveCtorDeleted(MoveCtorDeleted &&) = delete;
+};
+
+struct BaseDeletedMoveCtor : MoveCtorDeleted {};
+
+struct MemberDeletedMoveCtor {
+  MoveCtorDeleted x;
+};
+
+template <bool expected, typename T>
+void move_constructible_checks_impl() {
+  { int arr[T(__is_move_constructible(T) == expected)]; }                // expected-error{{incomplete type}}
+  { int arr[T(__is_move_constructible(const T) == expected)]; }          // expected-error{{incomplete type}}
+  { int arr[T(__is_move_constructible(volatile T) == expected)]; }       // expected-error{{incomplete type}}
+  { int arr[T(__is_move_constructible(const volatile T) == expected)]; } // expected-error{{incomplete type}}
+}
+
+void move_constructible_checks() {
+  // Builtin types
+  move_constructible_checks_impl<true, int>();
+  move_constructible_checks_impl<false, int &>();
+  move_constructible_checks_impl<true, int &&>();
+  move_constructible_checks_impl<true, int *>();
+  move_constructible_checks_impl<false, int[5]>();
+  move_constructible_checks_impl<false, int[]>();
+  move_constructible_checks_impl<true, decltype(nullptr)>();
+  move_constructible_checks_impl<true, void (*)()>();
+  move_constructible_checks_impl<true, void (&)()>();
+  move_constructible_checks_impl<true, int Empty::*>();
+  move_constructible_checks_impl<true, int (Empty::*)()>();
+  move_constructible_checks_impl<true, int (Empty::*)() const>();
+  move_constructible_checks_impl<true, int (Empty::*)() volatile>();
+  move_constructible_checks_impl<true, int (Empty::*)() const volatile>();
+  move_constructible_checks_impl<true, int (Empty::*)() &>();
+  move_constructible_checks_impl<true, int (Empty::*)() const &>();
+  move_constructible_checks_impl<true, int (Empty::*)() volatile &>();
+  move_constructible_checks_impl<true, int (Empty::*)() const volatile &>();
+  move_constructible_checks_impl<true, int (Empty::*)() &&>();
+  move_constructible_checks_impl<true, int (Empty::*)() const &&>();
+  move_constructible_checks_impl<true, int (Empty::*)() volatile &&>();
+  move_constructible_checks_impl<true, int (Empty::*)() const volatile &&>();
+
+  // // User-defined types
+  move_constructible_checks_impl<true, AllDefaulted>();
+  move_constructible_checks_impl<true, AllDefaulted>();
+  move_constructible_checks_impl<true, CEmptyStruct>();
+  move_constructible_checks_impl<true, ConstMoveCtor>();
+  move_constructible_checks_impl<true, CppEmptyStruct>();
+  move_constructible_checks_impl<true, CppStructNonStandardBy2ndVirtBase>();
+  move_constructible_checks_impl<true, CppStructNonStandardByBase>();
+  move_constructible_checks_impl<true, CppStructNonStandardByMemb>();
+  move_constructible_checks_impl<true, CppStructNonStandardByProt>();
+  move_constructible_checks_impl<true, CppStructNonStandardBySameBase>();
+  move_constructible_checks_impl<true, CppStructNonStandardByVirt>();
+  move_constructible_checks_impl<true, CppStructNonStandardByVirtBase>();
+  move_constructible_checks_impl<true, CppStructStandard>();
+  move_constructible_checks_impl<true, CStruct>();
+  move_constructible_checks_impl<true, CVMoveCtor>();
+  move_constructible_checks_impl<true, Derives>();
+  move_constructible_checks_impl<true, DerivesHasRef>();
+  move_constructible_checks_impl<true, Empty>();
+  move_constructible_checks_impl<true, EmptyUnion>();
+  move_constructible_checks_impl<true, Enum>();
+  move_constructible_checks_impl<true, EnumClass>();
+  move_constructible_checks_impl<true, ExtDefaulted>();
+  move_constructible_checks_impl<true, ExtDefaulted>();
+  move_constructible_checks_impl<true, HasCons>();
+  move_constructible_checks_impl<true, HasCopyAssign>();
+  move_constructible_checks_impl<true, HasDest>();
+  move_constructible_checks_impl<true, HasMove>();
+  move_constructible_checks_impl<true, HasPriv>();
+  move_constructible_checks_impl<true, HasRef>();
+  move_constructible_checks_impl<true, HasTemplateCons>();
+  move_constructible_checks_impl<true, NoDefaultMoveAssignDueToDtor>();
+  move_constructible_checks_impl<true, NoDefaultMoveAssignDueToUDCopyAssign>();
+  move_constructible_checks_impl<true, NoDefaultMoveAssignDueToUDCopyCtor>();
+  move_constructible_checks_impl<true, NonTCStruct>();
+  move_constructible_checks_impl<true, NonTrivialStruct>();
+  move_constructible_checks_impl<true, POD>();
+  move_constructible_checks_impl<true, SuperNonTrivialStruct>();
+  move_constructible_checks_impl<true, TrivialStruct>();
+  move_constructible_checks_impl<true, Union>();
+  move_constructible_checks_impl<true, VolatileMoveCtor>();
+
+  move_constructible_checks_impl<false, AllDeleted>();
+  move_constructible_checks_impl<false, AllPrivate>();
+  move_constructible_checks_impl<false, AnIncompleteType[]>();
+  move_constructible_checks_impl<false, AnIncompleteType>(); // expected-note{{in instantiation of function template specialization}}
+  move_constructible_checks_impl<false, BaseDeletedCopyCtor>();
+  move_constructible_checks_impl<false, BaseDeletedCopyCtor>();
+  move_constructible_checks_impl<false, BaseDeletedMoveCtor>();
+  move_constructible_checks_impl<false, CopyCtorDeleted>();
+  move_constructible_checks_impl<false, CopyCtorDeleted>();
+  move_constructible_checks_impl<false, CVCopyCtor>();
+  move_constructible_checks_impl<false, HasMutableCopyCtor>();
+  move_constructible_checks_impl<false, HasMoveAssign>();
+  move_constructible_checks_impl<false, MemberDeletedCopyCtor>();
+  move_constructible_checks_impl<false, MemberDeletedCopyCtor>();
+  move_constructible_checks_impl<false, MemberDeletedMoveCtor>();
+  move_constructible_checks_impl<false, MoveCtorDeleted>();
+  move_constructible_checks_impl<false, VirtAr>();
+  move_constructible_checks_impl<false, VolatileCopyCtor>();
+
+  // Non-referencable types
+  move_constructible_checks_impl<false, void>();
+  move_constructible_checks_impl<false, void()>();
+  move_constructible_checks_impl<false, void() const>();
+  move_constructible_checks_impl<false, void() volatile>();
+  move_constructible_checks_impl<false, void() const volatile>();
+  move_constructible_checks_impl<false, void() &>();
+  move_constructible_checks_impl<false, void() const &>();
+  move_constructible_checks_impl<false, void() volatile &>();
+  move_constructible_checks_impl<false, void() const volatile &>();
+  move_constructible_checks_impl<false, void() &&>();
+  move_constructible_checks_impl<false, void() const &&>();
+  move_constructible_checks_impl<false, void() volatile &&>();
+  move_constructible_checks_impl<false, void() const volatile &&>();
+}
+
+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
+  { int a[T(__is_copy_assignable(int))]; }
+  { int a[T(__is_copy_assignable(int &))]; }
+  { int a[T(__is_copy_assignable(int &&))]; }
+  { int a[T(__is_copy_assignable(int *))]; }
+  { int a[F(__is_copy_assignable(int[5]))]; }
+  { int a[F(__is_copy_assignable(int[]))]; }
+  { int a[T(__is_copy_assignable(decltype(nullptr)))]; }
+  { int a[T(__is_copy_assignable(void (*)()))]; }
+  { int a[F(__is_copy_assignable(void (&)()))]; }
+  { int a[T(__is_copy_assignable(int Empty::*))]; }
+  { int a[T(__is_copy_assignable(int(Empty::*)()))]; }
+  { int a[T(__is_copy_assignable(int(Empty::*)() const))]; }
+  { int a[T(__is_copy_assignable(int(Empty::*)() volatile))]; }
+  { int a[T(__is_copy_assignable(int(Empty::*)() const volatile))]; }
+  { int a[T(__is_copy_assignable(int(Empty::*)() &))]; }
+  { int a[T(__is_copy_assignable(int(Empty::*)() const &))]; }
+  { int a[T(__is_copy_assignable(int(Empty::*)() volatile &))]; }
+  { int a[T(__is_copy_assignable(int(Empty::*)() const volatile &))]; }
+  { int a[T(__is_copy_assignable(int(Empty::*)() &&))]; }
+  { int a[T(__is_copy_assignable(int(Empty::*)() const &&))]; }
+  { int a[T(__is_copy_assignable(int(Empty::*)() volatile &&))]; }
+  { int a[T(__is_copy_assignable(int(Empty::*)() const volatile &&))]; }
+
+  // // User-defined types
+  { int a[T(__is_copy_assignable(AllDefaulted))]; }
+  { int a[T(__is_copy_assignable(AllDefaulted))]; }
+  { int a[T(__is_copy_assignable(BaseDeletedCopyCtor))]; }
+  { int a[T(__is_copy_assignable(CEmptyStruct))]; }
+  { int a[T(__is_copy_assignable(CopyCtorDeleted))]; }
+  { int a[T(__is_copy_assignable(CppEmptyStruct))]; }
+  { int a[T(__is_copy_assignable(CppStructNonStandardBy2ndVirtBase))]; }
+  { int a[T(__is_copy_assignable(CppStructNonStandardByBase))]; }
+  { int a[T(__is_copy_assignable(CppStructNonStandardByMemb))]; }
+  { int a[T(__is_copy_assignable(CppStructNonStandardByProt))]; }
+  { int a[T(__is_copy_assignable(CppStructNonStandardBySameBase))]; }
+  { int a[T(__is_copy_assignable(CppStructNonStandardByVirt))]; }
+  { int a[T(__is_copy_assignable(CppStructNonStandardByVirtBase))]; }
+  { int a[T(__is_copy_assignable(CppStructStandard))]; }
+  { int a[T(__is_copy_assignable(CStruct))]; }
+  { int a[T(__is_copy_assignable(CVCopyCtor))]; }
+  { int a[T(__is_copy_assignable(Derives))]; }
+  { int a[T(__is_copy_assignable(DerivesHasCopyAssign))]; }
+  { int a[T(__is_copy_assignable(Empty))]; }
+  { int a[T(__is_copy_assignable(EmptyUnion))]; }
+  { int a[T(__is_copy_assignable(Enum))]; }
+  { int a[T(__is_copy_assignable(EnumClass))]; }
+  { int a[T(__is_copy_assignable(ExtDefaulted))]; }
+  { int a[T(__is_copy_assignable(ExtDefaulted))]; }
+  { int a[T(__is_copy_assignable(HasCons))]; }
+  { int a[T(__is_copy_assignable(HasCopyAssign))]; }
+  { int a[T(__is_copy_assignable(HasDest))]; }
+  { int a[T(__is_copy_assignable(HasMutableCopyCtor))]; }
+  { int a[T(__is_copy_assignable(HasPriv))]; }
+  { int a[T(__is_copy_assignable(HasMultipleCopyAssign))]; }
+  { int a[T(__is_copy_assignable(HasTemplateCons))]; }
+  { int a[T(__is_copy_assignable(MemberDeletedCopyCtor))]; }
+  { int a[T(__is_copy_assignable(NoDefaultMoveAssignDueToDtor))]; }
+  { int a[T(__is_copy_assignable(NoDefaultMoveAssignDueToUDCopyAssign))]; }
+  { int a[T(__is_copy_assignable(NoDefaultMoveAssignDueToUDCopyCtor))]; }
+  { int a[T(__is_copy_assignable(NonTCStruct))]; }
+  { int a[T(__is_copy_assignable(NonTrivialStruct))]; }
+  { int a[T(__is_copy_assignable(POD))]; }
+  { int a[T(__is_copy_assignable(SuperNonTrivialStruct))]; }
+  { int a[T(__is_copy_assignable(TrivialStruct))]; }
+  { int a[T(__is_copy_assignable(Union))]; }
+
+  { int a[F(__is_copy_assignable(AllDeleted))]; }
+  { int a[F(__is_copy_assignable(AllPrivate))]; }
+  { int a[F(__is_copy_assignable(AnIncompleteType[]))]; }
+  { int a[F(__is_copy_assignable(AnIncompleteType))]; } // expected-error{{incomplete type}}
+  { int a[F(__is_copy_assignable(DerivesHasRef))]; }
+  { int a[F(__is_copy_assignable(HasRef))]; }
+  { int a[F(__is_copy_assignable(HasMove))]; }
+  { int a[F(__is_copy_assignable(HasMoveAssign))]; }
+  { int a[F(__is_copy_assignable(VirtAr))]; }
+  { int a[F(__is_copy_assignable(CopyAssignDeleted))]; }
+  { int a[F(__is_copy_assignable(BaseDeletedCopyAssign))]; }
+  { int a[F(__is_copy_assignable(HasMemberWithDeletedCopyAssign))]; }
+
+  { int a[F(__is_copy_assignable(MutableCopyAssign_QualNone))]; }
+  { int a[F(__is_copy_assignable(MutableCopyAssign_QualConst))]; }
+  { int a[F(__is_copy_assignable(MutableCopyAssign_QualVolatile))]; }
+  { int a[F(__is_copy_assignable(MutableCopyAssign_QualCV))]; }
+  { int a[F(__is_copy_assignable(MutableCopyAssign_QualLvalue))]; }
+  { int a[F(__is_copy_assignable(MutableCopyAssign_QualConstLvalue))]; }
+  { int a[F(__is_copy_assignable(MutableCopyAssign_QualVolatileLvalue))]; }
+  { int a[F(__is_copy_assignable(MutableCopyAssign_QualCVLvalue))]; }
+  { int a[F(__is_copy_assignable(MutableCopyAssign_QualRvalue))]; }
+  { int a[F(__is_copy_assignable(MutableCopyAssign_QualConstRvalue))]; }
+  { int a[F(__is_copy_assignable(MutableCopyAssign_QualVolatileRvalue))]; }
+  { int a[F(__is_copy_assignable(MutableCopyAssign_QualCVRvalue))]; }
+  { int a[T(__is_copy_assignable(CopyAssign_QualNone))]; }
+  { int a[T(__is_copy_assignable(CopyAssign_QualConst))]; }
+  { int a[T(__is_copy_assignable(CopyAssign_QualVolatile))]; }
+  { int a[T(__is_copy_assignable(CopyAssign_QualCV))]; }
+  { int a[T(__is_copy_assignable(CopyAssign_QualLvalue))]; }
+  { int a[T(__is_copy_assignable(CopyAssign_QualConstLvalue))]; }
+  { int a[T(__is_copy_assignable(CopyAssign_QualVolatileLvalue))]; }
+  { int a[T(__is_copy_assignable(CopyAssign_QualCVLvalue))]; }
+  { int a[F(__is_copy_assignable(CopyAssign_QualRvalue))]; }
+  { int a[F(__is_copy_assignable(CopyAssign_QualConstRvalue))]; }
+  { int a[F(__is_copy_assignable(CopyAssign_QualVolatileRvalue))]; }
+  { int a[F(__is_copy_assignable(CopyAssign_QualCVRvalue))]; }
+  { int a[F(__is_copy_assignable(VolatileCopyAssign_QualNone))]; }
+  { int a[F(__is_copy_assignable(VolatileCopyAssign_QualConst))]; }
+  { int a[F(__is_copy_assignable(VolatileCopyAssign_QualVolatile))]; }
+  { int a[F(__is_copy_assignable(VolatileCopyAssign_QualCV))]; }
+  { int a[F(__is_copy_assignable(VolatileCopyAssign_QualLvalue))]; }
+  { int a[F(__is_copy_assignable(VolatileCopyAssign_QualConstLvalue))]; }
+  { int a[F(__is_copy_assignable(VolatileCopyAssign_QualVolatileLvalue))]; }
+  { int a[F(__is_copy_assignable(VolatileCopyAssign_QualCVLvalue))]; }
+  { int a[F(__is_copy_assignable(VolatileCopyAssign_QualRvalue))]; }
+  { int a[F(__is_copy_assignable(VolatileCopyAssign_QualConstRvalue))]; }
+  { int a[F(__is_copy_assignable(VolatileCopyAssign_QualVolatileRvalue))]; }
+  { int a[F(__is_copy_assignable(VolatileCopyAssign_QualCVRvalue))]; }
+  { int a[T(__is_copy_assignable(CVCopyAssign_QualNone))]; }
+  { int a[T(__is_copy_assignable(CVCopyAssign_QualConst))]; }
+  { int a[T(__is_copy_assignable(CVCopyAssign_QualVolatile))]; }
+  { int a[T(__is_copy_assignable(CVCopyAssign_QualCV))]; }
+  { int a[T(__is_copy_assignable(CVCopyAssign_QualLvalue))]; }
+  { int a[T(__is_copy_assignable(CVCopyAssign_QualConstLvalue))]; }
+  { int a[T(__is_copy_assignable(CVCopyAssign_QualVolatileLvalue))]; }
+  { int a[T(__is_copy_assignable(CVCopyAssign_QualCVLvalue))]; }
+  { int a[F(__is_copy_assignable(CVCopyAssign_QualRvalue))]; }
+  { int a[F(__is_copy_assignable(CVCopyAssign_QualConstRvalue))]; }
+  { int a[F(__is_copy_assignable(CVCopyAssign_QualVolatileRvalue))]; }
+  { int a[F(__is_copy_assignable(CVCopyAssign_QualCVRvalue))]; }
+
+  // Non-referencable types
+  { int a[F(__is_copy_assignable(void))]; }
+  { int a[F(__is_copy_assignable(void()))]; }
+
+  // cv-qualified types
+  { int a[F(__is_copy_assignable(const int))]; }
+  { int a[F(__is_copy_assignable(const Empty))]; }
+  { int a[T(__is_copy_assignable(volatile int))]; }
+  { int a[F(__is_copy_assignable(volatile Empty))]; }
+  { int a[F(__is_copy_assignable(const volatile int))]; }
+  { int a[F(__is_copy_assignable(const volatile Empty))]; }
+
+  { int a[T(__is_copy_assignable(const CopyAssign_QualConst))]; }
+  { int a[T(__is_copy_assignable(volatile CopyAssign_QualVolatile))]; }
+  { int a[T(__is_copy_assignable(const volatile CopyAssign_QualCV))]; }
+  { int a[F(__is_copy_assignable(const VolatileCopyAssign_QualConst))]; }
+  { int a[F(__is_copy_assignable(volatile VolatileCopyAssign_QualVolatile))]; }
+  { int a[F(__is_copy_assignable(const volatile VolatileCopyAssign_QualCV))]; }
+  { int a[T(__is_copy_assignable(const CVCopyAssign_QualConst))]; }
+  { int a[T(__is_copy_assignable(volatile CVCopyAssign_QualVolatile))]; }
+  { int a[T(__is_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
+  { int a[T(__is_move_assignable(int))]; }
+  { int a[T(__is_move_assignable(int &))]; }
+  { int a[T(__is_move_assignable(int &&))]; }
+  { int a[T(__is_move_assignable(int *))]; }
+  { int a[F(__is_move_assignable(int[5]))]; }
+  { int a[F(__is_move_assignable(int[]))]; }
+  { int a[T(__is_move_assignable(decltype(nullptr)))]; }
+  { int a[T(__is_move_assignable(void (*)()))]; }
+  { int a[F(__is_move_assignable(void (&)()))]; }
+  { int a[T(__is_move_assignable(int Empty::*))]; }
+  { int a[T(__is_move_assignable(int(Empty::*)()))]; }
+  { int a[T(__is_move_assignable(int(Empty::*)() const))]; }
+  { int a[T(__is_move_assignable(int(Empty::*)() volatile))]; }
+  { int a[T(__is_move_assignable(int(Empty::*)() const volatile))]; }
+  { int a[T(__is_move_assignable(int(Empty::*)() &))]; }
+  { int a[T(__is_move_assignable(int(Empty::*)() const &))]; }
+  { int a[T(__is_move_assignable(int(Empty::*)() volatile &))]; }
+  { int a[T(__is_move_assignable(int(Empty::*)() const volatile &))]; }
+  { int a[T(__is_move_assignable(int(Empty::*)() &&))]; }
+  { int a[T(__is_move_assignable(int(Empty::*)() const &&))]; }
+  { int a[T(__is_move_assignable(int(Empty::*)() volatile &&))]; }
+  { int a[T(__is_move_assignable(int(Empty::*)() const volatile &&))]; }
+
+  // // User-defined types
+  { int a[T(__is_move_assignable(AllDefaulted))]; }
+  { int a[T(__is_move_assignable(AllDefaulted))]; }
+  { int a[T(__is_move_assignable(BaseDeletedCopyCtor))]; }
+  { int a[T(__is_move_assignable(CEmptyStruct))]; }
+  { int a[T(__is_move_assignable(CopyCtorDeleted))]; }
+  { int a[T(__is_move_assignable(CppEmptyStruct))]; }
+  { int a[T(__is_move_assignable(CppStructNonStandardBy2ndVirtBase))]; }
+  { int a[T(__is_move_assignable(CppStructNonStandardByBase))]; }
+  { int a[T(__is_move_assignable(CppStructNonStandardByMemb))]; }
+  { int a[T(__is_move_assignable(CppStructNonStandardByProt))]; }
+  { int a[T(__is_move_assignable(CppStructNonStandardBySameBase))]; }
+  { int a[T(__is_move_assignable(CppStructNonStandardByVirt))]; }
+  { int a[T(__is_move_assignable(CppStructNonStandardByVirtBase))]; }
+  { int a[T(__is_move_assignable(CppStructStandard))]; }
+  { int a[T(__is_move_assignable(CStruct))]; }
+  { int a[T(__is_move_assignable(CVCopyCtor))]; }
+  { int a[T(__is_move_assignable(Derives))]; }
+  { int a[T(__is_move_assignable(DerivesHasCopyAssign))]; }
+  { int a[T(__is_move_assignable(Empty))]; }
+  { int a[T(__is_move_assignable(EmptyUnion))]; }
+  { int a[T(__is_move_assignable(Enum))]; }
+  { int a[T(__is_move_assignable(EnumClass))]; }
+  { int a[T(__is_move_assignable(ExtDefaulted))]; }
+  { int a[T(__is_move_assignable(ExtDefaulted))]; }
+  { int a[T(__is_move_assignable(HasCons))]; }
+  { int a[T(__is_move_assignable(HasCopyAssign))]; }
+  { int a[T(__is_move_assignable(HasDest))]; }
+  { int a[T(__is_move_assignable(HasMutableCopyCtor))]; }
+  { int a[T(__is_move_assignable(HasPriv))]; }
+  { int a[T(__is_move_assignable(HasMultipleCopyAssign))]; }
+  { int a[T(__is_move_assignable(HasTemplateCons))]; }
+  { int a[T(__is_move_assignable(MemberDeletedCopyCtor))]; }
+  { int a[T(__is_move_assignable(NoDefaultMoveAssignDueToDtor))]; }
+  { int a[T(__is_move_assignable(NoDefaultMoveAssignDueToUDCopyAssign))]; }
+  { int a[T(__is_move_assignable(NoDefaultMoveAssignDueToUDCopyCtor))]; }
+  { int a[T(__is_move_assignable(NonTCStruct))]; }
+  { int a[T(__is_move_assignable(NonTrivialStruct))]; }
+  { int a[T(__is_move_assignable(POD))]; }
+  { int a[T(__is_move_assignable(SuperNonTrivialStruct))]; }
+  { int a[T(__is_move_assignable(TrivialStruct))]; }
+  { int a[T(__is_move_assignable(Union))]; }
+  { int a[T(__is_move_assignable(HasMoveAssign))]; }
+
+  { int a[F(__is_move_assignable(AllDeleted))]; }
+  { int a[F(__is_move_assignable(AllPrivate))]; }
+  { int a[F(__is_move_assignable(AnIncompleteType[]))]; }
+  { int a[F(__is_move_assignable(AnIncompleteType))]; } // expected-error{{incomplete type}}
+  { int a[F(__is_move_assignable(DerivesHasRef))]; }
+  { int a[F(__is_move_assignable(HasRef))]; }
+  { int a[F(__is_move_assignable(HasMove))]; }
+  { int a[F(__is_move_assignable(VirtAr))]; }
+  { int a[F(__is_move_assignable(MoveAssignDeleted))]; }
+  { int a[F(__is_move_assignable(BaseDeletedMoveAssign))]; }
+  { int a[F(__is_move_assignable(HasMemberWithDeletedMoveAssign))]; }
+
+  { int a[T(__is_move_assignable(MoveAssign_QualNone))]; }
+  { int a[F(__is_move_assignable(MoveAssign_QualConst))]; }
+  { int a[F(__is_move_assignable(MoveAssign_QualVolatile))]; }
+  { int a[F(__is_move_assignable(MoveAssign_QualCV))]; }
+  { int a[T(__is_move_assignable(MoveAssign_QualLvalue))]; }
+  { int a[F(__is_move_assignable(MoveAssign_QualConstLvalue))]; }
+  { int a[F(__is_move_assignable(MoveAssign_QualVolatileLvalue))]; }
+  { int a[F(__is_move_assignable(MoveAssign_QualCVLvalue))]; }
+  { int a[F(__is_move_assignable(MoveAssign_QualRvalue))]; }
+  { int a[F(__is_move_assignable(MoveAssign_QualConstRvalue))]; }
+  { int a[F(__is_move_assignable(MoveAssign_QualVolatileRvalue))]; }
+  { int a[F(__is_move_assignable(MoveAssign_QualCVRvalue))]; }
+  { int a[T(__is_move_assignable(ConstMoveAssign_QualNone))]; }
+  { int a[F(__is_move_assignable(ConstMoveAssign_QualConst))]; }
+  { int a[F(__is_move_assignable(ConstMoveAssign_QualVolatile))]; }
+  { int a[F(__is_move_assignable(ConstMoveAssign_QualCV))]; }
+  { int a[T(__is_move_assignable(ConstMoveAssign_QualLvalue))]; }
+  { int a[F(__is_move_assignable(ConstMoveAssign_QualConstLvalue))]; }
+  { int a[F(__is_move_assignable(ConstMoveAssign_QualVolatileLvalue))]; }
+  { int a[F(__is_move_assignable(ConstMoveAssign_QualCVLvalue))]; }
+  { int a[F(__is_move_assignable(ConstMoveAssign_QualRvalue))]; }
+  { int a[F(__is_move_assignable(ConstMoveAssign_QualConstRvalue))]; }
+  { int a[F(__is_move_assignable(ConstMoveAssign_QualVolatileRvalue))]; }
+  { int a[F(__is_move_assignable(ConstMoveAssign_QualCVRvalue))]; }
+  { int a[T(__is_move_assignable(VolatileMoveAssign_QualNone))]; }
+  { int a[F(__is_move_assignable(VolatileMoveAssign_QualConst))]; }
+  { int a[F(__is_move_assignable(VolatileMoveAssign_QualVolatile))]; }
+  { int a[F(__is_move_assignable(VolatileMoveAssign_QualCV))]; }
+  { int a[T(__is_move_assignable(VolatileMoveAssign_QualLvalue))]; }
+  { int a[F(__is_move_assignable(VolatileMoveAssign_QualConstLvalue))]; }
+  { int a[F(__is_move_assignable(VolatileMoveAssign_QualVolatileLvalue))]; }
+  { int a[F(__is_move_assignable(VolatileMoveAssign_QualCVLvalue))]; }
+  { int a[F(__is_move_assignable(VolatileMoveAssign_QualRvalue))]; }
+  { int a[F(__is_move_assignable(VolatileMoveAssign_QualConstRvalue))]; }
+  { int a[F(__is_move_assignable(VolatileMoveAssign_QualVolatileRvalue))]; }
+  { int a[F(__is_move_assignable(VolatileMoveAssign_QualCVRvalue))]; }
+  { int a[T(__is_move_assignable(CVMoveAssign_QualNone))]; }
+  { int a[F(__is_move_assignable(CVMoveAssign_QualConst))]; }
+  { int a[F(__is_move_assignable(CVMoveAssign_QualVolatile))]; }
+  { int a[F(__is_move_assignable(CVMoveAssign_QualCV))]; }
+  { int a[T(__is_move_assignable(CVMoveAssign_QualLvalue))]; }
+  { int a[F(__is_move_assignable(CVMoveAssign_QualConstLvalue))]; }
+  { int a[F(__is_move_assignable(CVMoveAssign_QualVolatileLvalue))]; }
+  { int a[F(__is_move_assignable(CVMoveAssign_QualCVLvalue))]; }
+  { int a[F(__is_move_assignable(CVMoveAssign_QualRvalue))]; }
+  { int a[F(__is_move_assignable(CVMoveAssign_QualConstRvalue))]; }
+  { int a[F(__is_move_assignable(CVMoveAssign_QualVolatileRvalue))]; }
+  { int a[F(__is_move_assignable(CVMoveAssign_QualCVRvalue))]; }
+
+  // Non-referencable types
+  { int a[F(__is_move_assignable(void))]; }
+  { int a[F(__is_move_assignable(void()))]; }
+
+  // cv-qualified types
+  { int a[F(__is_move_assignable(const int))]; }
+  { int a[F(__is_move_assignable(const Empty))]; }
+  { int a[T(__is_move_assignable(volatile int))]; }
+  { int a[F(__is_move_assignable(volatile Empty))]; }
+  { int a[F(__is_move_assignable(const volatile int))]; }
+  { int a[F(__is_move_assignable(const volatile Empty))]; }
+
+  { int a[T(__is_move_assignable(const MoveAssign_QualConst))]; }
+  { int a[F(__is_move_assignable(volatile MoveAssign_QualConst))]; }
+  { int a[F(__is_move_assignable(const volatile MoveAssign_QualConst))]; }
+  { int a[T(__is_move_assignable(volatile MoveAssign_QualVolatile))]; }
+  { int a[T(__is_move_assignable(const volatile MoveAssign_QualCV))]; }
+  { int a[T(__is_move_assignable(const VolatileMoveAssign_QualConst))]; }
+  { int a[T(__is_move_assignable(volatile VolatileMoveAssign_QualVolatile))]; }
+  { int a[T(__is_move_assignable(const volatile VolatileMoveAssign_QualCV))]; }
+  { int a[T(__is_move_assignable(const CVMoveAssign_QualConst))]; }
+  { int a[T(__is_move_assignable(volatile CVMoveAssign_QualVolatile))]; }
+  { int a[T(__is_move_assignable(const volatile CVMoveAssign_QualCV))]; }
+}
+
 // Instantiation of __is_trivially_constructible
 template<typename T, typename ...Args>
 struct is_trivially_constructible {
@@ -3295,6 +4332,8 @@
     static_assert(__is_same(remove_cvref_t<M>, M), "");
     static_assert(__is_same(remove_pointer_t<M>, M), "");
     static_assert(__is_same(remove_reference_t<M>, M), "");
+
+    static_assert(!__is_referenceable(M), "");
   }
 };
 
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -2600,12 +2600,10 @@
 
   if (T->isVariableArrayType() && !Context.getTargetInfo().isVLASupported()) {
     // CUDA device code and some other targets don't support VLAs.
-    targetDiag(Loc, (getLangOpts().CUDA && getLangOpts().CUDAIsDevice)
-                        ? diag::err_cuda_vla
-                        : diag::err_vla_unsupported)
-        << ((getLangOpts().CUDA && getLangOpts().CUDAIsDevice)
-                ? CurrentCUDATarget()
-                : CFT_InvalidTarget);
+    bool IsCUDADevice = (getLangOpts().CUDA && getLangOpts().CUDAIsDevice);
+    targetDiag(Loc,
+               IsCUDADevice ? diag::err_cuda_vla : diag::err_vla_unsupported)
+        << (IsCUDADevice ? CurrentCUDATarget() : 0);
   }
 
   // If this is not C99, diagnose array size modifiers on non-VLAs.
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -21,12 +21,14 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/AlignedAllocation.h"
 #include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TypeTraits.h"
+#include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Initialization.h"
@@ -4740,12 +4742,16 @@
   case UTT_IsIntegral:
   case UTT_IsFloatingPoint:
   case UTT_IsArray:
+  case UTT_IsBoundedArray:
   case UTT_IsPointer:
+  case UTT_IsNullPointer:
+  case UTT_IsReferenceable:
   case UTT_IsLvalueReference:
   case UTT_IsRvalueReference:
   case UTT_IsMemberFunctionPointer:
   case UTT_IsMemberObjectPointer:
   case UTT_IsEnum:
+  case UTT_IsScopedEnum:
   case UTT_IsUnion:
   case UTT_IsClass:
   case UTT_IsFunction:
@@ -4766,6 +4772,7 @@
   case UTT_IsConst:
   case UTT_IsVolatile:
   case UTT_IsSigned:
+  case UTT_IsUnboundedArray:
   case UTT_IsUnsigned:
 
   // This type trait always returns false, checking the type is moot.
@@ -4825,6 +4832,10 @@
   case UTT_IsNothrowDestructible:
   case UTT_IsTriviallyDestructible:
   case UTT_HasUniqueObjectRepresentations:
+  case UTT_IsCopyConstructible:
+  case UTT_IsCopyAssignable:
+  case UTT_IsMoveConstructible:
+  case UTT_IsMoveAssignable:
     if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType())
       return true;
 
@@ -4868,6 +4879,12 @@
   return false;
 }
 
+static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc,
+                              ArrayRef<TypeSourceInfo *> Args,
+                              SourceLocation RParenLoc);
+static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
+                                    QualType RhsT, SourceLocation KeyLoc);
+
 static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
                                    SourceLocation KeyLoc, QualType T) {
   assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");
@@ -4885,8 +4902,20 @@
     return T->isFloatingType();
   case UTT_IsArray:
     return T->isArrayType();
+  case UTT_IsBoundedArray:
+    if (T->isVariableArrayType())
+      Self.Diag(KeyLoc, diag::err_vla_unsupported)
+          << 1 << tok::kw___is_bounded_array;
+    return T->isArrayType() && !T->isIncompleteArrayType();
+  case UTT_IsUnboundedArray:
+    if (T->isVariableArrayType())
+      Self.Diag(KeyLoc, diag::err_vla_unsupported)
+          << 1 << tok::kw___is_unbounded_array;
+    return T->isIncompleteArrayType();
   case UTT_IsPointer:
     return T->isAnyPointerType();
+  case UTT_IsNullPointer:
+    return T->isNullPtrType();
   case UTT_IsLvalueReference:
     return T->isLValueReferenceType();
   case UTT_IsRvalueReference:
@@ -4897,6 +4926,8 @@
     return T->isMemberDataPointerType();
   case UTT_IsEnum:
     return T->isEnumeralType();
+  case UTT_IsScopedEnum:
+    return T->isScopedEnumeralType();
   case UTT_IsUnion:
     return T->isUnionType();
   case UTT_IsClass:
@@ -5268,12 +5299,51 @@
     return C.hasUniqueObjectRepresentations(T);
   case UTT_IsTriviallyRelocatable:
     return T.isTriviallyRelocatableType(C);
+  case UTT_IsCopyConstructible:
+  case UTT_IsCopyAssignable: {
+    if (T->isIncompleteArrayType())
+      return false;
+    if (!T.isReferenceable())
+      return false;
+
+    QualType AssigneeType = Self.BuiltinRemoveReference(T, UnaryTransformType::RemoveCVRef, {});
+    AssigneeType.addConst();
+    AssigneeType = Self.BuildReferenceType(AssigneeType, true, KeyLoc,
+                                           T.getBaseTypeIdentifier());
+    if (UTT == UTT_IsCopyAssignable) {
+      return EvaluateBinaryTypeTrait(
+          Self, BTT_IsAssignable,
+          Self.BuildReferenceType(T, true, KeyLoc, T.getBaseTypeIdentifier()),
+          AssigneeType, KeyLoc);
+    }
+    llvm::SmallVector<TypeSourceInfo *, 2> Parameters = {
+        C.CreateTypeSourceInfo(T), C.CreateTypeSourceInfo(AssigneeType)};
+    return evaluateTypeTrait(Self, TT_IsConstructible, KeyLoc, Parameters, {});
+  }
+  case UTT_IsMoveConstructible:
+  case UTT_IsMoveAssignable: {
+    if (T->isIncompleteArrayType())
+      return false;
+    if (!T.isReferenceable())
+      return false;
+
+    QualType AssigneeType = Self.BuiltinRemoveReference(T, UnaryTransformType::RemoveCVRef, {});
+    AssigneeType = Self.BuildReferenceType(AssigneeType, false, KeyLoc,
+                                           T.getBaseTypeIdentifier());
+    if (UTT == UTT_IsMoveAssignable)
+      return EvaluateBinaryTypeTrait(
+          Self, BTT_IsAssignable,
+          Self.BuildReferenceType(T, true, KeyLoc, T.getBaseTypeIdentifier()),
+          AssigneeType, KeyLoc);
+    llvm::SmallVector<TypeSourceInfo *, 2> Parameters = {
+        C.CreateTypeSourceInfo(T), C.CreateTypeSourceInfo(AssigneeType)};
+    return evaluateTypeTrait(Self, TT_IsConstructible, KeyLoc, Parameters, {});
+  }
+  case UTT_IsReferenceable:
+    return T.isReferenceable();
   }
 }
 
-static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
-                                    QualType RhsT, SourceLocation KeyLoc);
-
 static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc,
                               ArrayRef<TypeSourceInfo *> Args,
                               SourceLocation RParenLoc) {
Index: clang/lib/Parse/ParseExpr.cpp
===================================================================
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -1068,6 +1068,7 @@
           REVERTIBLE_TYPE_TRAIT(__is_arithmetic);
           REVERTIBLE_TYPE_TRAIT(__is_array);
           REVERTIBLE_TYPE_TRAIT(__is_assignable);
+          REVERTIBLE_TYPE_TRAIT(__is_bounded_array);
           REVERTIBLE_TYPE_TRAIT(__is_base_of);
           REVERTIBLE_TYPE_TRAIT(__is_class);
           REVERTIBLE_TYPE_TRAIT(__is_complete_type);
@@ -1103,6 +1104,7 @@
           REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference);
           REVERTIBLE_TYPE_TRAIT(__is_same);
           REVERTIBLE_TYPE_TRAIT(__is_scalar);
+          REVERTIBLE_TYPE_TRAIT(__is_scoped_enum);
           REVERTIBLE_TYPE_TRAIT(__is_sealed);
           REVERTIBLE_TYPE_TRAIT(__is_signed);
           REVERTIBLE_TYPE_TRAIT(__is_standard_layout);
@@ -1110,6 +1112,7 @@
           REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable);
           REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible);
           REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable);
+          REVERTIBLE_TYPE_TRAIT(__is_unbounded_array);
           REVERTIBLE_TYPE_TRAIT(__is_union);
           REVERTIBLE_TYPE_TRAIT(__is_unsigned);
           REVERTIBLE_TYPE_TRAIT(__is_void);
Index: clang/lib/Parse/ParseDeclCXX.cpp
===================================================================
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -1547,6 +1547,7 @@
           tok::kw___is_array,
           tok::kw___is_assignable,
           tok::kw___is_base_of,
+          tok::kw___is_bounded_array,
           tok::kw___is_class,
           tok::kw___is_complete_type,
           tok::kw___is_compound,
@@ -1572,15 +1573,18 @@
           tok::kw___is_nothrow_assignable,
           tok::kw___is_nothrow_constructible,
           tok::kw___is_nothrow_destructible,
+          tok::kw___is_nullptr,
           tok::kw___is_object,
           tok::kw___is_pod,
           tok::kw___is_pointer,
           tok::kw___is_polymorphic,
           tok::kw___is_reference,
+          tok::kw___is_referenceable,
           tok::kw___is_rvalue_expr,
           tok::kw___is_rvalue_reference,
           tok::kw___is_same,
           tok::kw___is_scalar,
+          tok::kw___is_scoped_enum,
           tok::kw___is_sealed,
           tok::kw___is_signed,
           tok::kw___is_standard_layout,
@@ -1588,6 +1592,7 @@
           tok::kw___is_trivially_assignable,
           tok::kw___is_trivially_constructible,
           tok::kw___is_trivially_copyable,
+          tok::kw___is_unbounded_array,
           tok::kw___is_union,
           tok::kw___is_unsigned,
           tok::kw___is_void,
Index: clang/include/clang/Basic/TokenKinds.def
===================================================================
--- clang/include/clang/Basic/TokenKinds.def
+++ clang/include/clang/Basic/TokenKinds.def
@@ -455,12 +455,16 @@
 TYPE_TRAIT_1(__is_sealed, IsSealed, KEYMS)
 
 // MSVC12.0 / VS2013 Type Traits
-TYPE_TRAIT_1(__is_destructible, IsDestructible, KEYMS)
+TYPE_TRAIT_1(__is_destructible, IsDestructible, KEYCXX)
 TYPE_TRAIT_1(__is_trivially_destructible, IsTriviallyDestructible, KEYCXX)
-TYPE_TRAIT_1(__is_nothrow_destructible, IsNothrowDestructible, KEYMS)
+TYPE_TRAIT_1(__is_nothrow_destructible, IsNothrowDestructible, KEYCXX)
 TYPE_TRAIT_2(__is_nothrow_assignable, IsNothrowAssignable, KEYCXX)
 TYPE_TRAIT_N(__is_constructible, IsConstructible, KEYCXX)
 TYPE_TRAIT_N(__is_nothrow_constructible, IsNothrowConstructible, KEYCXX)
+TYPE_TRAIT_1(__is_copy_constructible, IsCopyConstructible, KEYCXX)
+TYPE_TRAIT_1(__is_copy_assignable, IsCopyAssignable, KEYCXX)
+TYPE_TRAIT_1(__is_move_constructible, IsMoveConstructible, KEYCXX)
+TYPE_TRAIT_1(__is_move_assignable, IsMoveAssignable, KEYCXX)
 
 // MSVC14.0 / VS2015 Type Traits
 TYPE_TRAIT_2(__is_assignable, IsAssignable, KEYCXX)
@@ -507,6 +511,11 @@
 
 // Clang-only C++ Type Traits
 TYPE_TRAIT_1(__is_trivially_relocatable, IsTriviallyRelocatable, KEYCXX)
+TYPE_TRAIT_1(__is_bounded_array, IsBoundedArray, KEYCXX)
+TYPE_TRAIT_1(__is_unbounded_array, IsUnboundedArray, KEYCXX)
+TYPE_TRAIT_1(__is_nullptr, IsNullPointer, KEYCXX)
+TYPE_TRAIT_1(__is_scoped_enum, IsScopedEnum, KEYCXX)
+TYPE_TRAIT_1(__is_referenceable, IsReferenceable, KEYCXX)
 TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
 
 // Embarcadero Expression Traits
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -147,7 +147,7 @@
   "variable length array folded to constant array as an extension">,
   InGroup<GNUFoldingConstant>;
 def err_vla_unsupported : Error<
-  "variable length arrays are not supported for the current target">;
+  "variable length arrays are not supported for %select{the current target|'%1'}0">;
 def note_vla_unsupported : Note<
   "variable length arrays are not supported for the current target">;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D116280: [cla... Christopher Di Bella via Phabricator via cfe-commits
    • [PATCH] D116280:... Christopher Di Bella via Phabricator via cfe-commits

Reply via email to