summaryrefslogtreecommitdiffstats
path: root/test/SemaObjCXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaObjCXX')
-rw-r--r--test/SemaObjCXX/Inputs/arc-system-header.h14
-rw-r--r--test/SemaObjCXX/arc-0x.mm32
-rw-r--r--test/SemaObjCXX/arc-bool-conversion.mm7
-rw-r--r--test/SemaObjCXX/arc-bridged-cast.mm36
-rw-r--r--test/SemaObjCXX/arc-libcxx.mm11
-rw-r--r--test/SemaObjCXX/arc-libstdcxx.mm10
-rw-r--r--test/SemaObjCXX/arc-memfunc.mm15
-rw-r--r--test/SemaObjCXX/arc-non-pod.mm116
-rw-r--r--test/SemaObjCXX/arc-object-init-destroy.mm52
-rw-r--r--test/SemaObjCXX/arc-overloading.mm175
-rw-r--r--test/SemaObjCXX/arc-system-header.mm10
-rw-r--r--test/SemaObjCXX/arc-templates.mm254
-rw-r--r--test/SemaObjCXX/arc-type-conversion.mm221
-rw-r--r--test/SemaObjCXX/arc-type-traits.mm90
-rw-r--r--test/SemaObjCXX/arc-unavailable-for-weakref.mm47
-rw-r--r--test/SemaObjCXX/exceptions-fragile.mm2
-rw-r--r--test/SemaObjCXX/gc-attributes.mm4
-rw-r--r--test/SemaObjCXX/null_objc_pointer.mm13
-rw-r--r--test/SemaObjCXX/nullptr.mm5
-rw-r--r--test/SemaObjCXX/property-type-mismatch.mm19
-rw-r--r--test/SemaObjCXX/related-result-type-inference.mm2
21 files changed, 1130 insertions, 5 deletions
diff --git a/test/SemaObjCXX/Inputs/arc-system-header.h b/test/SemaObjCXX/Inputs/arc-system-header.h
new file mode 100644
index 0000000..d7adeb4
--- /dev/null
+++ b/test/SemaObjCXX/Inputs/arc-system-header.h
@@ -0,0 +1,14 @@
+@interface B
+@end
+
+
+@interface A {
+@public
+ union {
+ struct {
+ B *b;
+ } a_b;
+ void *void_ptr;
+ } data;
+}
+@end
diff --git a/test/SemaObjCXX/arc-0x.mm b/test/SemaObjCXX/arc-0x.mm
new file mode 100644
index 0000000..fa022af
--- /dev/null
+++ b/test/SemaObjCXX/arc-0x.mm
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=c++0x -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -verify -fblocks -fobjc-exceptions %s
+
+// "Move" semantics, trivial version.
+void move_it(__strong id &&from) {
+ id to = static_cast<__strong id&&>(from);
+}
+
+// Deduction with 'auto'.
+@interface A
++ alloc;
+- init;
+@end
+
+// Ensure that deduction works with lifetime qualifiers.
+void deduction(id obj) {
+ auto a = [[A alloc] init];
+ __strong A** aPtr = &a;
+
+ auto a2([[A alloc] init]);
+ __strong A** aPtr2 = &a2;
+
+ __strong id *idp = new auto(obj);
+
+ __strong id array[17];
+ for (auto x : array) {
+ __strong id *xPtr = &x;
+ }
+
+ @try {
+ } @catch (auto e) { // expected-error {{'auto' not allowed in exception declaration}}
+ }
+}
diff --git a/test/SemaObjCXX/arc-bool-conversion.mm b/test/SemaObjCXX/arc-bool-conversion.mm
new file mode 100644
index 0000000..86da3ca
--- /dev/null
+++ b/test/SemaObjCXX/arc-bool-conversion.mm
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -verify -fblocks -triple x86_64-apple-darwin10.0.0 %s
+// rdar://9310049
+
+bool fn(id obj) {
+ return (bool)obj;
+}
+
diff --git a/test/SemaObjCXX/arc-bridged-cast.mm b/test/SemaObjCXX/arc-bridged-cast.mm
new file mode 100644
index 0000000..cbbe79e
--- /dev/null
+++ b/test/SemaObjCXX/arc-bridged-cast.mm
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -fblocks -verify %s
+
+typedef const void *CFTypeRef;
+typedef const struct __CFString *CFStringRef;
+
+@interface NSString
+@end
+
+CFTypeRef CFCreateSomething();
+CFStringRef CFCreateString();
+CFTypeRef CFGetSomething();
+CFStringRef CFGetString();
+
+id CreateSomething();
+NSString *CreateNSString();
+
+template<typename IdType, typename StringType, typename IntPtrType>
+void from_cf() {
+ id obj1 = (__bridge_transfer IdType)CFCreateSomething();
+ id obj2 = (__bridge_transfer StringType)CFCreateString();
+ (__bridge IntPtrType)CFCreateSomething(); // expected-error{{incompatible types casting 'CFTypeRef' (aka 'const void *') to 'int *' with a __bridge cast}}
+ id obj3 = (__bridge IdType)CFGetSomething();
+ id obj4 = (__bridge StringType)CFGetString();
+}
+
+template void from_cf<id, NSString*, int*>(); // expected-note{{in instantiation of function template specialization}}
+
+template<typename IdType, typename StringType>
+void to_cf(id obj) {
+ CFTypeRef cf1 = (__bridge_retained IdType)CreateSomething();
+ CFStringRef cf2 = (__bridge_retained StringType)CreateNSString();
+ CFTypeRef cf3 = (__bridge IdType)CreateSomething();
+ CFStringRef cf4 = (__bridge StringType)CreateNSString();
+}
+
+template void to_cf<CFTypeRef, CFStringRef>(id);
diff --git a/test/SemaObjCXX/arc-libcxx.mm b/test/SemaObjCXX/arc-libcxx.mm
new file mode 100644
index 0000000..7992f60
--- /dev/null
+++ b/test/SemaObjCXX/arc-libcxx.mm
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-arc-cxxlib=libc++ -fobjc-nonfragile-abi -fobjc-runtime-has-weak -verify %s
+
+@interface A @end
+
+void f(__strong id &sir, __weak id &wir, __autoreleasing id &air,
+ __unsafe_unretained id &uir) {
+ __strong id *sip = std::addressof(sir);
+ __weak id *wip = std::addressof(wir);
+ __autoreleasing id *aip = std::addressof(air);
+ __unsafe_unretained id *uip = std::addressof(uir);
+}
diff --git a/test/SemaObjCXX/arc-libstdcxx.mm b/test/SemaObjCXX/arc-libstdcxx.mm
new file mode 100644
index 0000000..edb7a9e
--- /dev/null
+++ b/test/SemaObjCXX/arc-libstdcxx.mm
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-arc-cxxlib=libstdc++ -fobjc-nonfragile-abi -fobjc-runtime-has-weak -verify %s
+
+@interface A @end
+
+int check0[std::__is_scalar<__strong id>::__value? -1 : 1];
+int check1[std::__is_scalar<__weak id>::__value? -1 : 1];
+int check2[std::__is_scalar<__autoreleasing id>::__value? -1 : 1];
+int check3[std::__is_scalar<__strong A*>::__value? -1 : 1];
+int check4[std::__is_scalar<__weak A*>::__value? -1 : 1];
+int check5[std::__is_scalar<__autoreleasing A*>::__value? -1 : 1];
diff --git a/test/SemaObjCXX/arc-memfunc.mm b/test/SemaObjCXX/arc-memfunc.mm
new file mode 100644
index 0000000..75b94c6
--- /dev/null
+++ b/test/SemaObjCXX/arc-memfunc.mm
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -verify -fblocks %s
+
+struct X0 {
+ static id makeObject1() __attribute__((ns_returns_retained));
+ id makeObject2() __attribute__((ns_returns_retained));
+};
+
+void test_X0(X0 x0, X0 *x0p) {
+ X0::makeObject1();
+ x0.makeObject2();
+ x0p->makeObject2();
+ id (X0::*pmf)() __attribute__((ns_returns_retained)) = &X0::makeObject2;
+ (x0.*pmf)();
+ (x0p->*pmf)();
+}
diff --git a/test/SemaObjCXX/arc-non-pod.mm b/test/SemaObjCXX/arc-non-pod.mm
new file mode 100644
index 0000000..6a47b3d
--- /dev/null
+++ b/test/SemaObjCXX/arc-non-pod.mm
@@ -0,0 +1,116 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -Warc-abi -verify -fblocks -triple x86_64-apple-darwin10.0.0 %s
+
+// Classes that have an Objective-C object pointer.
+struct HasObjectMember0 { // expected-warning{{'HasObjectMember0' cannot be shared between ARC and non-ARC code; add a copy constructor, a copy assignment operator, and a destructor to make it ABI-compatible}}
+ id x;
+};
+
+struct HasObjectMember1 { // expected-warning{{'HasObjectMember1' cannot be shared between ARC and non-ARC code; add a copy constructor, a copy assignment operator, and a destructor to make it ABI-compatible}}
+ id x[3];
+};
+
+struct HasObjectMember2 { // expected-warning{{'HasObjectMember2' cannot be shared between ARC and non-ARC code; add a copy constructor, a copy assignment operator, and a destructor to make it ABI-compatible}}
+ id x[3][2];
+};
+
+// Don't complain if the type has non-external linkage
+namespace {
+ struct HasObjectMember3 {
+ id x[3][2];
+ };
+}
+
+// Don't complain if the Objective-C pointer type was explicitly given
+// no ownership.
+struct HasObjectMember3 {
+ __unsafe_unretained id x[3][2];
+};
+
+struct HasBlockPointerMember0 { // expected-warning{{'HasBlockPointerMember0' cannot be shared between ARC and non-ARC code; add a copy constructor, a copy assignment operator, and a destructor to make it ABI-compatible}}
+ int (^bp)(int);
+};
+
+struct HasBlockPointerMember1 { // expected-warning{{'HasBlockPointerMember1' cannot be shared between ARC and non-ARC code; add a copy constructor, a copy assignment operator, and a destructor to make it ABI-compatible}}
+ int (^bp[2][3])(int);
+};
+
+struct NonPOD {
+ NonPOD(const NonPOD&);
+};
+
+struct HasObjectMemberAndNonPOD0 { // expected-warning{{'HasObjectMemberAndNonPOD0' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible}} \
+ // expected-warning{{'HasObjectMemberAndNonPOD0' cannot be shared between ARC and non-ARC code; add a non-trivial destructor to make it ABI-compatible}}
+ id x;
+ NonPOD np;
+};
+
+struct HasObjectMemberAndNonPOD1 { // expected-warning{{'HasObjectMemberAndNonPOD1' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible}} \
+ // expected-warning{{'HasObjectMemberAndNonPOD1' cannot be shared between ARC and non-ARC code; add a non-trivial destructor to make it ABI-compatible}}
+ NonPOD np;
+ id x[3];
+};
+
+struct HasObjectMemberAndNonPOD2 { // expected-warning{{'HasObjectMemberAndNonPOD2' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible}} \
+ // expected-warning{{'HasObjectMemberAndNonPOD2' cannot be shared between ARC and non-ARC code; add a non-trivial destructor to make it ABI-compatible}}
+ NonPOD np;
+ id x[3][2];
+};
+
+struct HasObjectMemberAndNonPOD3 {
+ HasObjectMemberAndNonPOD3 &operator=(const HasObjectMemberAndNonPOD3&);
+ ~HasObjectMemberAndNonPOD3();
+ NonPOD np;
+ id x[3][2];
+};
+
+struct HasBlockPointerMemberAndNonPOD0 { // expected-warning{{'HasBlockPointerMemberAndNonPOD0' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible}} \
+// expected-warning{{'HasBlockPointerMemberAndNonPOD0' cannot be shared between ARC and non-ARC code; add a non-trivial destructor to make it ABI-compatible}}
+ NonPOD np;
+ int (^bp)(int);
+};
+
+struct HasBlockPointerMemberAndNonPOD1 { // expected-warning{{'HasBlockPointerMemberAndNonPOD1' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible}} \
+// expected-warning{{'HasBlockPointerMemberAndNonPOD1' cannot be shared between ARC and non-ARC code; add a non-trivial destructor to make it ABI-compatible}}
+ NonPOD np;
+ int (^bp[2][3])(int);
+};
+
+int check_non_pod_objc_pointer0[__is_pod(id)? 1 : -1];
+int check_non_pod_objc_pointer1[__is_pod(__strong id)? -1 : 1];
+int check_non_pod_objc_pointer2[__is_pod(__unsafe_unretained id)? 1 : -1];
+int check_non_pod_objc_pointer3[__is_pod(id[2][3])? 1 : -1];
+int check_non_pod_objc_pointer4[__is_pod(__unsafe_unretained id[2][3])? 1 : -1];
+int check_non_pod_block0[__is_pod(int (^)(int))? 1 : -1];
+int check_non_pod_block1[__is_pod(int (^ __unsafe_unretained)(int))? 1 : -1];
+int check_non_pod_block2[__is_pod(int (^ __strong)(int))? -1 : 1];
+
+struct FlexibleArrayMember0 {
+ int length;
+ id array[]; // expected-error{{flexible array member 'array' of non-POD element type 'id __strong[]'}}
+};
+
+struct FlexibleArrayMember1 {
+ int length;
+ __unsafe_unretained id array[];
+};
+
+// It's okay to pass a retainable type through an ellipsis.
+void variadic(...);
+void test_variadic() {
+ variadic(1, 17, @"Foo");
+}
+
+// It's okay to create a VLA of retainable types.
+void vla(int n) {
+ id vla[n];
+}
+
+@interface Crufty {
+ union {
+ struct {
+ id object; // expected-note{{has __strong ownership}}
+ } an_object; // expected-error{{union member 'an_object' has a non-trivial copy constructor}}
+ void *ptr;
+ } storage;
+}
+@end
diff --git a/test/SemaObjCXX/arc-object-init-destroy.mm b/test/SemaObjCXX/arc-object-init-destroy.mm
new file mode 100644
index 0000000..196f493
--- /dev/null
+++ b/test/SemaObjCXX/arc-object-init-destroy.mm
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -Warc-abi -fblocks -triple x86_64-apple-darwin10.0.0 %s
+
+typedef __strong id strong_id;
+typedef __weak id weak_id;
+void test_pseudo_destructors(__strong id *sptr, __weak id *wptr) {
+ sptr->~id(); // okay
+ wptr->~id(); // okay
+ sptr->~strong_id(); // okay
+ wptr->~weak_id();
+ sptr->~weak_id(); // expected-error{{pseudo-destructor destroys object of type '__strong id' with inconsistently-qualified type 'weak_id' (aka '__weak id')}}
+ wptr->strong_id::~strong_id(); // expected-error{{pseudo-destructor destroys object of type '__weak id' with inconsistently-qualified type 'strong_id' (aka '__strong id')}}
+
+ sptr->id::~id(); // okay
+ wptr->id::~id(); // okay
+}
+
+void test_delete(__strong id *sptr, __weak id *wptr) {
+ delete sptr;
+ delete wptr;
+ delete [] sptr; // expected-warning{{destroying an array of '__strong id'; this array must not have been allocated from non-ARC code}}
+ delete [] wptr; // expected-warning{{destroying an array of '__weak id'; this array must not have been allocated from non-ARC code}}
+}
+
+void test_new(int n) {
+ (void)new strong_id;
+ (void)new weak_id;
+ (void)new strong_id [n]; // expected-warning{{allocating an array of 'strong_id' (aka '__strong id'); this array must not be deleted in non-ARC code}}
+ (void)new weak_id [n]; // expected-warning{{allocating an array of 'weak_id' (aka '__weak id'); this array must not be deleted in non-ARC code}}
+
+ (void)new __strong id;
+ (void)new __weak id;
+ (void)new __strong id [n]; // expected-warning{{allocating an array of '__strong id'; this array must not be deleted in non-ARC code}}
+
+ // Infer '__strong'.
+ __strong id *idptr = new id;
+ __strong id *idptr2 = new id [n]; // expected-warning{{allocating an array of '__strong id'; this array must not be deleted in non-ARC code}}
+
+ // ... but not for arrays.
+ typedef id id_array[2][3];
+ (void)new id_array; // expected-error{{'new' cannot allocate an array of 'id' with no explicit ownership}}
+
+ typedef __strong id strong_id_array[2][3];
+ typedef __strong id strong_id_3[3];
+ strong_id_3 *idptr3 = new strong_id_array; // expected-warning{{allocating an array of '__strong id'; this array must not be deleted in non-ARC code}}
+}
+
+void test_jump_scope() {
+ goto done; // expected-error{{goto into protected scope}}
+ __strong id x; // expected-note{{jump bypasses initialization of retaining variable}}
+ done:
+ return;
+}
diff --git a/test/SemaObjCXX/arc-overloading.mm b/test/SemaObjCXX/arc-overloading.mm
new file mode 100644
index 0000000..06b332c
--- /dev/null
+++ b/test/SemaObjCXX/arc-overloading.mm
@@ -0,0 +1,175 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -fblocks %s
+
+// Simple ownership conversions + diagnostics.
+int &f0(id __strong const *); // expected-note{{candidate function not viable: 1st argument ('__weak id *') has __weak ownership, but parameter has __strong ownership}}
+
+void test_f0() {
+ id __strong *sip;
+ id __strong const *csip;
+ id __weak *wip;
+ id __autoreleasing *aip;
+ id __unsafe_unretained *uip;
+
+ int &ir1 = f0(sip);
+ int &ir2 = f0(csip);
+ int &ir3 = f0(aip);
+ int &ir4 = f0(uip);
+ f0(wip); // expected-error{{no matching function for call to 'f0'}}
+}
+
+// Simple overloading
+int &f1(id __strong const *);
+float &f1(id __weak const *);
+
+void test_f1() {
+ id __strong *sip;
+ id __strong const *csip;
+ id __weak *wip;
+ id __autoreleasing *aip;
+ id __unsafe_unretained *uip;
+
+ int &ir1 = f1(sip);
+ int &ir2 = f1(csip);
+ float &fr1 = f1(wip);
+ int &ir3 = f1(aip);
+ int &ir4 = f1(uip);
+}
+
+// Simple overloading
+int &f2(id __strong const *); // expected-note{{candidate function}}
+float &f2(id __autoreleasing const *); // expected-note{{candidate function}}
+
+void test_f2() {
+ id __strong *sip;
+ id __strong const *csip;
+ id __weak *wip;
+ id __autoreleasing *aip;
+ id __unsafe_unretained *uip;
+
+ // Prefer non-ownership conversions to ownership conversions.
+ int &ir1 = f2(sip);
+ int &ir2 = f2(csip);
+ float &fr1 = f2(aip);
+
+ f2(uip); // expected-error{{call to 'f2' is ambiguous}}
+}
+
+// Writeback conversion
+int &f3(id __autoreleasing *); // expected-note{{candidate function not viable: 1st argument ('__unsafe_unretained id *') has __unsafe_unretained ownership, but parameter has __autoreleasing ownership}}
+
+void test_f3() {
+ id __strong sip;
+ id __weak wip;
+ id __autoreleasing aip;
+ id __unsafe_unretained uip;
+
+ int &ir1 = f3(&sip);
+ int &ir2 = f3(&wip);
+ int &ir3 = f3(&aip);
+ f3(&uip); // expected-error{{no matching function for call to 'f3'}}
+}
+
+// Writeback conversion vs. no conversion
+int &f4(id __autoreleasing *);
+float &f4(id __strong *);
+
+void test_f4() {
+ id __strong sip;
+ id __weak wip;
+ id __autoreleasing aip;
+ extern __weak id weak_global_ptr;
+
+ float &fr1 = f4(&sip);
+ int &ir1 = f4(&wip);
+ int &ir2 = f4(&aip);
+ int &ir3 = f4(&weak_global_ptr); // expected-error{{passing address of non-local object to __autoreleasing parameter for write-back}}
+}
+
+// Writeback conversion vs. other conversion.
+int &f5(id __autoreleasing *);
+float &f5(id const __unsafe_unretained *);
+
+void test_f5() {
+ id __strong sip;
+ id __weak wip;
+ id __autoreleasing aip;
+
+ int &ir1 = f5(&wip);
+ float &fr1 = f5(&sip);
+ int &ir2 = f5(&aip);
+}
+
+@interface A
+@end
+
+int &f6(id __autoreleasing *);
+float &f6(id const __unsafe_unretained *);
+
+void test_f6() {
+ A* __strong sip;
+ A* __weak wip;
+ A* __autoreleasing aip;
+
+ int &ir1 = f6(&wip);
+ float &fr1 = f6(&sip);
+ int &ir2 = f6(&aip);
+}
+
+// Reference binding
+void f7(__strong id&); // expected-note{{candidate function not viable: 1st argument ('__weak id') has __weak ownership, but parameter has __strong ownership}} \
+ // expected-note{{candidate function not viable: 1st argument ('__autoreleasing id') has __autoreleasing ownership, but parameter has __strong ownership}} \
+ // expected-note{{candidate function not viable: 1st argument ('__unsafe_unretained id') has __unsafe_unretained ownership, but parameter has __strong ownership}}
+
+void test_f7() {
+ __strong id strong_id;
+ __weak id weak_id;
+ __autoreleasing id autoreleasing_id;
+ __unsafe_unretained id unsafe_id;
+ f7(strong_id);
+ f7(weak_id); // expected-error{{no matching function for call to 'f7'}}
+ f7(autoreleasing_id); // expected-error{{no matching function for call to 'f7'}}
+ f7(unsafe_id); // expected-error{{no matching function for call to 'f7'}}
+}
+
+void f8(const __strong id&);
+
+void test_f8() {
+ __strong id strong_id;
+ __weak id weak_id;
+ __autoreleasing id autoreleasing_id;
+ __unsafe_unretained id unsafe_id;
+
+ f8(strong_id);
+ f8(weak_id);
+ f8(autoreleasing_id);
+ f8(unsafe_id);
+}
+
+int &f9(__strong id&);
+float &f9(const __autoreleasing id&);
+
+void test_f9() {
+ __strong id strong_id;
+ __weak id weak_id;
+ __autoreleasing id autoreleasing_id;
+ __unsafe_unretained id unsafe_id;
+
+ int &ir1 = f9(strong_id);
+ float &fr1 = f9(autoreleasing_id);
+ float &fr2 = f9(unsafe_id);
+ float &fr2a = f9(weak_id);
+
+ __strong A *strong_a;
+ __weak A *weak_a;
+ __autoreleasing A *autoreleasing_a;
+ __unsafe_unretained A *unsafe_unretained_a;
+ float &fr3 = f9(strong_a);
+ float &fr4 = f9(autoreleasing_a);
+ float &fr5 = f9(unsafe_unretained_a);
+ float &fr6 = f9(weak_a);
+
+ const __autoreleasing id& ar1 = strong_a;
+ const __autoreleasing id& ar2 = autoreleasing_a;
+ const __autoreleasing id& ar3 = unsafe_unretained_a;
+ const __autoreleasing id& ar4 = weak_a;
+}
diff --git a/test/SemaObjCXX/arc-system-header.mm b/test/SemaObjCXX/arc-system-header.mm
new file mode 100644
index 0000000..cb2b858
--- /dev/null
+++ b/test/SemaObjCXX/arc-system-header.mm
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fobjc-arc -fobjc-nonfragile-abi -isystem %S/Inputs %s -verify
+
+#include <arc-system-header.h>
+
+void f(A* a) {
+ a->data.void_ptr = 0;
+ a->data.a_b.b = 0; // expected-error{{'a_b' is unavailable: this system field has retaining ownership}}
+}
+// Silly location below
+// expected-note{{declaration has been explicitly marked unavailable here}}
diff --git a/test/SemaObjCXX/arc-templates.mm b/test/SemaObjCXX/arc-templates.mm
new file mode 100644
index 0000000..fa4e0a7
--- /dev/null
+++ b/test/SemaObjCXX/arc-templates.mm
@@ -0,0 +1,254 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -fblocks %s
+
+@interface A
+@end
+
+template<typename T, typename U>
+struct is_same {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+ static const bool value = true;
+};
+
+// Instantiation for reference/pointer types that will get lifetime
+// adjustments.
+template<typename T>
+struct X0 {
+ typedef T* pointer; // okay: ends up being strong.
+ typedef T& reference; // okay: ends up being strong
+};
+
+void test_X0() {
+ X0<id> x0id;
+ X0<A*> x0a;
+ X0<__strong A*> x0sa;
+
+ id __strong *ptr;
+ id __strong val;
+ X0<__strong id>::pointer &ptr_ref = ptr;
+ X0<__strong id>::reference ref = val;
+}
+
+int check_infer_strong[is_same<id, __strong id>::value? 1 : -1];
+
+// Check template argument deduction (e.g., for specialization) using
+// lifetime qualifiers.
+template<typename T>
+struct is_pointer_strong {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_pointer_strong<__strong T*> {
+ static const bool value = true;
+};
+
+int check_ptr_strong1[is_pointer_strong<__strong id*>::value? 1 : -1];
+int check_ptr_strong2[is_pointer_strong<__weak id*>::value? -1 : 1];
+int check_ptr_strong3[is_pointer_strong<__autoreleasing id*>::value? -1 : 1];
+int check_ptr_strong4[is_pointer_strong<__unsafe_unretained id*>::value? -1 : 1];
+int check_ptr_strong5[is_pointer_strong<id>::value? -1 : 1];
+
+// Check substitution into lifetime-qualified dependent types.
+template<typename T>
+struct make_strong_pointer {
+ typedef __strong T *type;
+};
+
+template<typename T>
+struct make_strong_pointer<__weak T> {
+ typedef __strong T *type;
+};
+
+template<typename T>
+struct make_strong_pointer<__autoreleasing T> {
+ typedef __strong T *type;
+};
+
+template<typename T>
+struct make_strong_pointer<__unsafe_unretained T> {
+ typedef __strong T *type;
+};
+
+// Adding qualifiers
+int check_make_strong1[is_same<make_strong_pointer<id>::type, __strong id *>::value ? 1 : -1];
+int check_make_strong2[is_same<make_strong_pointer<A*>::type, A* __strong *>::value ? 1 : -1];
+
+// Adding redundant qualifiers
+int check_make_strong3[is_same<make_strong_pointer<__strong id>::type, __strong id *>::value ? 1 : -1];
+int check_make_strong4[is_same<make_strong_pointer<__strong A*>::type, A* __strong *>::value ? 1 : -1];
+
+// Adding nonsensical qualifiers.
+int check_make_strong5[is_same<make_strong_pointer<int>::type, int *>::value ? 1 : -1];
+int check_make_strong6[is_same<make_strong_pointer<__weak id>::type, __strong id *>::value ? 1 : -1];
+
+template<typename T>
+struct make_weak {
+ typedef __weak T type;
+};
+
+int check_make_weak0[is_same<make_weak<id>::type, __weak id>::value? 1 : -1];
+int check_make_weak1[is_same<make_weak<__strong id>::type, __weak id>::value? 1 : -1];
+int check_make_weak2[is_same<make_weak<__autoreleasing id>::type, __weak id>::value? 1 : -1];
+
+template<typename T>
+struct make_weak_fail {
+ typedef T T_type;
+ typedef __weak T_type type; // expected-error{{the type 'T_type' (aka '__weak id') already has retainment attributes set on it}} \
+ // expected-error{{the type 'T_type' (aka '__strong id') already has retainment attributes set on it}}
+};
+
+int check_make_weak_fail0[is_same<make_weak_fail<__weak id>::type, __weak id>::value? 1 : -1]; // expected-note{{in instantiation of template class 'make_weak_fail<__weak id>' requested here}}
+
+int check_make_weak_fail1[is_same<make_weak_fail<id>::type, __weak id>::value? -1 : 1]; // expected-note{{in instantiation of template class 'make_weak_fail<id>' requested here}}
+
+// Check template argument deduction from function templates.
+template<typename T> struct identity { };
+
+template<typename T> identity<T> accept_strong_ptr(__strong T*);
+template<typename T> identity<T> accept_strong_ref(__strong T&);
+
+template<typename T> identity<T> accept_any_ptr(T*);
+template<typename T> identity<T> accept_any_ref(T&);
+
+void test_func_deduction_id() {
+ __strong id *sip;
+ __weak id *wip;
+ __autoreleasing id *aip;
+ __unsafe_unretained id *uip;
+
+ identity<id> res1 = accept_strong_ptr(sip);
+ identity<__strong id> res2 = accept_any_ptr(sip);
+
+ __strong id si;
+ __weak id wi;
+ __autoreleasing id ai;
+ __unsafe_unretained id ui;
+ identity<id> res3 = accept_strong_ref(si);
+ identity<__strong id> res4 = accept_any_ref(si);
+ identity<__weak id> res5 = accept_any_ref(wi);
+ identity<__autoreleasing id> res6 = accept_any_ref(ai);
+ identity<__unsafe_unretained id> res7 = accept_any_ref(ui);
+}
+
+void test_func_deduction_A() {
+ __strong A * *sip;
+ __weak A * *wip;
+ __autoreleasing A * *aip;
+ __unsafe_unretained A * *uip;
+
+ identity<A *> res1 = accept_strong_ptr(sip);
+ identity<__strong A *> res2 = accept_any_ptr(sip);
+
+ __strong A * si;
+ __weak A * wi;
+ __autoreleasing A * ai;
+ __unsafe_unretained A * ui;
+ identity<A *> res3 = accept_strong_ref(si);
+ identity<__strong A *> res4 = accept_any_ref(si);
+ identity<__weak A *> res5 = accept_any_ref(wi);
+ identity<__autoreleasing A *> res6 = accept_any_ref(ai);
+ identity<__unsafe_unretained A *> res7 = accept_any_ref(ui);
+}
+
+// Test partial ordering (qualified vs. non-qualified).
+template<typename T>
+struct classify_pointer_pointer {
+ static const unsigned value = 0;
+};
+
+template<typename T>
+struct classify_pointer_pointer<T*> {
+ static const unsigned value = 1;
+};
+
+template<typename T>
+struct classify_pointer_pointer<__strong T*> {
+ static const unsigned value = 2;
+};
+
+template<typename T>
+struct classify_pointer_pointer<__weak T*> {
+ static const unsigned value = 3;
+};
+
+template<typename T>
+struct classify_pointer_pointer<T&> {
+ static const unsigned value = 4;
+};
+
+template<typename T>
+struct classify_pointer_pointer<__strong T&> {
+ static const unsigned value = 5;
+};
+
+template<typename T>
+struct classify_pointer_pointer<__weak T&> {
+ static const unsigned value = 6;
+};
+
+int classify_ptr1[classify_pointer_pointer<int>::value == 0? 1 : -1];
+int classify_ptr2[classify_pointer_pointer<int *>::value == 1? 1 : -1];
+int classify_ptr3[classify_pointer_pointer<id __strong *>::value == 2? 1 : -1];
+int classify_ptr4[classify_pointer_pointer<id __weak *>::value == 3? 1 : -1];
+int classify_ptr5[classify_pointer_pointer<int&>::value == 4? 1 : -1];
+int classify_ptr6[classify_pointer_pointer<id __strong&>::value == 5? 1 : -1];
+int classify_ptr7[classify_pointer_pointer<id __weak&>::value == 6? 1 : -1];
+int classify_ptr8[classify_pointer_pointer<id __autoreleasing&>::value == 4? 1 : -1];
+int classify_ptr9[classify_pointer_pointer<id __unsafe_unretained&>::value == 4? 1 : -1];
+int classify_ptr10[classify_pointer_pointer<id __autoreleasing *>::value == 1? 1 : -1];
+int classify_ptr11[classify_pointer_pointer<id __unsafe_unretained *>::value == 1? 1 : -1];
+int classify_ptr12[classify_pointer_pointer<int *>::value == 1? 1 : -1];
+int classify_ptr13[classify_pointer_pointer<A * __strong *>::value == 2? 1 : -1];
+int classify_ptr14[classify_pointer_pointer<A * __weak *>::value == 3? 1 : -1];
+int classify_ptr15[classify_pointer_pointer<int&>::value == 4? 1 : -1];
+int classify_ptr16[classify_pointer_pointer<A * __strong&>::value == 5? 1 : -1];
+int classify_ptr17[classify_pointer_pointer<A * __weak&>::value == 6? 1 : -1];
+int classify_ptr18[classify_pointer_pointer<A * __autoreleasing&>::value == 4? 1 : -1];
+int classify_ptr19[classify_pointer_pointer<A * __unsafe_unretained&>::value == 4? 1 : -1];
+int classify_ptr20[classify_pointer_pointer<A * __autoreleasing *>::value == 1? 1 : -1];
+int classify_ptr21[classify_pointer_pointer<A * __unsafe_unretained *>::value == 1? 1 : -1];
+
+template<typename T> int& qual_vs_unqual_ptr(__strong T*);
+template<typename T> double& qual_vs_unqual_ptr(__weak T*);
+template<typename T> float& qual_vs_unqual_ptr(T*);
+template<typename T> int& qual_vs_unqual_ref(__strong T&);
+template<typename T> double& qual_vs_unqual_ref(__weak T&);
+template<typename T> float& qual_vs_unqual_ref(T&);
+
+void test_qual_vs_unqual_id() {
+ __strong id *sip;
+ __weak id *wip;
+ __autoreleasing id *aip;
+ __unsafe_unretained id *uip;
+
+ int &ir1 = qual_vs_unqual_ptr(sip);
+ double &dr1 = qual_vs_unqual_ptr(wip);
+ float &fr1 = qual_vs_unqual_ptr(aip);
+ float &fr2 = qual_vs_unqual_ptr(uip);
+
+ int &ir2 = qual_vs_unqual_ref(*sip);
+ double &dr2 = qual_vs_unqual_ref(*wip);
+ float &fr3 = qual_vs_unqual_ref(*aip);
+ float &fr4 = qual_vs_unqual_ref(*uip);
+}
+
+void test_qual_vs_unqual_a() {
+ __strong A * *sap;
+ __weak A * *wap;
+ __autoreleasing A * *aap;
+ __unsafe_unretained A * *uap;
+
+ int &ir1 = qual_vs_unqual_ptr(sap);
+ double &dr1 = qual_vs_unqual_ptr(wap);
+ float &fr1 = qual_vs_unqual_ptr(aap);
+ float &fr2 = qual_vs_unqual_ptr(uap);
+
+ int &ir2 = qual_vs_unqual_ref(*sap);
+ double &dr2 = qual_vs_unqual_ref(*wap);
+ float &fr3 = qual_vs_unqual_ref(*aap);
+ float &fr4 = qual_vs_unqual_ref(*uap);
+}
diff --git a/test/SemaObjCXX/arc-type-conversion.mm b/test/SemaObjCXX/arc-type-conversion.mm
new file mode 100644
index 0000000..f52f54a
--- /dev/null
+++ b/test/SemaObjCXX/arc-type-conversion.mm
@@ -0,0 +1,221 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -fblocks %s
+// rdar://8843600
+
+void * cvt(id arg) // expected-note{{candidate function not viable: cannot convert argument of incomplete type 'void *' to '__strong id'}}
+{
+ void* voidp_val;
+ (void)(int*)arg; // expected-error {{cast of an Objective-C pointer to 'int *' is disallowed with ARC}}
+ (void)(id)arg;
+ (void)(__autoreleasing id*)arg; // expected-error{{C-style cast from 'id' to '__autoreleasing id *' casts away qualifiers}}
+ (void)(id*)arg; // expected-error{{C-style cast from 'id' to '__strong id *' casts away qualifiers}}
+
+ (void)(__autoreleasing id**)voidp_val;
+ (void)(void*)voidp_val;
+ (void)(void**)arg; // expected-error {{cast of an Objective-C pointer to 'void **' is disallowed}}
+ cvt((void*)arg); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}} \
+ // expected-error {{no matching function for call to 'cvt'}} \
+ // expected-note{{use __bridge to convert directly (no change in ownership)}} \
+ // expected-note{{use __bridge_retained to make an ARC object available as a +1 'void *'}}
+ cvt(0);
+ (void)(__strong id**)(0);
+
+ // FIXME: Diagnostic could be better here.
+ return arg; // expected-error{{cannot initialize return object of type 'void *' with an lvalue of type '__strong id'}}
+}
+
+// rdar://8898937
+namespace rdar8898937 {
+
+typedef void (^dispatch_block_t)(void);
+
+void dispatch_once(dispatch_block_t block);
+static void _dispatch_once(dispatch_block_t block)
+{
+ dispatch_once(block);
+}
+
+}
+
+void static_casts(id arg) {
+ void* voidp_val;
+ (void)static_cast<int*>(arg); // expected-error {{cannot cast from type 'id' to pointer type 'int *'}}
+ (void)static_cast<id>(arg);
+ (void)static_cast<__autoreleasing id*>(arg); // expected-error{{cannot cast from type 'id' to pointer type '__autoreleasing id *'}}
+ (void)static_cast<id*>(arg); // expected-error {{cannot cast from type 'id' to pointer type '__strong id *'}}
+
+ (void)static_cast<__autoreleasing id**>(voidp_val);
+ (void)static_cast<void*>(voidp_val);
+ (void)static_cast<void**>(arg); // expected-error {{cannot cast from type 'id' to pointer type 'void **'}}
+ (void)static_cast<__strong id**>(0);
+
+ __strong id *idp;
+ (void)static_cast<__autoreleasing id*>(idp); // expected-error{{static_cast from '__strong id *' to '__autoreleasing id *' is not allowed}}
+ (void)static_cast<__weak id*>(idp); // expected-error{{static_cast from '__strong id *' to '__weak id *' is not allowed}}
+}
+
+void test_const_cast(__strong id *sip, __weak id *wip,
+ const __strong id *csip, __weak const id *cwip) {
+ // Cannot use const_cast to cast between ownership qualifications or
+ // add/remove ownership qualifications.
+ (void)const_cast<__strong id *>(wip); // expected-error{{is not allowed}}
+ (void)const_cast<__weak id *>(sip); // expected-error{{is not allowed}}
+
+ // It's acceptable to cast away constness.
+ (void)const_cast<__strong id *>(csip);
+ (void)const_cast<__weak id *>(cwip);
+}
+
+void test_reinterpret_cast(__strong id *sip, __weak id *wip,
+ const __strong id *csip, __weak const id *cwip) {
+ // Okay to reinterpret_cast to add/remove/change ownership
+ // qualifications.
+ (void)reinterpret_cast<__strong id *>(wip);
+ (void)reinterpret_cast<__weak id *>(sip);
+
+ // Not allowed to cast away constness
+ (void)reinterpret_cast<__strong id *>(csip); // expected-error{{reinterpret_cast from '__strong id const *' to '__strong id *' casts away qualifiers}}
+ (void)reinterpret_cast<__weak id *>(cwip); // expected-error{{reinterpret_cast from '__weak id const *' to '__weak id *' casts away qualifiers}}
+ (void)reinterpret_cast<__weak id *>(csip); // expected-error{{reinterpret_cast from '__strong id const *' to '__weak id *' casts away qualifiers}}
+ (void)reinterpret_cast<__strong id *>(cwip); // expected-error{{reinterpret_cast from '__weak id const *' to '__strong id *' casts away qualifiers}}
+}
+
+void test_cstyle_cast(__strong id *sip, __weak id *wip,
+ const __strong id *csip, __weak const id *cwip) {
+ // C-style casts aren't allowed to change Objective-C ownership
+ // qualifiers (beyond what the normal implicit conversion allows).
+
+ (void)(__strong id *)wip; // expected-error{{C-style cast from '__weak id *' to '__strong id *' casts away qualifiers}}
+ (void)(__strong id *)cwip; // expected-error{{C-style cast from '__weak id const *' to '__strong id *' casts away qualifiers}}
+ (void)(__weak id *)sip; // expected-error{{C-style cast from '__strong id *' to '__weak id *' casts away qualifiers}}
+ (void)(__weak id *)csip; // expected-error{{C-style cast from '__strong id const *' to '__weak id *' casts away qualifiers}}
+
+ (void)(__strong const id *)wip; // expected-error{{C-style cast from '__weak id *' to '__strong id const *' casts away qualifiers}}
+ (void)(__strong const id *)cwip; // expected-error{{C-style cast from '__weak id const *' to '__strong id const *' casts away qualifiers}}
+ (void)(__weak const id *)sip; // expected-error{{C-style cast from '__strong id *' to '__weak id const *' casts away qualifiers}}
+ (void)(__weak const id *)csip; // expected-error{{C-style cast from '__strong id const *' to '__weak id const *' casts away qualifiers}}
+ (void)(__autoreleasing const id *)wip; // expected-error{{C-style cast from '__weak id *' to '__autoreleasing id const *' casts away qualifiers}}
+ (void)(__autoreleasing const id *)cwip; // expected-error{{C-style cast from '__weak id const *' to '__autoreleasing id const *' casts away qualifiers}}
+ (void)(__autoreleasing const id *)sip;
+ (void)(__autoreleasing const id *)csip;
+}
+
+void test_functional_cast(__strong id *sip, __weak id *wip,
+ __autoreleasing id *aip) {
+ // Functional casts aren't allowed to change Objective-C ownership
+ // qualifiers (beyond what the normal implicit conversion allows).
+
+ typedef __strong id *strong_id_pointer;
+ typedef __weak id *weak_id_pointer;
+ typedef __autoreleasing id *autoreleasing_id_pointer;
+
+ typedef const __strong id *const_strong_id_pointer;
+ typedef const __weak id *const_weak_id_pointer;
+ typedef const __autoreleasing id *const_autoreleasing_id_pointer;
+
+ (void)strong_id_pointer(wip); // expected-error{{functional-style cast from '__weak id *' to 'strong_id_pointer' (aka '__strong id *') casts away qualifiers}}
+ (void)weak_id_pointer(sip); // expected-error{{functional-style cast from '__strong id *' to 'weak_id_pointer' (aka '__weak id *') casts away qualifiers}}
+ (void)autoreleasing_id_pointer(sip); // expected-error{{functional-style cast from '__strong id *' to 'autoreleasing_id_pointer' (aka '__autoreleasing id *') casts away qualifiers}}
+ (void)autoreleasing_id_pointer(wip); // expected-error{{functional-style cast from '__weak id *' to 'autoreleasing_id_pointer' (aka '__autoreleasing id *') casts away qualifiers}}
+ (void)const_strong_id_pointer(wip); // expected-error{{functional-style cast from '__weak id *' to 'const_strong_id_pointer' (aka 'const __strong id *') casts away qualifiers}}
+ (void)const_weak_id_pointer(sip); // expected-error{{functional-style cast from '__strong id *' to 'const_weak_id_pointer' (aka 'const __weak id *') casts away qualifiers}}
+ (void)const_autoreleasing_id_pointer(sip);
+ (void)const_autoreleasing_id_pointer(aip);
+ (void)const_autoreleasing_id_pointer(wip); // expected-error{{functional-style cast from '__weak id *' to 'const_autoreleasing_id_pointer' (aka 'const __autoreleasing id *') casts away qualifiers}}
+}
+
+void test_unsafe_unretained(__strong id *sip, __weak id *wip,
+ __autoreleasing id *aip,
+ __unsafe_unretained id *uip,
+ const __unsafe_unretained id *cuip) {
+ uip = sip; // expected-error{{assigning to '__unsafe_unretained id *' from incompatible type '__strong id *'}}
+ uip = wip; // expected-error{{assigning to '__unsafe_unretained id *' from incompatible type '__weak id *'}}
+ uip = aip; // expected-error{{assigning to '__unsafe_unretained id *' from incompatible type '__autoreleasing id *'}}
+
+ cuip = sip;
+ cuip = wip; // expected-error{{assigning to '__unsafe_unretained id const *' from incompatible type '__weak id *'}}
+ cuip = aip;
+}
+
+void to_void(__strong id *sip, __weak id *wip,
+ __autoreleasing id *aip,
+ __unsafe_unretained id *uip) {
+ void *vp1 = sip;
+ void *vp2 = wip;
+ void *vp3 = aip;
+ void *vp4 = uip;
+ (void)(void*)sip;
+ (void)(void*)wip;
+ (void)(void*)aip;
+ (void)(void*)uip;
+ (void)static_cast<void*>(sip);
+ (void)static_cast<void*>(wip);
+ (void)static_cast<void*>(aip);
+ (void)static_cast<void*>(uip);
+ (void)reinterpret_cast<void*>(sip);
+ (void)reinterpret_cast<void*>(wip);
+ (void)reinterpret_cast<void*>(aip);
+ (void)reinterpret_cast<void*>(uip);
+
+ (void)(void*)&sip;
+ (void)(void*)&wip;
+ (void)(void*)&aip;
+ (void)(void*)&uip;
+ (void)static_cast<void*>(&sip);
+ (void)static_cast<void*>(&wip);
+ (void)static_cast<void*>(&aip);
+ (void)static_cast<void*>(&uip);
+ (void)reinterpret_cast<void*>(&sip);
+ (void)reinterpret_cast<void*>(&wip);
+ (void)reinterpret_cast<void*>(&aip);
+ (void)reinterpret_cast<void*>(&uip);
+}
+
+void from_void(void *vp) {
+ __strong id *sip = (__strong id *)vp;
+ __weak id *wip = (__weak id *)vp;
+ __autoreleasing id *aip = (__autoreleasing id *)vp;
+ __unsafe_unretained id *uip = (__unsafe_unretained id *)vp;
+ __strong id *sip2 = static_cast<__strong id *>(vp);
+ __weak id *wip2 = static_cast<__weak id *>(vp);
+ __autoreleasing id *aip2 = static_cast<__autoreleasing id *>(vp);
+ __unsafe_unretained id *uip2 = static_cast<__unsafe_unretained id *>(vp);
+ __strong id *sip3 = reinterpret_cast<__strong id *>(vp);
+ __weak id *wip3 = reinterpret_cast<__weak id *>(vp);
+ __autoreleasing id *aip3 = reinterpret_cast<__autoreleasing id *>(vp);
+ __unsafe_unretained id *uip3 = reinterpret_cast<__unsafe_unretained id *>(vp);
+
+ __strong id **sipp = (__strong id **)vp;
+ __weak id **wipp = (__weak id **)vp;
+ __autoreleasing id **aipp = (__autoreleasing id **)vp;
+ __unsafe_unretained id **uipp = (__unsafe_unretained id **)vp;
+
+ sip = vp; // expected-error{{assigning to '__strong id *' from incompatible type 'void *'}}
+ wip = vp; // expected-error{{assigning to '__weak id *' from incompatible type 'void *'}}
+ aip = vp; // expected-error{{assigning to '__autoreleasing id *' from incompatible type 'void *'}}
+ uip = vp; // expected-error{{assigning to '__unsafe_unretained id *' from incompatible type 'void *'}}
+}
+
+typedef void (^Block)();
+typedef void (^Block_strong)() __strong;
+typedef void (^Block_autoreleasing)() __autoreleasing;
+
+@class NSString;
+
+void ownership_transfer_in_cast(void *vp, Block *pblk) {
+ __strong NSString **sip2 = static_cast<NSString **>(static_cast<__strong id *>(vp));
+ __strong NSString **&si2pref = static_cast<NSString **&>(sip2);
+ __weak NSString **wip2 = static_cast<NSString **>(static_cast<__weak id *>(vp));
+ __autoreleasing id *aip2 = static_cast<id *>(static_cast<__autoreleasing id *>(vp));
+ __unsafe_unretained id *uip2 = static_cast<id *>(static_cast<__unsafe_unretained id *>(vp));
+ __strong id *sip3 = reinterpret_cast<id *>(reinterpret_cast<__strong id *>(vp));
+ __weak id *wip3 = reinterpret_cast<id *>(reinterpret_cast<__weak id *>(vp));
+ __autoreleasing id *aip3 = reinterpret_cast<id *>(reinterpret_cast<__autoreleasing id *>(vp));
+ __unsafe_unretained id *uip3 = reinterpret_cast<id *>(reinterpret_cast<__unsafe_unretained id *>(vp));
+
+ Block_strong blk_strong1;
+ Block_strong blk_strong2 = static_cast<Block>(blk_strong1);
+ Block_autoreleasing *blk_auto = static_cast<Block*>(pblk);
+}
+
+// Make sure we don't crash.
+void writeback_test(NSString & &) {} // expected-error {{type name declared as a reference to a reference}}
diff --git a/test/SemaObjCXX/arc-type-traits.mm b/test/SemaObjCXX/arc-type-traits.mm
new file mode 100644
index 0000000..f50904b
--- /dev/null
+++ b/test/SemaObjCXX/arc-type-traits.mm
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-nonfragile-abi -fobjc-runtime-has-weak -verify %s
+
+// Check the results of the various type-trait query functions on
+// lifetime-qualified types in ARC.
+
+#define JOIN3(X,Y) X ## Y
+#define JOIN2(X,Y) JOIN3(X,Y)
+#define JOIN(X,Y) JOIN2(X,Y)
+
+#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]
+
+// __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);
+
+// __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);
+
+// __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);
+
+// __has_trivial_assign
+TRAIT_IS_FALSE(__has_trivial_assign, __strong id);
+TRAIT_IS_FALSE(__has_trivial_assign, __weak id);
+TRAIT_IS_FALSE(__has_trivial_assign, __autoreleasing id);
+TRAIT_IS_TRUE(__has_trivial_assign, __unsafe_unretained id);
+
+// __has_trivial_copy
+TRAIT_IS_FALSE(__has_trivial_copy, __strong id);
+TRAIT_IS_FALSE(__has_trivial_copy, __weak id);
+TRAIT_IS_FALSE(__has_trivial_copy, __autoreleasing id);
+TRAIT_IS_TRUE(__has_trivial_copy, __unsafe_unretained id);
+
+// __has_trivial_constructor
+TRAIT_IS_FALSE(__has_trivial_constructor, __strong id);
+TRAIT_IS_FALSE(__has_trivial_constructor, __weak id);
+TRAIT_IS_FALSE(__has_trivial_constructor, __autoreleasing id);
+TRAIT_IS_TRUE(__has_trivial_constructor, __unsafe_unretained id);
+
+// __has_trivial_destructor
+TRAIT_IS_FALSE(__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);
+
+// __is_literal
+TRAIT_IS_FALSE(__is_literal, __strong id);
+TRAIT_IS_FALSE(__is_literal, __weak id);
+TRAIT_IS_FALSE(__is_literal, __autoreleasing id);
+TRAIT_IS_FALSE(__is_literal, __unsafe_unretained id);
+
+// __is_literal_type
+TRAIT_IS_FALSE(__is_literal_type, __strong id);
+TRAIT_IS_FALSE(__is_literal_type, __weak id);
+TRAIT_IS_FALSE(__is_literal_type, __autoreleasing id);
+TRAIT_IS_FALSE(__is_literal_type, __unsafe_unretained id);
+
+// __is_pod
+TRAIT_IS_FALSE(__is_pod, __strong id);
+TRAIT_IS_FALSE(__is_pod, __weak id);
+TRAIT_IS_FALSE(__is_pod, __autoreleasing id);
+TRAIT_IS_TRUE(__is_pod, __unsafe_unretained id);
+
+// __is_trivial
+TRAIT_IS_FALSE(__is_trivial, __strong id);
+TRAIT_IS_FALSE(__is_trivial, __weak id);
+TRAIT_IS_FALSE(__is_trivial, __autoreleasing id);
+TRAIT_IS_TRUE(__is_trivial, __unsafe_unretained id);
+
+// __is_scalar
+TRAIT_IS_FALSE(__is_scalar, __strong id);
+TRAIT_IS_FALSE(__is_scalar, __weak id);
+TRAIT_IS_FALSE(__is_scalar, __autoreleasing id);
+TRAIT_IS_TRUE(__is_scalar, __unsafe_unretained id);
+
+// __is_standard_layout
+TRAIT_IS_TRUE(__is_standard_layout, __strong id);
+TRAIT_IS_TRUE(__is_standard_layout, __weak id);
+TRAIT_IS_TRUE(__is_standard_layout, __autoreleasing id);
+TRAIT_IS_TRUE(__is_standard_layout, __unsafe_unretained id);
+
diff --git a/test/SemaObjCXX/arc-unavailable-for-weakref.mm b/test/SemaObjCXX/arc-unavailable-for-weakref.mm
new file mode 100644
index 0000000..a7b3570
--- /dev/null
+++ b/test/SemaObjCXX/arc-unavailable-for-weakref.mm
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -fobjc-nonfragile-abi -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify %s
+// rdar://9693477
+
+__attribute__((objc_arc_weak_reference_unavailable))
+@interface NSOptOut1072 // expected-note {{class is declared here}}
+@end
+
+@interface sub : NSOptOut1072 @end // expected-note 2 {{class is declared here}}
+
+int main() {
+ __weak sub *w2; // expected-error {{class is incompatible with __weak references}}
+
+ __weak NSOptOut1072 *ns1; // expected-error {{class is incompatible with __weak references}}
+
+ id obj;
+
+ ns1 = (__weak sub *)obj; // expected-error {{assignment of a weak-unavailable object to a __weak object}} \
+ // expected-error {{class is incompatible with __weak references}}
+}
+
+// rdar://9732636
+__attribute__((objc_arc_weak_reference_unavailable))
+@interface NOWEAK
++ (id) new;
+@end
+
+NOWEAK * Test1() {
+ NOWEAK * strong1 = [NOWEAK new];
+ __weak id weak1;
+ weak1 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}}
+
+ __weak id weak2 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}}
+ return (__weak id)strong1; // expected-error {{cast of weak-unavailable object of type 'NOWEAK *' to a __weak object of type '__weak id'}}
+}
+
+@protocol P @end
+@protocol P1 @end
+
+NOWEAK<P, P1> * Test2() {
+ NOWEAK<P, P1> * strong1 = 0;
+ __weak id<P> weak1;
+ weak1 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}}
+
+ __weak id<P> weak2 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}}
+ return (__weak id<P, P1>)strong1; // expected-error {{cast of weak-unavailable object of type 'NOWEAK<P,P1> *' to a __weak object of type '__weak id<P,P1>'}}
+}
+
diff --git a/test/SemaObjCXX/exceptions-fragile.mm b/test/SemaObjCXX/exceptions-fragile.mm
index d1e7077..71e259a 100644
--- a/test/SemaObjCXX/exceptions-fragile.mm
+++ b/test/SemaObjCXX/exceptions-fragile.mm
@@ -6,7 +6,7 @@ void opaque();
namespace test0 {
void test() {
try {
- } catch (NSException *e) { // expected-error {{can't catch Objective C exceptions in C++ in the non-unified exception model}}
+ } catch (NSException *e) { // expected-warning {{can not catch an exception thrown with @throw in C++ in the non-unified exception model}}
}
}
}
diff --git a/test/SemaObjCXX/gc-attributes.mm b/test/SemaObjCXX/gc-attributes.mm
index 70a93b2..4549683 100644
--- a/test/SemaObjCXX/gc-attributes.mm
+++ b/test/SemaObjCXX/gc-attributes.mm
@@ -3,7 +3,7 @@
@interface A
@end
-void f0(__strong A**); // expected-note{{candidate function not viable: 1st argument ('A *__weak *') has __weak lifetime, but parameter has __strong lifetime}}
+void f0(__strong A**); // expected-note{{candidate function not viable: 1st argument ('A *__weak *') has __weak ownership, but parameter has __strong ownership}}
void test_f0() {
A *a;
@@ -12,7 +12,7 @@ void test_f0() {
f0(&a2); // expected-error{{no matching function}}
}
-void f1(__weak A**); // expected-note{{candidate function not viable: 1st argument ('A *__strong *') has __strong lifetime, but parameter has __weak lifetime}}
+void f1(__weak A**); // expected-note{{candidate function not viable: 1st argument ('A *__strong *') has __strong ownership, but parameter has __weak ownership}}
void test_f1() {
A *a;
diff --git a/test/SemaObjCXX/null_objc_pointer.mm b/test/SemaObjCXX/null_objc_pointer.mm
new file mode 100644
index 0000000..0da9e50
--- /dev/null
+++ b/test/SemaObjCXX/null_objc_pointer.mm
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wnull-arithmetic %s
+#define NULL __null
+
+@interface X
+@end
+
+void f() {
+ bool b;
+ X *d;
+ b = d < NULL || NULL < d || d > NULL || NULL > d;
+ b = d <= NULL || NULL <= d || d >= NULL || NULL >= d;
+ b = d == NULL || NULL == d || d != NULL || NULL != d;
+}
diff --git a/test/SemaObjCXX/nullptr.mm b/test/SemaObjCXX/nullptr.mm
index 4cd5669..4a9d1a0 100644
--- a/test/SemaObjCXX/nullptr.mm
+++ b/test/SemaObjCXX/nullptr.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++0x -fblocks -fsyntax-only -verify %s
@interface A
@end
@@ -11,3 +11,6 @@ void comparisons(A *a) {
void assignment(A *a) {
a = nullptr;
}
+
+int PR10145a = (void(^)())0 == nullptr;
+int PR10145b = nullptr == (void(^)())0;
diff --git a/test/SemaObjCXX/property-type-mismatch.mm b/test/SemaObjCXX/property-type-mismatch.mm
new file mode 100644
index 0000000..059793c
--- /dev/null
+++ b/test/SemaObjCXX/property-type-mismatch.mm
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar://9740328
+
+@protocol P1;
+
+@interface NSObject
+@end
+
+@interface A : NSObject
+@property (assign) NSObject<P1> *prop;
+@end
+
+@protocol P2 <P1>
+@end
+
+@interface B : A
+@property (assign) NSObject<P2> *prop;
+@end
+
diff --git a/test/SemaObjCXX/related-result-type-inference.mm b/test/SemaObjCXX/related-result-type-inference.mm
index c3cab05..675e6ac 100644
--- a/test/SemaObjCXX/related-result-type-inference.mm
+++ b/test/SemaObjCXX/related-result-type-inference.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fobjc-infer-related-result-type -verify %s
+// RUN: %clang_cc1 -verify %s
@interface Unrelated
@end
OpenPOWER on IntegriCloud