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) {
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);
}
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);
}
}
-// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -std=c++11 %s
// Check the results of the various type-trait query functions on
// lifetime-qualified types in ARC.
#define TRAIT_IS_TRUE(Trait, Type) char JOIN2(Trait,__LINE__)[Trait(Type)? 1 : -1]
#define TRAIT_IS_FALSE(Trait, Type) char JOIN2(Trait,__LINE__)[Trait(Type)? -1 : 1]
+#define TRAIT_IS_TRUE_2(Trait, Type1, Type2) char JOIN2(Trait,__LINE__)[Trait(Type1, Type2)? 1 : -1]
+#define TRAIT_IS_FALSE_2(Trait, Type1, Type2) char JOIN2(Trait,__LINE__)[Trait(Type1, Type2)? -1 : 1]
// __has_nothrow_assign
TRAIT_IS_TRUE(__has_nothrow_assign, __strong id);
TRAIT_IS_TRUE(__is_standard_layout, __autoreleasing id);
TRAIT_IS_TRUE(__is_standard_layout, __unsafe_unretained id);
+// __is_trivally_assignable
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __strong id&, __strong id);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __strong id&, __weak id);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __strong id&, __autoreleasing id);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __strong id&, __unsafe_unretained id);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __strong id&, __strong id&&);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __strong id&, __weak id&&);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __strong id&, __autoreleasing id&&);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __strong id&, __unsafe_unretained id&&);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __strong id);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __weak id);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __autoreleasing id);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __unsafe_unretained id);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __strong id&&);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __weak id&&);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __autoreleasing id&&);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __unsafe_unretained id&&);
+
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __autoreleasing id&, __strong id);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __autoreleasing id&, __weak id);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __autoreleasing id&, __autoreleasing id);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __autoreleasing id&, __unsafe_unretained id);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __autoreleasing id&, __strong id&&);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __autoreleasing id&, __weak id&&);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __autoreleasing id&, __autoreleasing id&&);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __autoreleasing id&, __unsafe_unretained id&&);
+
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __strong id);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __weak id);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __autoreleasing id);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __unsafe_unretained id);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __strong id&&);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __weak id&&);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __autoreleasing id&&);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __unsafe_unretained id&&);
+
+// __is_trivally_constructible
+TRAIT_IS_FALSE(__is_trivially_constructible, __strong id);
+TRAIT_IS_FALSE(__is_trivially_constructible, __weak id);
+TRAIT_IS_FALSE(__is_trivially_constructible, __autoreleasing id);
+TRAIT_IS_TRUE(__is_trivially_constructible, __unsafe_unretained id);
+
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __strong id, __strong id);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __strong id, __weak id);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __strong id, __autoreleasing id);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __strong id, __unsafe_unretained id);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __strong id, __strong id&&);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __strong id, __weak id&&);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __strong id, __autoreleasing id&&);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __strong id, __unsafe_unretained id&&);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __strong id);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __weak id);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __autoreleasing id);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __unsafe_unretained id);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __strong id&&);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __weak id&&);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __autoreleasing id&&);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __unsafe_unretained id&&);
+
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __autoreleasing id, __strong id);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __autoreleasing id, __weak id);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __autoreleasing id, __autoreleasing id);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __autoreleasing id, __unsafe_unretained id);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __autoreleasing id, __strong id&&);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __autoreleasing id, __weak id&&);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __autoreleasing id, __autoreleasing id&&);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __autoreleasing id, __unsafe_unretained id&&);
+
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __strong id);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __weak id);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __autoreleasing id);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __unsafe_unretained id);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __strong id&&);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __weak id&&);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __autoreleasing id&&);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __unsafe_unretained id&&);
+