diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -468,6 +468,10 @@ 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) @@ -526,6 +530,10 @@ KEYWORD(__remove_volatile, KEYCXX) // Clang-only C++ Type Traits +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_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX) // Embarcadero Expression Traits diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2429,8 +2429,11 @@ 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 BuiltinChangeCVQualifiers(QualType BaseType, UTTKind UKind, SourceLocation Loc); QualType BuiltinChangeSignedness(QualType BaseType, UTTKind UKind, diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1531,6 +1531,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, @@ -1556,6 +1557,7 @@ 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, @@ -1565,6 +1567,7 @@ 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, @@ -1572,6 +1575,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, diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1069,6 +1069,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); @@ -1095,6 +1096,7 @@ REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable); REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible); REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible); + REVERTIBLE_TYPE_TRAIT(__is_nullptr); REVERTIBLE_TYPE_TRAIT(__is_object); REVERTIBLE_TYPE_TRAIT(__is_pod); REVERTIBLE_TYPE_TRAIT(__is_pointer); @@ -1104,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); @@ -1111,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); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -11,6 +11,7 @@ /// //===----------------------------------------------------------------------===// +#include "clang/AST/Type.h" #include "clang/Sema/Template.h" #include "clang/Sema/SemaInternal.h" #include "TreeTransform.h" @@ -4728,12 +4729,15 @@ case UTT_IsIntegral: case UTT_IsFloatingPoint: case UTT_IsArray: + case UTT_IsBoundedArray: case UTT_IsPointer: + case UTT_IsNullPointer: 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: @@ -4754,6 +4758,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. @@ -4811,6 +4816,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; @@ -4854,6 +4863,12 @@ return false; } +static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, + ArrayRef 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"); @@ -4871,8 +4886,14 @@ return T->isFloatingType(); case UTT_IsArray: return T->isArrayType(); + case UTT_IsBoundedArray: + return T->isArrayType() && !T->isIncompleteArrayType(); + case UTT_IsUnboundedArray: + return T->isIncompleteArrayType(); case UTT_IsPointer: return T->isAnyPointerType(); + case UTT_IsNullPointer: + return T->isNullPtrType(); case UTT_IsLvalueReference: return T->isLValueReferenceType(); case UTT_IsRvalueReference: @@ -4883,6 +4904,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: @@ -5252,11 +5275,39 @@ return !T->isIncompleteType(); case UTT_HasUniqueObjectRepresentations: return C.hasUniqueObjectRepresentations(T); + case UTT_IsCopyConstructible: + case UTT_IsCopyAssignable: { + if (T->isIncompleteArrayType()) + return false; + if (!T.isReferenceable(LangStandard::getLangStandardForKind(Self.LangOpts.LangStd).isCPlusPlus())) + 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 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(LangStandard::getLangStandardForKind(Self.LangOpts.LangStd).isCPlusPlus())) + return false; -static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT, - QualType RhsT, SourceLocation KeyLoc); + QualType AssigneeType = Self.RemoveReference(T, true); + AssigneeType = Self.BuildReferenceType(AssigneeType, false, KeyLoc, T.getBaseTypeIdentifier()); + if (UTT == UTT_IsMoveAssignable) + return not EvaluateBinaryTypeTrait(Self, BTT_IsAssignable, T, AssigneeType, KeyLoc); + Self.Diag(KeyLoc, diag::err_typecheck_converted_constant_expression) << T << AssigneeType; + llvm::SmallVector Parameters = {C.CreateTypeSourceInfo(T), C.CreateTypeSourceInfo(AssigneeType)}; + return evaluateTypeTrait(Self, TT_IsConstructible, KeyLoc, Parameters, {}); + } + } +} static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, ArrayRef Args, diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -9212,18 +9212,21 @@ return Context.getUnaryTransformType(BaseType, Underlying, UKind); } -QualType Sema::BuiltinRemoveReference(QualType BaseType, UTTKind UKind, - SourceLocation Loc) { +QualType Sema::RemoveReference(QualType BaseType, bool RemoveCVQualifiers) { QualType Underlying = BaseType.getNonReferenceType(); Qualifiers Quals = Underlying.getQualifiers(); - if (UKind == UnaryTransformType::RemoveCVRef) { + if (RemoveCVQualifiers) { Quals.removeConst(); Quals.removeVolatile(); } + return QualType(Underlying.getSplitUnqualifiedType().Ty, Quals.getAsOpaqueValue()); +} + +QualType Sema::BuiltinRemoveReference(QualType BaseType, UTTKind UKind, + SourceLocation Loc) { return Context.getUnaryTransformType( BaseType, - QualType(Underlying.getSplitUnqualifiedType().Ty, - Quals.getAsOpaqueValue()), + RemoveReference(BaseType, UKind == UnaryTransformType::RemoveCVRef), UKind); } diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp --- a/clang/test/SemaCXX/type-traits.cpp +++ b/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,30 @@ { 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 +734,66 @@ int t31[F(__is_array(cvoid*))]; } +void is_bounded_array() +{ + 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*))]; +} + +void is_unbounded_array() +{ + 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*))]; +} + template void tmpl_func(T&) {} template struct type_wrapper { @@ -934,6 +1026,43 @@ 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 +1610,8 @@ typedef const IntAr ConstIntAr; typedef ConstIntAr ConstIntArAr[4]; -struct HasCopy { - HasCopy(HasCopy& cp); +struct HasMutableCopyCtor { + HasMutableCopyCtor(HasMutableCopyCtor& cp); }; struct HasMove { @@ -1518,7 +1647,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 +1710,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 +1730,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 +1764,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 +1821,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 +1930,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 +1960,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 +1987,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 +2454,467 @@ { 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 +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(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + + // // User-defined types + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); // expected-note{{in instantiation of function template specialization}} + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + + // Non-referencable types + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); + copy_constructible_checks_impl(); +} + +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 +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(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + + // // User-defined types + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); // expected-note{{in instantiation of function template specialization}} + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + + // Non-referencable types + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); + move_constructible_checks_impl(); +} + +template +void copy_assignable_checks_impl() { + { int arr[T(__is_copy_assignable(T) == expected)]; } // expected-error{{incomplete type}} + // { int arr[F(__is_copy_assignable(const T))]; } // expected-erxror{{incomplete type}} + // { int arr[F(__is_copy_assignable(volatile T))]; } // expectexd-error{{incomplete type}} + // { int arr[F(__is_copy_assignable(const volatile T))]; } // xexpected-error{{incomplete type}} +} + +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 + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + + // // User-defined types + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); // expected-note{{in instantiation of function template specialization}} + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + + // Non-referencable types + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); + copy_assignable_checks_impl(); +} + // Instantiation of __is_trivially_constructible template struct is_trivially_constructible {