Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
return true;
- // C++0x [meta.unary.prop] Table 49 requires the following traits to be
- // applied to a complete type.
+ // C++1z [meta.unary.prop]:
+ // remove_all_extents_t<T> shall be a complete type or cv void.
case UTT_IsAggregate:
case UTT_IsTrivial:
case UTT_IsTriviallyCopyable:
case UTT_IsStandardLayout:
case UTT_IsPOD:
case UTT_IsLiteral:
+ ArgTy = QualType(ArgTy->getBaseElementTypeUnsafe(), 0);
+ LLVM_FALLTHROUGH;
+ // C++1z [meta.unary.prop]:
+ // T shall be a complete type, cv void, or an array of unknown bound.
case UTT_IsDestructible:
case UTT_IsNothrowDestructible:
- // Fall-through
-
- // These trait expressions are designed to help implement predicates in
- // [meta.unary.prop] despite not being named the same. They are specified
- // by both GCC and the Embarcadero C++ compiler, and require the complete
- // type due to the overarching C++0x type predicates being implemented
- // requiring the complete type.
+ case UTT_IsTriviallyDestructible:
+ // Per the GCC type traits documentation, the same constraints apply to these.
case UTT_HasNothrowAssign:
case UTT_HasNothrowMoveAssign:
case UTT_HasNothrowConstructor:
case UTT_HasTrivialCopy:
case UTT_HasTrivialDestructor:
case UTT_HasVirtualDestructor:
- // Arrays of unknown bound are expressly allowed.
- QualType ElTy = ArgTy;
- if (ArgTy->isIncompleteArrayType())
- ElTy = S.Context.getAsArrayType(ArgTy)->getElementType();
-
- // The void type is expressly allowed.
- if (ElTy->isVoidType())
+ if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType())
return true;
return !S.RequireCompleteType(
- Loc, ElTy, diag::err_incomplete_type_used_in_type_trait_expr);
+ Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
}
}
!RD->hasNonTrivialCopyAssignment();
return false;
case UTT_IsDestructible:
+ case UTT_IsTriviallyDestructible:
case UTT_IsNothrowDestructible:
// C++14 [meta.unary.prop]:
// For reference types, is_destructible<T>::value is true.
if (T->isIncompleteType() || T->isFunctionType())
return false;
+ // A type that requires destruction (via a non-trivial destructor or ARC
+ // lifetime semantics) is not trivially-destructible.
+ if (UTT == UTT_IsTriviallyDestructible && T.isDestructedType())
+ return false;
+
// C++14 [meta.unary.prop]:
// For object types and given U equal to remove_all_extents_t<T>, if the
// expression std::declval<U&>().~U() is well-formed when treated as an
{ int arr[F(__is_pod(void))]; }
{ int arr[F(__is_pod(cvoid))]; }
// { int arr[F(__is_pod(NonPODUnion))]; }
+
+ { int arr[T(__is_pod(ACompleteType))]; }
+ { int arr[F(__is_pod(AnIncompleteType))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_pod(AnIncompleteType[]))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_pod(AnIncompleteType[1]))]; } // expected-error {{incomplete type}}
}
typedef Empty EmptyAr[10];
{ int arr[F(__is_empty(IntArNB))]; }
{ int arr[F(__is_empty(HasAnonymousUnion))]; }
// { int arr[F(__is_empty(DerivesVirt))]; }
+
+ { int arr[T(__is_empty(ACompleteType))]; }
+ { int arr[F(__is_empty(AnIncompleteType))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_empty(AnIncompleteType[]))]; }
+ { int arr[F(__is_empty(AnIncompleteType[1]))]; }
}
typedef Derives ClassType;
constexpr bool TrueAfterCpp14 = __cplusplus > 201402L;
__is_aggregate(AnIncompleteType); // expected-error {{incomplete type}}
+ __is_aggregate(AnIncompleteType[]); // expected-error {{incomplete type}}
+ __is_aggregate(AnIncompleteType[1]); // expected-error {{incomplete type}}
__is_aggregate(AnIncompleteTypeAr); // expected-error {{incomplete type}}
__is_aggregate(AnIncompleteTypeArNB); // expected-error {{incomplete type}}
__is_aggregate(AnIncompleteTypeArMB); // expected-error {{incomplete type}}
int t32[F(__is_trivial(SuperNonTrivialStruct))];
int t33[F(__is_trivial(NonTCStruct))];
int t34[F(__is_trivial(ExtDefaulted))];
+
+ int t40[T(__is_trivial(ACompleteType))];
+ int t41[F(__is_trivial(AnIncompleteType))]; // expected-error {{incomplete type}}
+ int t42[F(__is_trivial(AnIncompleteType[]))]; // expected-error {{incomplete type}}
+ int t43[F(__is_trivial(AnIncompleteType[1]))]; // expected-error {{incomplete type}}
+ int t44[F(__is_trivial(void))];
+ int t45[F(__is_trivial(const volatile void))];
}
void is_trivially_copyable2()
int t34[T(__is_trivially_copyable(const int))];
int t35[T(__is_trivially_copyable(volatile int))];
+
+ int t40[T(__is_trivially_copyable(ACompleteType))];
+ int t41[F(__is_trivially_copyable(AnIncompleteType))]; // expected-error {{incomplete type}}
+ int t42[F(__is_trivially_copyable(AnIncompleteType[]))]; // expected-error {{incomplete type}}
+ int t43[F(__is_trivially_copyable(AnIncompleteType[1]))]; // expected-error {{incomplete type}}
+ int t44[F(__is_trivially_copyable(void))];
+ int t45[F(__is_trivially_copyable(const volatile void))];
}
struct CStruct {
int t15[F(__is_standard_layout(CppStructNonStandardByBaseAr))];
int t16[F(__is_standard_layout(CppStructNonStandardBySameBase))];
int t17[F(__is_standard_layout(CppStructNonStandardBy2ndVirtBase))];
+
+ int t40[T(__is_standard_layout(ACompleteType))];
+ int t41[F(__is_standard_layout(AnIncompleteType))]; // expected-error {{incomplete type}}
+ int t42[F(__is_standard_layout(AnIncompleteType[]))]; // expected-error {{incomplete type}}
+ int t43[F(__is_standard_layout(AnIncompleteType[1]))]; // expected-error {{incomplete type}}
+ int t44[F(__is_standard_layout(void))];
+ int t45[F(__is_standard_layout(const volatile void))];
}
void is_signed()
TrivialMoveButNotCopy)))]; }
{ int arr[T((__is_assignable(TrivialMoveButNotCopy &,
TrivialMoveButNotCopy &&)))]; }
+
+ { int arr[T(__is_assignable(ACompleteType, ACompleteType))]; }
+ { int arr[F(__is_assignable(AnIncompleteType, AnIncompleteType))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_assignable(AnIncompleteType[], AnIncompleteType[]))]; }
+ { int arr[F(__is_assignable(AnIncompleteType[1], AnIncompleteType[1]))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_assignable(void, void))]; }
+ { int arr[F(__is_assignable(const volatile void, const volatile void))]; }
}
void constructible_checks() {
// PR25513
{ int arr[F(__is_constructible(int(int)))]; }
+
+ { int arr[T(__is_constructible(ACompleteType))]; }
+ { int arr[T(__is_nothrow_constructible(ACompleteType))]; }
+ { int arr[F(__is_constructible(AnIncompleteType))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_nothrow_constructible(AnIncompleteType))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_constructible(AnIncompleteType[]))]; }
+ { int arr[F(__is_nothrow_constructible(AnIncompleteType[]))]; }
+ { int arr[F(__is_constructible(AnIncompleteType[1]))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_nothrow_constructible(AnIncompleteType[1]))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_constructible(void))]; }
+ { int arr[F(__is_nothrow_constructible(void))]; }
+ { int arr[F(__is_constructible(const volatile void))]; }
+ { int arr[F(__is_nothrow_constructible(const volatile void))]; }
}
// Instantiation of __is_trivially_constructible
{ int arr[F((is_trivially_constructible<NonTrivialDefault>::value))]; }
{ int arr[F((is_trivially_constructible<ThreeArgCtor, int*, char*, int&>::value))]; }
{ int arr[F((is_trivially_constructible<Abstract>::value))]; } // PR19178
+
+ { int arr[T(__is_trivially_constructible(ACompleteType))]; }
+ { int arr[F(__is_trivially_constructible(AnIncompleteType))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_trivially_constructible(AnIncompleteType[]))]; }
+ { int arr[F(__is_trivially_constructible(AnIncompleteType[1]))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_trivially_constructible(void))]; }
+ { int arr[F(__is_trivially_constructible(const volatile void))]; }
}
void array_rank() {
{ int arr[F(__is_destructible(AllDeleted))]; }
{ int arr[T(__is_destructible(ThrowingDtor))]; }
{ int arr[T(__is_destructible(NoThrowDtor))]; }
+
+ { int arr[T(__is_destructible(ACompleteType))]; }
+ { int arr[F(__is_destructible(AnIncompleteType))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_destructible(AnIncompleteType[]))]; }
+ { int arr[F(__is_destructible(AnIncompleteType[1]))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_destructible(void))]; }
+ { int arr[F(__is_destructible(const volatile void))]; }
}
void is_nothrow_destructible_test() {
{ int arr[F(__is_nothrow_destructible(ThrowingDtor))]; }
{ int arr[T(__is_nothrow_destructible(NoExceptDtor))]; }
{ int arr[T(__is_nothrow_destructible(NoThrowDtor))]; }
+
+ { int arr[T(__is_nothrow_destructible(ACompleteType))]; }
+ { int arr[F(__is_nothrow_destructible(AnIncompleteType))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_nothrow_destructible(AnIncompleteType[]))]; }
+ { int arr[F(__is_nothrow_destructible(AnIncompleteType[1]))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_nothrow_destructible(void))]; }
+ { int arr[F(__is_nothrow_destructible(const volatile void))]; }
+}
+
+void is_trivially_destructible_test() {
+ { int arr[T(__is_trivially_destructible(int))]; }
+ { int arr[T(__is_trivially_destructible(int[2]))]; }
+ { int arr[F(__is_trivially_destructible(int[]))]; }
+ { int arr[F(__is_trivially_destructible(void))]; }
+ { int arr[T(__is_trivially_destructible(int &))]; }
+ { int arr[F(__is_trivially_destructible(HasDest))]; }
+ { int arr[F(__is_trivially_destructible(AllPrivate))]; }
+ { int arr[F(__is_trivially_destructible(SuperNonTrivialStruct))]; }
+ { int arr[T(__is_trivially_destructible(AllDefaulted))]; }
+ { int arr[F(__is_trivially_destructible(AllDeleted))]; }
+ { int arr[F(__is_trivially_destructible(ThrowingDtor))]; }
+ { int arr[F(__is_trivially_destructible(NoThrowDtor))]; }
+
+ { int arr[T(__is_trivially_destructible(ACompleteType))]; }
+ { int arr[F(__is_trivially_destructible(AnIncompleteType))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_trivially_destructible(AnIncompleteType[]))]; }
+ { int arr[F(__is_trivially_destructible(AnIncompleteType[1]))]; } // expected-error {{incomplete type}}
+ { int arr[F(__is_trivially_destructible(void))]; }
+ { int arr[F(__is_trivially_destructible(const volatile void))]; }
}