forked from OSchip/llvm-project
[MSVC Compat] Implement __is_destructible, __is_nothrow_destructible
Our implementations of these type trait intrinsics simply mapped them to __has_trivial_destructor. Instead, flesh these intrinsics out with a full implementation which matches the standard's description. llvm-svn: 244564
This commit is contained in:
parent
85a549dbc8
commit
ac73de9502
|
@ -3814,8 +3814,47 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
|
|||
return false;
|
||||
case UTT_IsDestructible:
|
||||
case UTT_IsNothrowDestructible:
|
||||
// FIXME: Implement UTT_IsDestructible and UTT_IsNothrowDestructible.
|
||||
// For now, let's fall through.
|
||||
// C++14 [meta.unary.prop]:
|
||||
// For reference types, is_destructible<T>::value is true.
|
||||
if (T->isReferenceType())
|
||||
return true;
|
||||
|
||||
// Objective-C++ ARC: autorelease types don't require destruction.
|
||||
if (T->isObjCLifetimeType() &&
|
||||
T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing)
|
||||
return true;
|
||||
|
||||
// C++14 [meta.unary.prop]:
|
||||
// For incomplete types and function types, is_destructible<T>::value is
|
||||
// false.
|
||||
if (T->isIncompleteType() || T->isFunctionType())
|
||||
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
|
||||
// unevaluated operand (Clause 5), then is_destructible<T>::value is true
|
||||
if (auto *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
|
||||
CXXDestructorDecl *Destructor = Self.LookupDestructor(RD);
|
||||
if (!Destructor)
|
||||
return false;
|
||||
// C++14 [dcl.fct.def.delete]p2:
|
||||
// A program that refers to a deleted function implicitly or
|
||||
// explicitly, other than to declare it, is ill-formed.
|
||||
if (Destructor->isDeleted())
|
||||
return false;
|
||||
if (C.getLangOpts().AccessControl && Destructor->getAccess() != AS_public)
|
||||
return false;
|
||||
if (UTT == UTT_IsNothrowDestructible) {
|
||||
const FunctionProtoType *CPT =
|
||||
Destructor->getType()->getAs<FunctionProtoType>();
|
||||
CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
|
||||
if (!CPT || !CPT->isNothrow(C))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
case UTT_HasTrivialDestructor:
|
||||
// http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
|
||||
// If __is_pod (type) is true or type is a reference type
|
||||
|
|
|
@ -150,6 +150,18 @@ struct VariadicCtor {
|
|||
template<typename...T> VariadicCtor(T...);
|
||||
};
|
||||
|
||||
struct ThrowingDtor {
|
||||
~ThrowingDtor() throw(int);
|
||||
};
|
||||
|
||||
struct NoExceptDtor {
|
||||
~NoExceptDtor() noexcept(true);
|
||||
};
|
||||
|
||||
struct NoThrowDtor {
|
||||
~NoThrowDtor() throw();
|
||||
};
|
||||
|
||||
void is_pod()
|
||||
{
|
||||
{ int arr[T(__is_pod(int))]; }
|
||||
|
@ -2019,3 +2031,34 @@ void array_extent() {
|
|||
int t02[T(__array_extent(ConstIntArAr, 0) == 4)];
|
||||
int t03[T(__array_extent(ConstIntArAr, 1) == 10)];
|
||||
}
|
||||
|
||||
void is_destructible_test() {
|
||||
{ int arr[T(__is_destructible(int))]; }
|
||||
{ int arr[T(__is_destructible(int[2]))]; }
|
||||
{ int arr[F(__is_destructible(int[]))]; }
|
||||
{ int arr[F(__is_destructible(void))]; }
|
||||
{ int arr[T(__is_destructible(int &))]; }
|
||||
{ int arr[T(__is_destructible(HasDest))]; }
|
||||
{ int arr[F(__is_destructible(AllPrivate))]; }
|
||||
{ int arr[T(__is_destructible(SuperNonTrivialStruct))]; }
|
||||
{ int arr[T(__is_destructible(AllDefaulted))]; }
|
||||
{ int arr[F(__is_destructible(AllDeleted))]; }
|
||||
{ int arr[T(__is_destructible(ThrowingDtor))]; }
|
||||
{ int arr[T(__is_destructible(NoThrowDtor))]; }
|
||||
}
|
||||
|
||||
void is_nothrow_destructible_test() {
|
||||
{ int arr[T(__is_nothrow_destructible(int))]; }
|
||||
{ int arr[T(__is_nothrow_destructible(int[2]))]; }
|
||||
{ int arr[F(__is_nothrow_destructible(int[]))]; }
|
||||
{ int arr[F(__is_nothrow_destructible(void))]; }
|
||||
{ int arr[T(__is_nothrow_destructible(int &))]; }
|
||||
{ int arr[T(__is_nothrow_destructible(HasDest))]; }
|
||||
{ int arr[F(__is_nothrow_destructible(AllPrivate))]; }
|
||||
{ int arr[T(__is_nothrow_destructible(SuperNonTrivialStruct))]; }
|
||||
{ int arr[T(__is_nothrow_destructible(AllDefaulted))]; }
|
||||
{ int arr[F(__is_nothrow_destructible(AllDeleted))]; }
|
||||
{ int arr[F(__is_nothrow_destructible(ThrowingDtor))]; }
|
||||
{ int arr[T(__is_nothrow_destructible(NoExceptDtor))]; }
|
||||
{ int arr[T(__is_nothrow_destructible(NoThrowDtor))]; }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue