diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-08-11 03:03:28 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-08-11 03:03:28 +0000 |
commit | ac73de950252d8028408449e669ec7778e944b05 (patch) | |
tree | 52647f0d8cdc8645cd6f2c7d4da7eaa39a03173a /clang/lib/Sema/SemaExprCXX.cpp | |
parent | 85a549dbc86a17f2e3ed2785528aebb089cc46fb (diff) | |
download | bcm5719-llvm-ac73de950252d8028408449e669ec7778e944b05.tar.gz bcm5719-llvm-ac73de950252d8028408449e669ec7778e944b05.zip |
[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
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 9dce8176006..f7103c885ad 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -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 |