cjdb updated this revision to Diff 448806.
cjdb added a subscriber: rsmith.
cjdb added a comment.

I think this covers all the feedback @rsmith has provided, though my treatment 
of `BuildPointerType` and `BuildReferenceType` might be wrong.

Hopefully `__make_signed` and `__make_unsigned` are correct now!


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/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  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 {
@@ -3191,29 +4228,7 @@
   static_assert(__is_same(remove_reference_t<const volatile S &&>, const volatile S), "");
   static_assert(__is_same(remove_reference_t<int S::*const volatile &>, int S::*const volatile), "");
   static_assert(__is_same(remove_reference_t<int (S::*const volatile &)()>, int(S::*const volatile)()), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &)() &>, int(S::*const volatile)() &), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &)() &&>, int(S::*const volatile)() &&), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &)() const>, int(S::*const volatile)() const), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &)() const &>, int(S::*const volatile)() const &), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &)() const &&>, int(S::*const volatile)() const &&), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &)() volatile>, int(S::*const volatile)() volatile), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &)() volatile &>, int(S::*const volatile)() volatile &), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &)() volatile &&>, int(S::*const volatile)() volatile &&), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &)() const volatile>, int(S::*const volatile)() const volatile), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &)() const volatile &>, int(S::*const volatile)() const volatile &), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &)() const volatile &&>, int(S::*const volatile)() const volatile &&), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &)()>, int(S::*const volatile)()), "");
   static_assert(__is_same(remove_reference_t<int (S::*const volatile &&)() &>, int(S::*const volatile)() &), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &&)() &&>, int(S::*const volatile)() &&), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &&)() const>, int(S::*const volatile)() const), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &&)() const &>, int(S::*const volatile)() const &), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &&)() const &&>, int(S::*const volatile)() const &&), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &&)() volatile>, int(S::*const volatile)() volatile), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &&)() volatile &>, int(S::*const volatile)() volatile &), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &&)() volatile &&>, int(S::*const volatile)() volatile &&), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &&)() const volatile>, int(S::*const volatile)() const volatile), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &&)() const volatile &>, int(S::*const volatile)() const volatile &), "");
-  static_assert(__is_same(remove_reference_t<int (S::*const volatile &&)() const volatile &&>, int(S::*const volatile)() const volatile &&), "");
 }
 
 template <class T> using remove_cvref_t = __remove_cvref(T);
@@ -3254,41 +4269,6 @@
   static_assert(__is_same(remove_cvref_t<int (S::*const volatile)()>, int(S::*)()), "");
   static_assert(__is_same(remove_cvref_t<int (S::*const volatile)() &>, int(S::*)() &), "");
   static_assert(__is_same(remove_cvref_t<int (S::*const volatile)() &&>, int(S::*)() &&), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile)() const>, int(S::*)() const), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile)() const &>, int(S::*)() const &), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile)() const &&>, int(S::*)() const &&), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile)() volatile>, int(S::*)() volatile), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile)() volatile &>, int(S::*)() volatile &), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile)() volatile &&>, int(S::*)() volatile &&), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile)() const volatile>, int(S::*)() const volatile), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile)() const volatile &>, int(S::*)() const volatile &), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile)() const volatile &&>, int(S::*)() const volatile &&), "");
-  static_assert(__is_same(remove_cvref_t<int S::*const volatile &>, int S::*), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &)()>, int(S::*)()), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &)() &>, int(S::*)() &), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &)() &&>, int(S::*)() &&), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &)() const>, int(S::*)() const), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &)() const &>, int(S::*)() const &), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &)() const &&>, int(S::*)() const &&), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &)() volatile>, int(S::*)() volatile), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &)() volatile &>, int(S::*)() volatile &), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &)() volatile &&>, int(S::*)() volatile &&), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &)() const volatile>, int(S::*)() const volatile), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &)() const volatile &>, int(S::*)() const volatile &), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &)() const volatile &&>, int(S::*)() const volatile &&), "");
-  static_assert(__is_same(remove_cvref_t<int S::*const volatile &&>, int S::*), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &&)()>, int(S::*)()), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &&)() &>, int(S::*)() &), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &&)() &&>, int(S::*)() &&), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &&)() const>, int(S::*)() const), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &&)() const &>, int(S::*)() const &), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &&)() const &&>, int(S::*)() const &&), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &&)() volatile>, int(S::*)() volatile), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &&)() volatile &>, int(S::*)() volatile &), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &&)() volatile &&>, int(S::*)() volatile &&), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &&)() const volatile>, int(S::*)() const volatile), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &&)() const volatile &>, int(S::*)() const volatile &), "");
-  static_assert(__is_same(remove_cvref_t<int (S::*const volatile &&)() const volatile &&>, int(S::*)() const volatile &&), "");
 }
 
 template <class T> using decay_t = __decay(T);
@@ -3333,43 +4313,10 @@
   static_assert(__is_same(decay_t<const volatile S &&>, S), "");
   static_assert(__is_same(decay_t<int S::*const volatile>, int S::*), "");
   static_assert(__is_same(decay_t<int (S::*const volatile)()>, int(S::*)()), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile)() &>, int(S::*)() &), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile)() &&>, int(S::*)() &&), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile)() const>, int(S::*)() const), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile)() const &>, int(S::*)() const &), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile)() const &&>, int(S::*)() const &&), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile)() volatile>, int(S::*)() volatile), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile)() volatile &>, int(S::*)() volatile &), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile)() volatile &&>, int(S::*)() volatile &&), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile)() const volatile>, int(S::*)() const volatile), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile)() const volatile &>, int(S::*)() const volatile &), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile)() const volatile &&>, int(S::*)() const volatile &&), "");
   static_assert(__is_same(decay_t<int S::*const volatile &>, int S::*), "");
   static_assert(__is_same(decay_t<int (S::*const volatile &)()>, int(S::*)()), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &)() &>, int(S::*)() &), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &)() &&>, int(S::*)() &&), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &)() const>, int(S::*)() const), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &)() const &>, int(S::*)() const &), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &)() const &&>, int(S::*)() const &&), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &)() volatile>, int(S::*)() volatile), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &)() volatile &>, int(S::*)() volatile &), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &)() volatile &&>, int(S::*)() volatile &&), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &)() const volatile>, int(S::*)() const volatile), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &)() const volatile &>, int(S::*)() const volatile &), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &)() const volatile &&>, int(S::*)() const volatile &&), "");
   static_assert(__is_same(decay_t<int S::*const volatile &&>, int S::*), "");
   static_assert(__is_same(decay_t<int (S::*const volatile &&)()>, int(S::*)()), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &&)() &>, int(S::*)() &), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &&)() &&>, int(S::*)() &&), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &&)() const>, int(S::*)() const), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &&)() const &>, int(S::*)() const &), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &&)() const &&>, int(S::*)() const &&), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &&)() volatile>, int(S::*)() volatile), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &&)() volatile &>, int(S::*)() volatile &), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &&)() volatile &&>, int(S::*)() volatile &&), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &&)() const volatile>, int(S::*)() const volatile), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &&)() const volatile &>, int(S::*)() const volatile &), "");
-  static_assert(__is_same(decay_t<int (S::*const volatile &&)() const volatile &&>, int(S::*)() const volatile &&), "");
 }
 
 template <class T> struct CheckAbominableFunction {};
@@ -3385,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), "");
   }
 };
 
@@ -3411,6 +4360,25 @@
   static_assert(__is_same(make_signed_t<const volatile T>, const volatile Expected), "");
 }
 
+#if defined(__ILP32__) || defined(__LLP64__)
+  using Int64 = long long;
+  using UInt64 = unsigned long long;
+#elif defined(__LP64__) || defined(__ILP64__) || defined(__SILP64__)
+  using Int64 = long;
+  using UInt64 = unsigned long;
+#else
+#error Programming model currently unsupported; please add a new entry.
+#endif
+
+enum UnscopedChar : char {}; // deliberately char
+enum class ScopedChar : char {}; // deliberately char
+enum UnscopedUChar : unsigned char {};
+enum class ScopedUChar : unsigned char {};
+enum UnscopedLongLong : long long {};
+enum UnscopedULongLong : unsigned long long {};
+enum class ScopedLongLong : long long {};
+enum class ScopedULongLong : unsigned long long {};
+
 void make_signed() {
   check_make_signed<char, signed char>();
   check_make_signed<signed char, signed char>();
@@ -3437,29 +4405,16 @@
   check_make_signed<char32_t, int>();
 #endif
 
-  enum CE : char {}; // deliberately char
-  check_make_signed<CE, signed char>();
-
-  enum SLLE : long long {};
-  check_make_signed<SLLE, long long>();
+  check_make_signed<UnscopedChar, signed char>();
+  check_make_signed<ScopedChar, signed char>();
+  check_make_signed<UnscopedUChar, signed char>();
+  check_make_signed<ScopedUChar, signed char>();
 
-  enum UCE : unsigned char {};
-  check_make_signed<UCE, signed char>();
+  check_make_signed<UnscopedLongLong, Int64>();
+  check_make_signed<UnscopedULongLong, Int64>();
+  check_make_signed<ScopedLongLong, Int64>();
+  check_make_signed<ScopedULongLong, Int64>();
 
-  enum ULLE : unsigned long long {};
-  check_make_signed<ULLE, long long>();
-
-  enum class CEC : char {}; // deliberately char
-  check_make_signed<CEC, signed char>();
-
-  enum class SLLEC : long long {};
-  check_make_signed<SLLEC, long long>();
-
-  enum class ULLEC : unsigned long long {};
-  check_make_signed<ULLEC, long long>();
-
-  enum class UCEC : unsigned char {};
-  check_make_signed<UCEC, signed char>();
 
   { using ExpectedError = __make_signed(bool); }
   // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'bool'}}
@@ -3528,29 +4483,15 @@
   check_make_unsigned<char32_t, unsigned int>();
 #endif
 
-  enum CE : char {}; // deliberately char
-  check_make_unsigned<CE, unsigned char>();
-
-  enum SLLE : long long {};
-  check_make_unsigned<SLLE, unsigned long long>();
-
-  enum UCE : unsigned char {};
-  check_make_unsigned<UCE, unsigned char>();
-
-  enum ULLE : unsigned long long {};
-  check_make_unsigned<ULLE, unsigned long long>();
-
-  enum class CEC : char {}; // deliberately char
-  check_make_unsigned<CEC, unsigned char>();
-
-  enum class SLLEC : long long {};
-  check_make_unsigned<SLLEC, unsigned long long>();
-
-  enum class ULLEC : unsigned long long {};
-  check_make_unsigned<ULLEC, unsigned long long>();
+  check_make_unsigned<UnscopedChar, unsigned char>();
+  check_make_unsigned<ScopedChar, unsigned char>();
+  check_make_unsigned<UnscopedUChar, unsigned char>();
+  check_make_unsigned<ScopedUChar, unsigned char>();
 
-  enum class UCEC : unsigned char {};
-  check_make_unsigned<UCEC, unsigned char>();
+  check_make_unsigned<UnscopedLongLong, UInt64>();
+  check_make_unsigned<UnscopedULongLong, UInt64>();
+  check_make_unsigned<ScopedLongLong, UInt64>();
+  check_make_unsigned<ScopedULongLong, UInt64>();
 
   { using ExpectedError = __make_unsigned(bool); }
   // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'bool'}}
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -2599,12 +2599,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.
@@ -9214,6 +9212,20 @@
   return Context.getDecltypeType(E, getDecltypeForExpr(E));
 }
 
+static QualType GetEnumUnderlyingType(Sema &S, QualType BaseType,
+                                      SourceLocation Loc) {
+  assert(BaseType->isEnumeralType());
+  EnumDecl *ED = BaseType->castAs<EnumType>()->getDecl();
+  assert(ED && "EnumType has no EnumDecl");
+
+  S.DiagnoseUseOfDecl(ED, Loc);
+
+  QualType Underlying = ED->getIntegerType();
+  assert(!Underlying.isNull());
+
+  return Underlying;
+}
+
 QualType Sema::BuiltinEnumUnderlyingType(QualType BaseType,
                                          SourceLocation Loc) {
   constexpr auto UKind = UTTKind::EnumUnderlyingType;
@@ -9231,24 +9243,19 @@
     return QualType();
   }
 
-  EnumDecl *ED = BaseType->castAs<EnumType>()->getDecl();
-  assert(ED && "EnumType has no EnumDecl");
-
-  DiagnoseUseOfDecl(ED, Loc);
-
-  QualType Underlying = ED->getIntegerType();
-  assert(!Underlying.isNull());
+  QualType Underlying = GetEnumUnderlyingType(*this, BaseType, Loc);
   return Context.getUnaryTransformType(BaseType, Underlying, UKind);
 }
 
 QualType Sema::BuiltinAddPointer(QualType BaseType, SourceLocation Loc) {
-  DeclarationName EntityName(BaseType.getBaseTypeIdentifier());
-  QualType PointerToT =
-      BaseType.isReferenceable() || BaseType->isVoidType()
-          ? BuildPointerType(BaseType.getNonReferenceType(), Loc, EntityName)
-          : BaseType;
-  return Context.getUnaryTransformType(BaseType, PointerToT,
-                                       UTTKind::AddPointer);
+  QualType PointerToT = BaseType.isReferenceable() || BaseType->isVoidType()
+                            ? BuildPointerType(BaseType.getNonReferenceType(),
+                                               Loc, DeclarationName())
+                            : BaseType;
+
+  return PointerToT.isNull() ? QualType()
+                             : Context.getUnaryTransformType(
+                                   BaseType, PointerToT, UTTKind::AddPointer);
 }
 
 QualType Sema::BuiltinRemovePointer(QualType BaseType, SourceLocation Loc) {
@@ -9258,9 +9265,7 @@
     return Context.getUnaryTransformType(BaseType, BaseType, UKind);
 
   QualType Pointee = BaseType->getPointeeType();
-  Qualifiers Quals = Pointee.getQualifiers();
-  return Context.getUnaryTransformType(
-      BaseType, Context.getQualifiedType(Pointee, Quals), UKind);
+  return Context.getUnaryTransformType(BaseType, Pointee, UKind);
 }
 
 QualType Sema::BuiltinDecay(QualType BaseType, SourceLocation Loc) {
@@ -9282,14 +9287,15 @@
 QualType Sema::BuiltinAddReference(QualType BaseType, UTTKind UKind,
                                    SourceLocation Loc) {
   assert(LangOpts.CPlusPlus);
-  DeclarationName EntityName(BaseType.getBaseTypeIdentifier());
   QualType PointerToT =
       QualType(BaseType).isReferenceable()
           ? BuildReferenceType(BaseType,
                                UKind == UnaryTransformType::AddLvalueReference,
-                               Loc, EntityName)
+                               Loc, DeclarationName())
           : BaseType;
-  return Context.getUnaryTransformType(BaseType, PointerToT, UKind);
+  return PointerToT.isNull()
+             ? QualType()
+             : Context.getUnaryTransformType(BaseType, PointerToT, UKind);
 }
 
 QualType Sema::BuiltinRemoveExtent(QualType BaseType, UTTKind UKind,
@@ -9304,19 +9310,25 @@
   return Context.getUnaryTransformType(BaseType, Result, UKind);
 }
 
-QualType Sema::BuiltinRemoveReference(QualType BaseType, UTTKind UKind,
-                                      SourceLocation Loc) {
-  assert(LangOpts.CPlusPlus);
+QualType Sema::RemoveReference(QualType BaseType, bool RemoveCVQualifiers) {
   QualType T = BaseType.getNonReferenceType();
-  if (UKind == UnaryTransformType::RemoveCVRef &&
-      (T.isConstQualified() || T.isVolatileQualified())) {
+  if (RemoveCVQualifiers && (T.isConstQualified() || T.isVolatileQualified())) {
     Qualifiers Quals;
     QualType Unqual = Context.getUnqualifiedArrayType(T, Quals);
     Quals.removeConst();
     Quals.removeVolatile();
     T = Context.getQualifiedType(Unqual, Quals);
   }
-  return Context.getUnaryTransformType(BaseType, T, UKind);
+  return T;
+}
+
+QualType Sema::BuiltinRemoveReference(QualType BaseType, UTTKind UKind,
+                                      SourceLocation Loc) {
+  assert(LangOpts.CPlusPlus);
+  return Context.getUnaryTransformType(
+      BaseType,
+      RemoveReference(BaseType, UKind == UnaryTransformType::RemoveCVRef),
+      UKind);
 }
 
 QualType Sema::BuiltinChangeCVRQualifiers(QualType BaseType, UTTKind UKind,
@@ -9339,6 +9351,30 @@
   return Context.getUnaryTransformType(Unqual, Result, UKind);
 }
 
+static QualType ChangeIntegralSignedness(Sema &S, QualType BaseType,
+                                         UnaryTransformType::UTTKind Kind,
+                                         SourceLocation Loc) {
+  static const std::array<CanQualType *, 6> SignedIntegers = {
+      &S.Context.SignedCharTy, &S.Context.ShortTy,    &S.Context.IntTy,
+      &S.Context.LongTy,       &S.Context.LongLongTy, &S.Context.Int128Ty};
+  static const std::array<CanQualType *, 6> UnsignedIntegers = {
+      &S.Context.UnsignedCharTy,     &S.Context.UnsignedShortTy,
+      &S.Context.UnsignedIntTy,      &S.Context.UnsignedLongTy,
+      &S.Context.UnsignedLongLongTy, &S.Context.UnsignedInt128Ty};
+  const std::array<CanQualType *, 6> *Consider =
+      Kind == UnaryTransformType::UTTKind::MakeSigned ? &SignedIntegers
+                                                      : &UnsignedIntegers;
+
+  auto *Result =
+      llvm::find_if(*Consider, [&S, &BaseType](const CanQual<Type> *T) {
+        return S.Context.getTypeSize(BaseType) ==
+               S.Context.getTypeSize(T->getTypePtr());
+      });
+  assert(Result != Consider->end());
+
+  return QualType((*Result)->getTypePtr(), 0);
+}
+
 QualType Sema::BuiltinChangeSignedness(QualType BaseType, UTTKind UKind,
                                        SourceLocation Loc) {
   bool IsMakeSigned = UKind == UnaryTransformType::MakeSigned;
@@ -9348,9 +9384,16 @@
     return QualType();
   }
 
-  QualType Underlying = IsMakeSigned
-                            ? Context.getCorrespondingSignedType(BaseType)
-                            : Context.getCorrespondingUnsignedType(BaseType);
+  bool IsNonIntIntegral =
+      (BaseType->isChar16Type() || BaseType->isChar32Type() ||
+       BaseType->isWideCharType() ||
+       (BaseType->isEnumeralType() &&
+        !GetEnumUnderlyingType(*this, BaseType, {})->isBitIntType()));
+
+  QualType Underlying =
+      IsNonIntIntegral ? ChangeIntegralSignedness(*this, BaseType, UKind, Loc)
+      : IsMakeSigned   ? Context.getCorrespondingSignedType(BaseType)
+                       : Context.getCorrespondingUnsignedType(BaseType);
   Underlying = Context.getQualifiedType(Underlying, BaseType.getQualifiers());
   return Context.getUnaryTransformType(BaseType, Underlying, UKind);
 }
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -21,11 +21,13 @@
 #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/TokenKinds.h"
 #include "clang/Basic/TypeTraits.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/DeclSpec.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.RemoveReference(T, true);
+    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.RemoveReference(T, true);
+    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
@@ -1070,6 +1070,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);
@@ -1105,6 +1106,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);
@@ -1112,6 +1114,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
@@ -1150,7 +1150,6 @@
     return DeclSpec::TST_##Trait;
 #include "clang/AST/TransformTypeTraits.def"
   default:
-    assert(false && "passed in an unhandled type transformation built-in");
     llvm_unreachable("passed in an unhandled type transformation built-in");
   }
 }
@@ -1158,6 +1157,8 @@
 bool Parser::MaybeParseTypeTransformTypeSpecifier(DeclSpec &DS) {
   if (!NextToken().is(tok::l_paren)) {
     Tok.setKind(tok::identifier);
+    Diag(Tok, diag::ext_keyword_as_ident)
+        << Tok.getIdentifierInfo()->getName() << 0;
     return false;
   }
   DeclSpec::TST TypeTransformTST = TypeTransformTokToDeclSpec();
@@ -1548,6 +1549,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,
@@ -1573,15 +1575,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,
@@ -1589,6 +1594,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/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -5871,7 +5871,7 @@
 /// Used when in C++, as a GCC extension.
 QualType ASTContext::getSignedWCharType() const {
   // FIXME: derive from "Target" ?
-  return IntTy;
+  return WCharTy;
 }
 
 /// getUnsignedWCharType - Return the type of "unsigned wchar_t".
@@ -10804,10 +10804,8 @@
   case BuiltinType::Char8:
     return UnsignedCharTy;
   case BuiltinType::Short:
-  case BuiltinType::Char16:
     return UnsignedShortTy;
   case BuiltinType::Int:
-  case BuiltinType::Char32:
     return UnsignedIntTy;
   case BuiltinType::Long:
   case BuiltinType::ULong:
@@ -10820,7 +10818,6 @@
   // there's no matching "unsigned wchar_t". Therefore we return the unsigned
   // version of its underlying type instead.
   case BuiltinType::WChar_S:
-  case BuiltinType::WChar_U:
     return getUnsignedWCharType();
 
   case BuiltinType::ShortAccum:
@@ -10882,10 +10879,8 @@
   case BuiltinType::Char8:
     return SignedCharTy;
   case BuiltinType::UShort:
-  case BuiltinType::Char16:
     return ShortTy;
   case BuiltinType::UInt:
-  case BuiltinType::Char32:
     return IntTy;
   case BuiltinType::ULong:
     return LongTy;
@@ -10896,7 +10891,6 @@
   // wchar_t is special. It is either unsigned or not, but when it's unsigned,
   // there's no matching "signed wchar_t". Therefore we return the signed
   // version of its underlying type instead.
-  case BuiltinType::WChar_S:
   case BuiltinType::WChar_U:
     return getSignedWCharType();
 
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -2518,6 +2518,8 @@
                                SourceLocation Loc);
   QualType BuiltinRemoveExtent(QualType BaseType, UTTKind UKind,
                                SourceLocation Loc);
+
+  QualType RemoveReference(QualType BaseType, bool RemoveCVQualifiers);
   QualType BuiltinRemoveReference(QualType BaseType, UTTKind UKind,
                                   SourceLocation Loc);
   QualType BuiltinChangeCVRQualifiers(QualType BaseType, UTTKind UKind,
Index: clang/include/clang/Basic/TokenKinds.def
===================================================================
--- clang/include/clang/Basic/TokenKinds.def
+++ clang/include/clang/Basic/TokenKinds.def
@@ -462,12 +462,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)
@@ -514,6 +518,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

Reply via email to