diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-06-29 00:49:17 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-06-29 00:49:17 +0000 |
commit | 14b23277db34fd33292dd9ec23abb13e7cb72613 (patch) | |
tree | 4fc7a6ded88eef3d00ec1107d734e23263f646c4 /lib/Sema/SemaExprCXX.cpp | |
parent | 65cf624deb6ae4a235e567697cd1fc5ecb26cfcf (diff) |
Teach the __is_trivially_assignable and __is_trivially_constructible
type traits that assignment to/construction of a lifetime-qualified
object under ARC is *not* trivial. Fixes <rdar://problem/11738725>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159401 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 27ac381867..8efd465580 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -3335,6 +3335,25 @@ ExprResult Sema::ActOnBinaryTypeTrait(BinaryTypeTrait BTT, return BuildBinaryTypeTrait(BTT, KWLoc, LhsTSInfo, RhsTSInfo, RParen); } +/// \brief Determine whether T has a non-trivial Objective-C lifetime in +/// ARC mode. +static bool hasNontrivialObjCLifetime(QualType T) { + switch (T.getObjCLifetime()) { + case Qualifiers::OCL_ExplicitNone: + return false; + + case Qualifiers::OCL_Strong: + case Qualifiers::OCL_Weak: + case Qualifiers::OCL_Autoreleasing: + return true; + + case Qualifiers::OCL_None: + return T->isObjCLifetimeType(); + } + + llvm_unreachable("Unknown ObjC lifetime qualifier"); +} + static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, ArrayRef<TypeSourceInfo *> Args, SourceLocation RParenLoc) { @@ -3408,8 +3427,14 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, ArgExprs.size())); if (Result.isInvalid() || SFINAE.hasErrorOccurred()) return false; - - // The initialization succeeded; not make sure there are no non-trivial + + // Under Objective-C ARC, if the destination has non-trivial Objective-C + // lifetime, this is a non-trivial construction. + if (S.getLangOpts().ObjCAutoRefCount && + hasNontrivialObjCLifetime(Args[0]->getType().getNonReferenceType())) + return false; + + // The initialization succeeded; now make sure there are no non-trivial // calls. return !Result.get()->hasNonTrivialCall(S.Context); } @@ -3590,6 +3615,12 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT, if (Result.isInvalid() || SFINAE.hasErrorOccurred()) return false; + // Under Objective-C ARC, if the destination has non-trivial Objective-C + // lifetime, this is a non-trivial assignment. + if (Self.getLangOpts().ObjCAutoRefCount && + hasNontrivialObjCLifetime(LhsT.getNonReferenceType())) + return false; + return !Result.get()->hasNonTrivialCall(Self.Context); } } |