r244564 - [MSVC Compat] Implement __is_destructible, __is_nothrow_destructible
David Majnemer via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 10 20:03:28 PDT 2015
Author: majnemer
Date: Mon Aug 10 22:03:28 2015
New Revision: 244564
URL: http://llvm.org/viewvc/llvm-project?rev=244564&view=rev
Log:
[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.
Modified:
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/SemaCXX/type-traits.cpp
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=244564&r1=244563&r2=244564&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Aug 10 22:03:28 2015
@@ -3814,8 +3814,47 @@ static bool EvaluateUnaryTypeTrait(Sema
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
Modified: cfe/trunk/test/SemaCXX/type-traits.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/type-traits.cpp?rev=244564&r1=244563&r2=244564&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/type-traits.cpp (original)
+++ cfe/trunk/test/SemaCXX/type-traits.cpp Mon Aug 10 22:03:28 2015
@@ -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))]; }
+}
More information about the cfe-commits
mailing list