summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-08-11 03:03:28 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-08-11 03:03:28 +0000
commitac73de950252d8028408449e669ec7778e944b05 (patch)
tree52647f0d8cdc8645cd6f2c7d4da7eaa39a03173a /clang/lib/Sema/SemaExprCXX.cpp
parent85a549dbc86a17f2e3ed2785528aebb089cc46fb (diff)
downloadbcm5719-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.cpp43
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
OpenPOWER on IntegriCloud