[PATCH] D31004: [Objective-C] Fix __weak type traits with -fobjc-weak
bkelley added a comment. Thank you @rjmccall for the approval. I don't have commit access; would someone be willing to commit this path for me please? Thanks! https://reviews.llvm.org/D31004 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31004: [Objective-C] Fix __weak type traits with -fobjc-weak
rjmccall accepted this revision. rjmccall added a comment. This revision is now accepted and ready to land. Looks great, thanks! https://reviews.llvm.org/D31004 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31004: [Objective-C] Fix __weak type traits with -fobjc-weak
bkelley updated this revision to Diff 92890. bkelley marked an inline comment as done. bkelley added a comment. Removed redundant conditions, per feedback from @rjmccall https://reviews.llvm.org/D31004 Files: lib/AST/Type.cpp lib/Sema/SemaExprCXX.cpp test/SemaObjCXX/objc-weak-type-traits.mm Index: test/SemaObjCXX/objc-weak-type-traits.mm === --- /dev/null +++ test/SemaObjCXX/objc-weak-type-traits.mm @@ -0,0 +1,210 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-weak -fobjc-runtime-has-weak -verify -std=c++11 %s +// expected-no-diagnostics + +// Check the results of the various type-trait query functions on +// lifetime-qualified types in ObjC Weak. + +#define TRAIT_IS_TRUE(Trait, Type) static_assert(Trait(Type), "") +#define TRAIT_IS_FALSE(Trait, Type) static_assert(!Trait(Type), "") +#define TRAIT_IS_TRUE_2(Trait, Type1, Type2) static_assert(Trait(Type1, Type2), "") +#define TRAIT_IS_FALSE_2(Trait, Type1, Type2) static_assert(!Trait(Type1, Type2), "") + +struct HasStrong { id obj; }; +struct HasWeak { __weak id obj; }; +struct HasUnsafeUnretained { __unsafe_unretained id obj; }; + +// __has_nothrow_assign +TRAIT_IS_TRUE(__has_nothrow_assign, __strong id); +TRAIT_IS_TRUE(__has_nothrow_assign, __weak id); +TRAIT_IS_TRUE(__has_nothrow_assign, __autoreleasing id); +TRAIT_IS_TRUE(__has_nothrow_assign, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_nothrow_assign, HasStrong); +TRAIT_IS_TRUE(__has_nothrow_assign, HasWeak); +TRAIT_IS_TRUE(__has_nothrow_assign, HasUnsafeUnretained); + +// __has_nothrow_copy +TRAIT_IS_TRUE(__has_nothrow_copy, __strong id); +TRAIT_IS_TRUE(__has_nothrow_copy, __weak id); +TRAIT_IS_TRUE(__has_nothrow_copy, __autoreleasing id); +TRAIT_IS_TRUE(__has_nothrow_copy, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_nothrow_copy, HasStrong); +TRAIT_IS_TRUE(__has_nothrow_copy, HasWeak); +TRAIT_IS_TRUE(__has_nothrow_copy, HasUnsafeUnretained); + +// __has_nothrow_constructor +TRAIT_IS_TRUE(__has_nothrow_constructor, __strong id); +TRAIT_IS_TRUE(__has_nothrow_constructor, __weak id); +TRAIT_IS_TRUE(__has_nothrow_constructor, __autoreleasing id); +TRAIT_IS_TRUE(__has_nothrow_constructor, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_nothrow_constructor, HasStrong); +TRAIT_IS_TRUE(__has_nothrow_constructor, HasWeak); +TRAIT_IS_TRUE(__has_nothrow_constructor, HasUnsafeUnretained); + +// __has_trivial_assign +TRAIT_IS_TRUE(__has_trivial_assign, __strong id); +TRAIT_IS_FALSE(__has_trivial_assign, __weak id); +TRAIT_IS_TRUE(__has_trivial_assign, __autoreleasing id); +TRAIT_IS_TRUE(__has_trivial_assign, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_trivial_assign, HasStrong); +TRAIT_IS_FALSE(__has_trivial_assign, HasWeak); +TRAIT_IS_TRUE(__has_trivial_assign, HasUnsafeUnretained); + +// __has_trivial_copy +TRAIT_IS_TRUE(__has_trivial_copy, __strong id); +TRAIT_IS_FALSE(__has_trivial_copy, __weak id); +TRAIT_IS_TRUE(__has_trivial_copy, __autoreleasing id); +TRAIT_IS_TRUE(__has_trivial_copy, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_trivial_copy, HasStrong); +TRAIT_IS_FALSE(__has_trivial_copy, HasWeak); +TRAIT_IS_TRUE(__has_trivial_copy, HasUnsafeUnretained); + +// __has_trivial_constructor +TRAIT_IS_TRUE(__has_trivial_constructor, __strong id); +TRAIT_IS_FALSE(__has_trivial_constructor, __weak id); +TRAIT_IS_TRUE(__has_trivial_constructor, __autoreleasing id); +TRAIT_IS_TRUE(__has_trivial_constructor, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_trivial_constructor, HasStrong); +TRAIT_IS_FALSE(__has_trivial_constructor, HasWeak); +TRAIT_IS_TRUE(__has_trivial_constructor, HasUnsafeUnretained); + +// __has_trivial_destructor +TRAIT_IS_TRUE(__has_trivial_destructor, __strong id); +TRAIT_IS_FALSE(__has_trivial_destructor, __weak id); +TRAIT_IS_TRUE(__has_trivial_destructor, __autoreleasing id); +TRAIT_IS_TRUE(__has_trivial_destructor, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_trivial_destructor, HasStrong); +TRAIT_IS_FALSE(__has_trivial_destructor, HasWeak); +TRAIT_IS_TRUE(__has_trivial_destructor, HasUnsafeUnretained); + +// __is_literal +TRAIT_IS_TRUE(__is_literal, __strong id); +TRAIT_IS_TRUE(__is_literal, __weak id); +TRAIT_IS_TRUE(__is_literal, __autoreleasing id); +TRAIT_IS_TRUE(__is_literal, __unsafe_unretained id); + +// __is_literal_type +TRAIT_IS_TRUE(__is_literal_type, __strong id); +TRAIT_IS_TRUE(__is_literal_type, __weak id); +TRAIT_IS_TRUE(__is_literal_type, __autoreleasing id); +TRAIT_IS_TRUE(__is_literal_type, __unsafe_unretained id); + +// __is_pod +TRAIT_IS_TRUE(__is_pod, __strong id); +TRAIT_IS_FALSE(__is_pod, __weak id); +TRAIT_IS_TRUE(__is_pod, __autoreleasing id); +TRAIT_IS_TRUE(__is_pod, __unsafe_unretained id); +TRAIT_IS_TRUE(__is_pod, HasStrong); +TRAIT_IS_FALSE(__is_pod, HasWeak); +TRAIT_IS_TRUE(__is_pod, HasUnsafeUnretained); + +// __is_trivial +TRAIT_IS_TRUE(__is_trivial, __strong id); +TRAIT_IS_FALSE(__is_trivial, __weak id); +TRAIT_IS_TRUE(__is_trivial, __autoreleasing id);
[PATCH] D31004: [Objective-C] Fix __weak type traits with -fobjc-weak
bkelley added a comment. Thanks for the feedback! Apologies for the slow turn around; I was out sick :( Comment at: lib/AST/Type.cpp:2026 - if (Context.getLangOpts().ObjCAutoRefCount) { -switch (getObjCLifetime()) { -case Qualifiers::OCL_ExplicitNone: - return true; - -case Qualifiers::OCL_Strong: -case Qualifiers::OCL_Weak: -case Qualifiers::OCL_Autoreleasing: - return false; - -case Qualifiers::OCL_None: - break; -} - } + if (getQualifiers().hasObjCLifetime() && hasNonTrivialObjCLifetime()) +return false; rjmccall wrote: > Is the first condition not implied by the second? It definitely is. Thanks! https://reviews.llvm.org/D31004 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31004: [Objective-C] Fix __weak type traits with -fobjc-weak
rjmccall added inline comments. Comment at: lib/AST/Type.cpp:2026 - if (Context.getLangOpts().ObjCAutoRefCount) { -switch (getObjCLifetime()) { -case Qualifiers::OCL_ExplicitNone: - return true; - -case Qualifiers::OCL_Strong: -case Qualifiers::OCL_Weak: -case Qualifiers::OCL_Autoreleasing: - return false; - -case Qualifiers::OCL_None: - break; -} - } + if (getQualifiers().hasObjCLifetime() && hasNonTrivialObjCLifetime()) +return false; Is the first condition not implied by the second? https://reviews.llvm.org/D31004 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31004: [Objective-C] Fix __weak type traits with -fobjc-weak
bkelley added a comment. Looks like we can simplify everything by using `hasNonTrivialObjCLifetime()`, like in https://reviews.llvm.org/D31003. https://reviews.llvm.org/D31004 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31004: [Objective-C] Fix __weak type traits with -fobjc-weak
bkelley updated this revision to Diff 92217. bkelley added a comment. Updated with feedback from @rjmccall https://reviews.llvm.org/D31004 Files: lib/AST/Type.cpp lib/Sema/SemaExprCXX.cpp test/SemaObjCXX/objc-weak-type-traits.mm Index: test/SemaObjCXX/objc-weak-type-traits.mm === --- /dev/null +++ test/SemaObjCXX/objc-weak-type-traits.mm @@ -0,0 +1,210 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-weak -fobjc-runtime-has-weak -verify -std=c++11 %s +// expected-no-diagnostics + +// Check the results of the various type-trait query functions on +// lifetime-qualified types in ObjC Weak. + +#define TRAIT_IS_TRUE(Trait, Type) static_assert(Trait(Type), "") +#define TRAIT_IS_FALSE(Trait, Type) static_assert(!Trait(Type), "") +#define TRAIT_IS_TRUE_2(Trait, Type1, Type2) static_assert(Trait(Type1, Type2), "") +#define TRAIT_IS_FALSE_2(Trait, Type1, Type2) static_assert(!Trait(Type1, Type2), "") + +struct HasStrong { id obj; }; +struct HasWeak { __weak id obj; }; +struct HasUnsafeUnretained { __unsafe_unretained id obj; }; + +// __has_nothrow_assign +TRAIT_IS_TRUE(__has_nothrow_assign, __strong id); +TRAIT_IS_TRUE(__has_nothrow_assign, __weak id); +TRAIT_IS_TRUE(__has_nothrow_assign, __autoreleasing id); +TRAIT_IS_TRUE(__has_nothrow_assign, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_nothrow_assign, HasStrong); +TRAIT_IS_TRUE(__has_nothrow_assign, HasWeak); +TRAIT_IS_TRUE(__has_nothrow_assign, HasUnsafeUnretained); + +// __has_nothrow_copy +TRAIT_IS_TRUE(__has_nothrow_copy, __strong id); +TRAIT_IS_TRUE(__has_nothrow_copy, __weak id); +TRAIT_IS_TRUE(__has_nothrow_copy, __autoreleasing id); +TRAIT_IS_TRUE(__has_nothrow_copy, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_nothrow_copy, HasStrong); +TRAIT_IS_TRUE(__has_nothrow_copy, HasWeak); +TRAIT_IS_TRUE(__has_nothrow_copy, HasUnsafeUnretained); + +// __has_nothrow_constructor +TRAIT_IS_TRUE(__has_nothrow_constructor, __strong id); +TRAIT_IS_TRUE(__has_nothrow_constructor, __weak id); +TRAIT_IS_TRUE(__has_nothrow_constructor, __autoreleasing id); +TRAIT_IS_TRUE(__has_nothrow_constructor, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_nothrow_constructor, HasStrong); +TRAIT_IS_TRUE(__has_nothrow_constructor, HasWeak); +TRAIT_IS_TRUE(__has_nothrow_constructor, HasUnsafeUnretained); + +// __has_trivial_assign +TRAIT_IS_TRUE(__has_trivial_assign, __strong id); +TRAIT_IS_FALSE(__has_trivial_assign, __weak id); +TRAIT_IS_TRUE(__has_trivial_assign, __autoreleasing id); +TRAIT_IS_TRUE(__has_trivial_assign, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_trivial_assign, HasStrong); +TRAIT_IS_FALSE(__has_trivial_assign, HasWeak); +TRAIT_IS_TRUE(__has_trivial_assign, HasUnsafeUnretained); + +// __has_trivial_copy +TRAIT_IS_TRUE(__has_trivial_copy, __strong id); +TRAIT_IS_FALSE(__has_trivial_copy, __weak id); +TRAIT_IS_TRUE(__has_trivial_copy, __autoreleasing id); +TRAIT_IS_TRUE(__has_trivial_copy, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_trivial_copy, HasStrong); +TRAIT_IS_FALSE(__has_trivial_copy, HasWeak); +TRAIT_IS_TRUE(__has_trivial_copy, HasUnsafeUnretained); + +// __has_trivial_constructor +TRAIT_IS_TRUE(__has_trivial_constructor, __strong id); +TRAIT_IS_FALSE(__has_trivial_constructor, __weak id); +TRAIT_IS_TRUE(__has_trivial_constructor, __autoreleasing id); +TRAIT_IS_TRUE(__has_trivial_constructor, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_trivial_constructor, HasStrong); +TRAIT_IS_FALSE(__has_trivial_constructor, HasWeak); +TRAIT_IS_TRUE(__has_trivial_constructor, HasUnsafeUnretained); + +// __has_trivial_destructor +TRAIT_IS_TRUE(__has_trivial_destructor, __strong id); +TRAIT_IS_FALSE(__has_trivial_destructor, __weak id); +TRAIT_IS_TRUE(__has_trivial_destructor, __autoreleasing id); +TRAIT_IS_TRUE(__has_trivial_destructor, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_trivial_destructor, HasStrong); +TRAIT_IS_FALSE(__has_trivial_destructor, HasWeak); +TRAIT_IS_TRUE(__has_trivial_destructor, HasUnsafeUnretained); + +// __is_literal +TRAIT_IS_TRUE(__is_literal, __strong id); +TRAIT_IS_TRUE(__is_literal, __weak id); +TRAIT_IS_TRUE(__is_literal, __autoreleasing id); +TRAIT_IS_TRUE(__is_literal, __unsafe_unretained id); + +// __is_literal_type +TRAIT_IS_TRUE(__is_literal_type, __strong id); +TRAIT_IS_TRUE(__is_literal_type, __weak id); +TRAIT_IS_TRUE(__is_literal_type, __autoreleasing id); +TRAIT_IS_TRUE(__is_literal_type, __unsafe_unretained id); + +// __is_pod +TRAIT_IS_TRUE(__is_pod, __strong id); +TRAIT_IS_FALSE(__is_pod, __weak id); +TRAIT_IS_TRUE(__is_pod, __autoreleasing id); +TRAIT_IS_TRUE(__is_pod, __unsafe_unretained id); +TRAIT_IS_TRUE(__is_pod, HasStrong); +TRAIT_IS_FALSE(__is_pod, HasWeak); +TRAIT_IS_TRUE(__is_pod, HasUnsafeUnretained); + +// __is_trivial +TRAIT_IS_TRUE(__is_trivial, __strong id); +TRAIT_IS_FALSE(__is_trivial, __weak id); +TRAIT_IS_TRUE(__is_trivial, __autoreleasing id); +TRAIT_IS_TRUE(__is_trivial, __unsafe_unretained id); +TRAIT_IS_TRUE(__is_trivial,
[PATCH] D31004: [Objective-C] Fix __weak type traits with -fobjc-weak
rjmccall added a comment. I have similar feedback here to the other patch. Please try to see if there's some reasonable way to make this dependent just on the lifetime qualifier without paying attention to the language options. If we, say, decide to start supporting __strong in non-ARC modes, it'd be nice if that just worked without having to revisit all of this code. https://reviews.llvm.org/D31004 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31004: [Objective-C] Fix __weak type traits with -fobjc-weak
bkelley created this revision. Similar to ARC, in ObjCWeak Objective-C object pointers qualified with a weak lifetime are not POD or trivial types. Update the type trait code to reflect this. Copy and adapt the arc-type-traits.mm test case to verify correctness. https://reviews.llvm.org/D31004 Files: lib/AST/Type.cpp lib/Sema/SemaExprCXX.cpp test/SemaObjCXX/objc-weak-type-traits.mm Index: test/SemaObjCXX/objc-weak-type-traits.mm === --- /dev/null +++ test/SemaObjCXX/objc-weak-type-traits.mm @@ -0,0 +1,210 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-weak -fobjc-runtime-has-weak -verify -std=c++11 %s +// expected-no-diagnostics + +// Check the results of the various type-trait query functions on +// lifetime-qualified types in ObjC Weak. + +#define TRAIT_IS_TRUE(Trait, Type) static_assert(Trait(Type), "") +#define TRAIT_IS_FALSE(Trait, Type) static_assert(!Trait(Type), "") +#define TRAIT_IS_TRUE_2(Trait, Type1, Type2) static_assert(Trait(Type1, Type2), "") +#define TRAIT_IS_FALSE_2(Trait, Type1, Type2) static_assert(!Trait(Type1, Type2), "") + +struct HasStrong { id obj; }; +struct HasWeak { __weak id obj; }; +struct HasUnsafeUnretained { __unsafe_unretained id obj; }; + +// __has_nothrow_assign +TRAIT_IS_TRUE(__has_nothrow_assign, __strong id); +TRAIT_IS_TRUE(__has_nothrow_assign, __weak id); +TRAIT_IS_TRUE(__has_nothrow_assign, __autoreleasing id); +TRAIT_IS_TRUE(__has_nothrow_assign, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_nothrow_assign, HasStrong); +TRAIT_IS_TRUE(__has_nothrow_assign, HasWeak); +TRAIT_IS_TRUE(__has_nothrow_assign, HasUnsafeUnretained); + +// __has_nothrow_copy +TRAIT_IS_TRUE(__has_nothrow_copy, __strong id); +TRAIT_IS_TRUE(__has_nothrow_copy, __weak id); +TRAIT_IS_TRUE(__has_nothrow_copy, __autoreleasing id); +TRAIT_IS_TRUE(__has_nothrow_copy, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_nothrow_copy, HasStrong); +TRAIT_IS_TRUE(__has_nothrow_copy, HasWeak); +TRAIT_IS_TRUE(__has_nothrow_copy, HasUnsafeUnretained); + +// __has_nothrow_constructor +TRAIT_IS_TRUE(__has_nothrow_constructor, __strong id); +TRAIT_IS_TRUE(__has_nothrow_constructor, __weak id); +TRAIT_IS_TRUE(__has_nothrow_constructor, __autoreleasing id); +TRAIT_IS_TRUE(__has_nothrow_constructor, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_nothrow_constructor, HasStrong); +TRAIT_IS_TRUE(__has_nothrow_constructor, HasWeak); +TRAIT_IS_TRUE(__has_nothrow_constructor, HasUnsafeUnretained); + +// __has_trivial_assign +TRAIT_IS_TRUE(__has_trivial_assign, __strong id); +TRAIT_IS_FALSE(__has_trivial_assign, __weak id); +TRAIT_IS_TRUE(__has_trivial_assign, __autoreleasing id); +TRAIT_IS_TRUE(__has_trivial_assign, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_trivial_assign, HasStrong); +TRAIT_IS_FALSE(__has_trivial_assign, HasWeak); +TRAIT_IS_TRUE(__has_trivial_assign, HasUnsafeUnretained); + +// __has_trivial_copy +TRAIT_IS_TRUE(__has_trivial_copy, __strong id); +TRAIT_IS_FALSE(__has_trivial_copy, __weak id); +TRAIT_IS_TRUE(__has_trivial_copy, __autoreleasing id); +TRAIT_IS_TRUE(__has_trivial_copy, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_trivial_copy, HasStrong); +TRAIT_IS_FALSE(__has_trivial_copy, HasWeak); +TRAIT_IS_TRUE(__has_trivial_copy, HasUnsafeUnretained); + +// __has_trivial_constructor +TRAIT_IS_TRUE(__has_trivial_constructor, __strong id); +TRAIT_IS_FALSE(__has_trivial_constructor, __weak id); +TRAIT_IS_TRUE(__has_trivial_constructor, __autoreleasing id); +TRAIT_IS_TRUE(__has_trivial_constructor, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_trivial_constructor, HasStrong); +TRAIT_IS_FALSE(__has_trivial_constructor, HasWeak); +TRAIT_IS_TRUE(__has_trivial_constructor, HasUnsafeUnretained); + +// __has_trivial_destructor +TRAIT_IS_TRUE(__has_trivial_destructor, __strong id); +TRAIT_IS_FALSE(__has_trivial_destructor, __weak id); +TRAIT_IS_TRUE(__has_trivial_destructor, __autoreleasing id); +TRAIT_IS_TRUE(__has_trivial_destructor, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_trivial_destructor, HasStrong); +TRAIT_IS_FALSE(__has_trivial_destructor, HasWeak); +TRAIT_IS_TRUE(__has_trivial_destructor, HasUnsafeUnretained); + +// __is_literal +TRAIT_IS_TRUE(__is_literal, __strong id); +TRAIT_IS_TRUE(__is_literal, __weak id); +TRAIT_IS_TRUE(__is_literal, __autoreleasing id); +TRAIT_IS_TRUE(__is_literal, __unsafe_unretained id); + +// __is_literal_type +TRAIT_IS_TRUE(__is_literal_type, __strong id); +TRAIT_IS_TRUE(__is_literal_type, __weak id); +TRAIT_IS_TRUE(__is_literal_type, __autoreleasing id); +TRAIT_IS_TRUE(__is_literal_type, __unsafe_unretained id); + +// __is_pod +TRAIT_IS_TRUE(__is_pod, __strong id); +TRAIT_IS_FALSE(__is_pod, __weak id); +TRAIT_IS_TRUE(__is_pod, __autoreleasing id); +TRAIT_IS_TRUE(__is_pod, __unsafe_unretained id); +TRAIT_IS_TRUE(__is_pod, HasStrong); +TRAIT_IS_FALSE(__is_pod, HasWeak); +TRAIT_IS_TRUE(__is_pod, HasUnsafeUnretained); + +// __is_trivial +TRAIT_IS_TRUE(__is_trivial, __strong id);