diff options
author | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 |
---|---|---|
committer | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 |
commit | 222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch) | |
tree | 7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/test/SemaObjCXX | |
parent | 3d206f03985b50beacae843d880bccdc91a9f424 (diff) |
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/test/SemaObjCXX')
80 files changed, 4063 insertions, 0 deletions
diff --git a/clang/test/SemaObjCXX/Inputs/arc-system-header.h b/clang/test/SemaObjCXX/Inputs/arc-system-header.h new file mode 100644 index 0000000..d7adeb4 --- /dev/null +++ b/clang/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/clang/test/SemaObjCXX/NSString-type.mm b/clang/test/SemaObjCXX/NSString-type.mm new file mode 100644 index 0000000..1033866 --- /dev/null +++ b/clang/test/SemaObjCXX/NSString-type.mm @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -verify %s +// rdar://10907410 + +void test(id pid, Class pclass) { + void (^block)(void) = @"help"; // expected-error {{cannot initialize a variable of type 'void (^)()' with an rvalue of type 'NSString *'}} + void (^block1)(void) = pid; + void (^block2)(void) = @"help"; // expected-error {{cannot initialize a variable of type 'void (^)()' with an rvalue of type 'NSString *'}} + void (^block3)(void) = @"help"; // expected-error {{cannot initialize a variable of type 'void (^)()' with an rvalue of type 'NSString *'}} +} + diff --git a/clang/test/SemaObjCXX/arc-0x.mm b/clang/test/SemaObjCXX/arc-0x.mm new file mode 100644 index 0000000..28eec51 --- /dev/null +++ b/clang/test/SemaObjCXX/arc-0x.mm @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -std=c++11 -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}} + } +} + +// rdar://problem/11068137 +void test1a() { + __autoreleasing id p; // expected-note 2 {{'p' declared here}} + (void) [&p] {}; + (void) [p] {}; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}} + (void) [=] { (void) p; }; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}} +} +void test1b() { + __autoreleasing id v; + __autoreleasing id &p = v; // expected-note 2 {{'p' declared here}} + (void) [&p] {}; + (void) [p] {}; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}} + (void) [=] { (void) p; }; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}} +} +void test1c() { + __autoreleasing id v; // expected-note {{'v' declared here}} + __autoreleasing id &p = v; + (void) ^{ (void) p; }; + (void) ^{ (void) v; }; // expected-error {{cannot capture __autoreleasing variable in a block}} +} diff --git a/clang/test/SemaObjCXX/arc-bool-conversion.mm b/clang/test/SemaObjCXX/arc-bool-conversion.mm new file mode 100644 index 0000000..d8f840e --- /dev/null +++ b/clang/test/SemaObjCXX/arc-bool-conversion.mm @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -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/clang/test/SemaObjCXX/arc-bridged-cast.mm b/clang/test/SemaObjCXX/arc-bridged-cast.mm new file mode 100644 index 0000000..1ea67a3 --- /dev/null +++ b/clang/test/SemaObjCXX/arc-bridged-cast.mm @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -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/clang/test/SemaObjCXX/arc-libstdcxx.mm b/clang/test/SemaObjCXX/arc-libstdcxx.mm new file mode 100644 index 0000000..71771b4 --- /dev/null +++ b/clang/test/SemaObjCXX/arc-libstdcxx.mm @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-arc-cxxlib=libstdc++ -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/clang/test/SemaObjCXX/arc-memfunc.mm b/clang/test/SemaObjCXX/arc-memfunc.mm new file mode 100644 index 0000000..274f873 --- /dev/null +++ b/clang/test/SemaObjCXX/arc-memfunc.mm @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -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/clang/test/SemaObjCXX/arc-non-pod.mm b/clang/test/SemaObjCXX/arc-non-pod.mm new file mode 100644 index 0000000..1c5cf7a --- /dev/null +++ b/clang/test/SemaObjCXX/arc-non-pod.mm @@ -0,0 +1,116 @@ +// RUN: %clang_cc1 -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/clang/test/SemaObjCXX/arc-nsconsumed-errors.mm b/clang/test/SemaObjCXX/arc-nsconsumed-errors.mm new file mode 100644 index 0000000..93f5d99 --- /dev/null +++ b/clang/test/SemaObjCXX/arc-nsconsumed-errors.mm @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -verify -fblocks -triple x86_64-apple-darwin10.0.0 %s +// rdar://10187884 + +typedef void (^blk)(id, __attribute((ns_consumed)) id); +typedef void (^blk1)(__attribute((ns_consumed))id, __attribute((ns_consumed)) id); +blk a = ^void (__attribute((ns_consumed)) id, __attribute((ns_consumed)) id){}; // expected-error {{cannot initialize a variable of type '__strong blk'}} + +blk b = ^void (id, __attribute((ns_consumed)) id){}; + +blk c = ^void (__attribute((ns_consumed)) id, __attribute((ns_consumed)) id){}; // expected-error {{cannot initialize a variable of type '__strong blk'}} + +blk d = ^void (id, id) {}; // expected-error {{cannot initialize a variable of type '__strong blk'}} + +blk1 a1 = ^void (__attribute((ns_consumed)) id, id){}; // expected-error {{cannot initialize a variable of type '__strong blk1'}} + +blk1 b2 = ^void (id, __attribute((ns_consumed)) id){}; // expected-error {{cannot initialize a variable of type '__strong blk1'}} + +blk1 c3 = ^void (__attribute((ns_consumed)) id, __attribute((ns_consumed)) id){}; + +blk1 d4 = ^void (id, id) {}; // expected-error {{cannot initialize a variable of type '__strong blk1'}} diff --git a/clang/test/SemaObjCXX/arc-object-init-destroy.mm b/clang/test/SemaObjCXX/arc-object-init-destroy.mm new file mode 100644 index 0000000..e10e3ea --- /dev/null +++ b/clang/test/SemaObjCXX/arc-object-init-destroy.mm @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -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/clang/test/SemaObjCXX/arc-overloading.mm b/clang/test/SemaObjCXX/arc-overloading.mm new file mode 100644 index 0000000..a749417 --- /dev/null +++ b/clang/test/SemaObjCXX/arc-overloading.mm @@ -0,0 +1,202 @@ +// RUN: %clang_cc1 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -fblocks -Wno-objc-root-class %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; +} + +// rdar://9790531 +void f9790531(void *inClientData); // expected-note {{candidate function not viable: cannot implicitly convert argument of type 'MixerEQGraphTestDelegate *const __strong' to 'void *' for 1st argument under ARC}} +void f9790531_1(struct S*inClientData); // expected-note {{candidate function not viable}} +void f9790531_2(char * inClientData); // expected-note {{candidate function not viable}} + +@class UIApplication; + +@interface MixerEQGraphTestDelegate +- (void)applicationDidFinishLaunching; +@end + +@implementation MixerEQGraphTestDelegate +- (void)applicationDidFinishLaunching { + f9790531(self); // expected-error {{no matching function for call to 'f9790531'}} + f9790531_1(self); // expected-error {{no matching function for call to 'f9790531_1'}} + f9790531_2(self); // expected-error {{no matching function for call to 'f9790531_2'}} +} +@end + +class rdar10142572 { + id f() __attribute__((ns_returns_retained)); + id g(); // expected-note{{previous declaration}} +}; + +id rdar10142572::f() { return 0; } // okay: merged down +id __attribute__((ns_returns_retained)) rdar10142572::g() { return 0; } // expected-error{{function declared with the ns_returns_retained attribute was previously declared without the ns_returns_retained attribute}} diff --git a/clang/test/SemaObjCXX/arc-ppe.mm b/clang/test/SemaObjCXX/arc-ppe.mm new file mode 100644 index 0000000..c9ff811 --- /dev/null +++ b/clang/test/SemaObjCXX/arc-ppe.mm @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fobjc-arc %s + +// Make sure the ARC auto-deduction of id* in unevaluated contexts +// works correctly in cases where we can't immediately tell whether the +// context is unevaluated. + +namespace std { + class type_info; +} + +int& NP(void*); +void test1() { (void)typeid(NP((void*)(id*)0)); } + +class Poly { virtual ~Poly(); }; +Poly& P(void*); +void test2() { (void)typeid(P((void*)(id*)0)); } // expected-error {{pointer to non-const type 'id'}} diff --git a/clang/test/SemaObjCXX/arc-system-header.mm b/clang/test/SemaObjCXX/arc-system-header.mm new file mode 100644 index 0000000..107b5b5 --- /dev/null +++ b/clang/test/SemaObjCXX/arc-system-header.mm @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fobjc-arc -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/clang/test/SemaObjCXX/arc-templates.mm b/clang/test/SemaObjCXX/arc-templates.mm new file mode 100644 index 0000000..9eca846 --- /dev/null +++ b/clang/test/SemaObjCXX/arc-templates.mm @@ -0,0 +1,268 @@ +// RUN: %clang_cc1 -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') is already explicitly ownership-qualified}} \ + // expected-error{{the type 'T_type' (aka '__strong id') is already explicitly ownership-qualified}} +}; + +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); +} + +namespace rdar9828157 { + // Template argument deduction involving lifetime qualifiers and + // non-lifetime types. + class A { }; + + template<typename T> float& f(T&); + template<typename T> int& f(__strong T&); + template<typename T> double& f(__weak T&); + + void test_f(A* ap) { + float &fr = (f)(ap); + } +} diff --git a/clang/test/SemaObjCXX/arc-type-conversion.mm b/clang/test/SemaObjCXX/arc-type-conversion.mm new file mode 100644 index 0000000..fd42513 --- /dev/null +++ b/clang/test/SemaObjCXX/arc-type-conversion.mm @@ -0,0 +1,218 @@ +// RUN: %clang_cc1 -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 {{no matching function for call to 'cvt'}} + 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/clang/test/SemaObjCXX/arc-type-traits.mm b/clang/test/SemaObjCXX/arc-type-traits.mm new file mode 100644 index 0000000..9877870 --- /dev/null +++ b/clang/test/SemaObjCXX/arc-type-traits.mm @@ -0,0 +1,90 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -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_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_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/clang/test/SemaObjCXX/arc-unavailable-for-weakref.mm b/clang/test/SemaObjCXX/arc-unavailable-for-weakref.mm new file mode 100644 index 0000000..2a80aeb --- /dev/null +++ b/clang/test/SemaObjCXX/arc-unavailable-for-weakref.mm @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -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}} \ + // expected-error {{explicit ownership qualifier on cast result has no effect}} +} + +// 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'}} \ + // expected-error {{explicit ownership qualifier on cast result has no effect}} +} + +@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>'}} \ + // expected-error {{explicit ownership qualifier on cast result has no effect}} +} + diff --git a/clang/test/SemaObjCXX/arc-unbridged-cast.mm b/clang/test/SemaObjCXX/arc-unbridged-cast.mm new file mode 100644 index 0000000..0b3ba07 --- /dev/null +++ b/clang/test/SemaObjCXX/arc-unbridged-cast.mm @@ -0,0 +1,110 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify %s + +typedef const struct __CFString * CFStringRef; +typedef const void * CFTypeRef; +extern "C" CFTypeRef CFBridgingRetain(id X); +extern "C" id CFBridgingRelease(CFTypeRef); + + +@interface Object +@property CFStringRef property; +- (CFStringRef) implicitProperty; +- (CFStringRef) newString; +- (CFStringRef) makeString; +@end + +extern Object *object; + +// rdar://9744349 +id test0(void) { + id p1 = (id)[object property]; + id p2 = (__bridge_transfer id)[object property]; + id p3 = (__bridge id)[object property]; + return (id) object.property; +} + +// rdar://10140692 +CFStringRef unauditedString(void); +CFStringRef plusOneString(void) __attribute__((cf_returns_retained)); + +#pragma clang arc_cf_code_audited begin +CFStringRef auditedString(void); +CFStringRef auditedCreateString(void); +#pragma clang arc_cf_code_audited end + +void test1(int cond) { + id x; + x = (id) auditedString(); + x = (id) (cond ? auditedString() : (void*) 0); + x = (id) (cond ? (void*) 0 : auditedString()); + x = (id) (cond ? (CFStringRef) @"help" : auditedString()); + + x = (id) unauditedString(); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} + x = (id) (cond ? unauditedString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} + x = (id) (cond ? (void*) 0 : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} + x = (id) (cond ? (CFStringRef) @"help" : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} + + x = (id) auditedCreateString(); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} + x = (id) (cond ? auditedCreateString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} + x = (id) (cond ? (void*) 0 : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} + x = (id) (cond ? (CFStringRef) @"help" : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} + + x = (id) [object property]; + x = (id) (cond ? [object property] : (void*) 0); + x = (id) (cond ? (void*) 0 : [object property]); + x = (id) (cond ? (CFStringRef) @"help" : [object property]); + + x = (id) object.property; + x = (id) (cond ? object.property : (void*) 0); + x = (id) (cond ? (void*) 0 : object.property); + x = (id) (cond ? (CFStringRef) @"help" : object.property); + + x = (id) object.implicitProperty; + x = (id) (cond ? object.implicitProperty : (void*) 0); + x = (id) (cond ? (void*) 0 : object.implicitProperty); + x = (id) (cond ? (CFStringRef) @"help" : object.implicitProperty); + + x = (id) [object makeString]; + x = (id) (cond ? [object makeString] : (void*) 0); + x = (id) (cond ? (void*) 0 : [object makeString]); + x = (id) (cond ? (CFStringRef) @"help" : [object makeString]); + + x = (id) [object newString]; + x = (id) (cond ? [object newString] : (void*) 0); + x = (id) (cond ? (void*) 0 : [object newString]); + x = (id) (cond ? (CFStringRef) @"help" : [object newString]); // a bit questionable +} + +// rdar://problem/10246264 +@interface CFTaker +- (void) takeOrdinary: (CFStringRef) arg; +- (void) takeVariadic: (int) n, ...; +- (void) takeConsumed: (CFStringRef __attribute__((cf_consumed))) arg; +@end +void testCFTaker(CFTaker *taker, id string) { + [taker takeOrdinary: (CFStringRef) string]; + [taker takeVariadic: 1, (CFStringRef) string]; + [taker takeConsumed: (CFStringRef) string]; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}} +} + +void takeCFOrdinaryUnaudited(CFStringRef arg); +void takeCFVariadicUnaudited(int n, ...); +void takeCFConsumedUnaudited(CFStringRef __attribute__((cf_consumed)) arg); +#pragma clang arc_cf_code_audited begin +void takeCFOrdinaryAudited(CFStringRef arg); +void takeCFVariadicAudited(int n, ...); +void takeCFConsumedAudited(CFStringRef __attribute__((cf_consumed)) arg); +#pragma clang arc_cf_code_audited end + +void testTakerFunctions(id string) { + takeCFOrdinaryUnaudited((CFStringRef) string); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}} + takeCFVariadicUnaudited(1, (CFStringRef) string); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}} + takeCFConsumedUnaudited((CFStringRef) string); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}} + + void (*taker)(CFStringRef) = 0; + taker((CFStringRef) string); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}} + + takeCFOrdinaryAudited((CFStringRef) string); + takeCFVariadicAudited(1, (CFStringRef) string); + takeCFConsumedAudited((CFStringRef) string); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}} +} diff --git a/clang/test/SemaObjCXX/argument-dependent-lookup.mm b/clang/test/SemaObjCXX/argument-dependent-lookup.mm new file mode 100644 index 0000000..a25cc68 --- /dev/null +++ b/clang/test/SemaObjCXX/argument-dependent-lookup.mm @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// <rdar://problem/9142559>: For the purposes of Argument-Dependent +// Lookup, Objective-C classes are considered to be in the global +// namespace. + +@interface NSFoo +@end + +template<typename T> +void f(T t) { + g(t); +} + +void g(NSFoo*); + +void test(NSFoo *foo) { + f(foo); +} diff --git a/clang/test/SemaObjCXX/blocks.mm b/clang/test/SemaObjCXX/blocks.mm new file mode 100644 index 0000000..09d614d --- /dev/null +++ b/clang/test/SemaObjCXX/blocks.mm @@ -0,0 +1,146 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s +@protocol NSObject; + +void bar(id(^)(void)); +void foo(id <NSObject>(^objectCreationBlock)(void)) { + return bar(objectCreationBlock); // OK +} + +void bar2(id(*)(void)); +void foo2(id <NSObject>(*objectCreationBlock)(void)) { + return bar2(objectCreationBlock); // expected-warning{{incompatible pointer types passing 'id<NSObject> (*)()' to parameter of type 'id (*)()'}} +} + +void bar3(id(*)()); // expected-note{{candidate function}} +void foo3(id (*objectCreationBlock)(int)) { + return bar3(objectCreationBlock); // expected-error{{no matching}} +} + +void bar4(id(^)()); // expected-note{{candidate function}} +void foo4(id (^objectCreationBlock)(int)) { + return bar4(objectCreationBlock); // expected-error{{no matching}} +} + +void foo5(id (^x)(int)) { + if (x) { } +} + +// <rdar://problem/6590445> +@interface Foo { + @private + void (^_block)(void); +} +- (void)bar; +@end + +namespace N { + class X { }; + void foo(X); +} + +@implementation Foo +- (void)bar { + _block(); + foo(N::X()); // okay +} +@end + +typedef signed char BOOL; +void foo6(void *block) { + void (^vb)(id obj, int idx, BOOL *stop) = (void (^)(id, int, BOOL *))block; + BOOL (^bb)(id obj, int idx, BOOL *stop) = (BOOL (^)(id, int, BOOL *))block; +} + +// <rdar://problem/8600419>: Require that the types of block +// parameters are complete. +namespace N1 { + template<class _T> class ptr; // expected-note{{template is declared here}} + + template<class _T> + class foo { + public: + void bar(void (^)(ptr<_T>)); + }; + + class X; + + void test2(); + + void test() + { + foo<X> f; + f.bar(^(ptr<X> _f) { // expected-error{{implicit instantiation of undefined template 'N1::ptr<N1::X>'}} + test2(); + }); + } +} + +// Make sure we successfully instantiate the copy constructor of a +// __block variable's type. +namespace N2 { + template <int n> struct A { + A() {} + A(const A &other) { + int invalid[-n]; // expected-error 2 {{array with a negative size}} + } + }; + + void test1() { + __block A<1> x; // expected-note {{requested here}} + } + + template <int n> void test2() { + __block A<n> x; // expected-note {{requested here}} + } + template void test2<2>(); +} + +// Handle value-dependent block declaration references. +namespace N3 { + template<int N> struct X { }; + + template<int N> + void f() { + X<N> xN = ^() { return X<N>(); }(); + } +} + +// rdar://8979379 + +@interface A +@end + +@interface B : A +@end + +void f(int (^bl)(A* a)); // expected-note {{candidate function not viable: no known conversion from 'int (^)(B *)' to 'int (^)(A *)' for 1st argument}} + +void g() { + f(^(B* b) { return 0; }); // expected-error {{no matching function for call to 'f'}} +} + +namespace DependentReturn { + template<typename T> + void f(T t) { + (void)^(T u) { + if (t != u) + return t + u; + else + return; + }; + + (void)^(T u) { + if (t == u) + return; + else + return t + u; + }; + } + + struct X { }; + void operator+(X, X); + bool operator==(X, X); + bool operator!=(X, X); + + template void f<X>(X); +} diff --git a/clang/test/SemaObjCXX/category-lookup.mm b/clang/test/SemaObjCXX/category-lookup.mm new file mode 100644 index 0000000..0e87025 --- /dev/null +++ b/clang/test/SemaObjCXX/category-lookup.mm @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface NSObject @end + +@interface NSObject (NSScriptClassDescription) +@end + +void f() { + NSScriptClassDescription *f; // expected-error {{use of undeclared identifier 'NSScriptClassDescription'}} +} diff --git a/clang/test/SemaObjCXX/composite-objc-pointertype.mm b/clang/test/SemaObjCXX/composite-objc-pointertype.mm new file mode 100644 index 0000000..684f633 --- /dev/null +++ b/clang/test/SemaObjCXX/composite-objc-pointertype.mm @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface Foo +@end + +@implementation Foo +- (id)test { + id bar; + Class cl; + Foo *f; + + (void)((bar!= 0) ? bar : 0); + (void)((cl != 0) ? cl : 0); + (void)((f != 0) ? 0 : f); + return (0 == 1) ? 0 : bar; +} +@end + diff --git a/clang/test/SemaObjCXX/conditional-expr.mm b/clang/test/SemaObjCXX/conditional-expr.mm new file mode 100644 index 0000000..a6b7c08 --- /dev/null +++ b/clang/test/SemaObjCXX/conditional-expr.mm @@ -0,0 +1,67 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@protocol P0 +@end +@protocol P1 +@end +@protocol P2 +@end + +@interface A <P0> +@end + +@interface B : A +@end + +void bar(id x); +void barP0(id<P0> x); +void barP1(id<P1> x); +void barP2(id<P2> x); + +void f0(A *a) { + id l = a; +} + +void f1(id x, A *a) { + id<P0> l = a; +} + +void f2(id<P1> x) { + id<P0> l = x; // expected-error {{cannot initialize a variable of type 'id<P0>' with an lvalue of type 'id<P1>'}} +} + +void f3(A *a) { + id<P1> l = a; // expected-error {{cannot initialize a variable of type 'id<P1>' with an lvalue of type 'A *'}} +} + +void f4(int cond, id x, A *a) { + bar(cond ? x : a); +} + +void f5(int cond, A *a, B *b) { + bar(cond ? a : b); +} + +void f6(int cond, id x, A *a) { + bar(cond ? (id<P0, P1>) x : a); +} + +void f7(int cond, id x, A *a) { + bar(cond ? a : (id<P0, P1>) x); +} + +void f8(int cond, id<P0,P1> x0, id<P0,P2> x1) { + barP0(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}} +} + +void f9(int cond, id<P0,P1> x0, id<P0,P2> x1) { + barP1(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}} +} + +void f10(int cond, id<P0,P1> x0, id<P0,P2> x1) { + barP2(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}} +} + +int f11(int cond, A* a, B* b) { + return (cond? b : a)->x; // expected-error{{'A' does not have a member named 'x'}} +} diff --git a/clang/test/SemaObjCXX/const-cast.mm b/clang/test/SemaObjCXX/const-cast.mm new file mode 100644 index 0000000..933fd47 --- /dev/null +++ b/clang/test/SemaObjCXX/const-cast.mm @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@class Foo; + +void test() { + const Foo *foo1 = 0; + Foo *foo2 = foo1; // expected-error {{cannot initialize}} +} + +void test1() { + const Foo *foo1 = 0; + Foo *foo2 = const_cast<Foo*>(foo1); +} diff --git a/clang/test/SemaObjCXX/conversion-ranking.mm b/clang/test/SemaObjCXX/conversion-ranking.mm new file mode 100644 index 0000000..6c1408b --- /dev/null +++ b/clang/test/SemaObjCXX/conversion-ranking.mm @@ -0,0 +1,89 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +@protocol P1 +@end + +@interface A <P1> +@end + +@interface B : A +@end + +@interface C : B +@end + +template<typename T> +struct ConvertsTo { + operator T() const; +}; + + +// conversion of C* to B* is better than conversion of C* to A*. +int &f0(A*); +float &f0(B*); + +void test_f0(C *c) { + float &fr1 = f0(c); +} + +// conversion of B* to A* is better than conversion of C* to A* +void f1(A*); + +struct ConvertsToBoth { +private: + operator C*() const; + +public: + operator B*() const; +}; + +void test_f1(ConvertsTo<B*> toB, ConvertsTo<C*> toC, ConvertsToBoth toBoth) { + f1(toB); + f1(toC); + f1(toBoth); +}; + +// A conversion to an a non-id object pointer type is better than a +// conversion to 'id'. +int &f2(A*); +float &f2(id); + +void test_f2(B *b) { + int &ir = f2(b); +} + +// A conversion to an a non-Class object pointer type is better than a +// conversion to 'Class'. +int &f3(A*); +float &f3(Class); + +void test_f3(B *b) { + int &ir = f3(b); +} + +// When both conversions convert to 'id' or 'Class', pick the most +// specific type to convert from. +void f4(id); + +void test_f4(ConvertsTo<B*> toB, ConvertsTo<C*> toC, ConvertsToBoth toBoth) { + f4(toB); + f4(toC); + f4(toBoth); +} + +void f5(id<P1>); + +void test_f5(ConvertsTo<B*> toB, ConvertsTo<C*> toC, ConvertsToBoth toBoth) { + f5(toB); + f5(toC); + f5(toBoth); +} + + +// A conversion to an a non-id object pointer type is better than a +// conversion to qualified 'id'. +int &f6(A*); +float &f6(id<P1>); + +void test_f6(B *b) { + int &ir = f6(b); +} diff --git a/clang/test/SemaObjCXX/conversion-to-objc-pointer-2.mm b/clang/test/SemaObjCXX/conversion-to-objc-pointer-2.mm new file mode 100644 index 0000000..b03d4d8 --- /dev/null +++ b/clang/test/SemaObjCXX/conversion-to-objc-pointer-2.mm @@ -0,0 +1,88 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar: // 7963410 + +@protocol NSObject @end +@interface NSObject +- (id)init; +- (id) alloc; +- (id) autorelease; +@end + +template<class T> +class TNSAutoRef +{ +public: + TNSAutoRef(T t) + : fRef(t) + { } + + ~TNSAutoRef() + { } + + operator T() const + { return fRef; } + +private: + T fRef; +}; + + +#pragma mark - + + +@protocol TFooProtocol <NSObject> + +- (void) foo; +@end + + +#pragma mark - + + +@interface TFoo : NSObject + +- (void) setBlah: (id<TFooProtocol>)blah; +@end + + +#pragma mark - + + +@implementation TFoo + +- (void) setBlah: (id<TFooProtocol>)blah + { } +@end + + +#pragma mark - + + +@interface TBar : NSObject + +- (void) setBlah: (id)blah; +@end + +#pragma mark - + + +@implementation TBar + +- (void) setBlah: (id)blah + { } +@end + + +#pragma mark - + + +int main (int argc, const char * argv[]) { + + NSObject* object1 = [[[NSObject alloc] init] autorelease]; + TNSAutoRef<NSObject*> object2([[NSObject alloc] init]); + TNSAutoRef<TBar*> bar([[TBar alloc] init]); + [bar setBlah: object1]; // <== Does not compile. It should. + if (object1 == object2) + [bar setBlah: object2]; // <== Does not compile. It should. + return 0; +} diff --git a/clang/test/SemaObjCXX/conversion-to-objc-pointer.mm b/clang/test/SemaObjCXX/conversion-to-objc-pointer.mm new file mode 100644 index 0000000..235aaac --- /dev/null +++ b/clang/test/SemaObjCXX/conversion-to-objc-pointer.mm @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar: // 7963410 + +template<class T> +class TNSAutoRef +{ +public: + TNSAutoRef(T t) + : fRef(t) + { } + + ~TNSAutoRef() + { } + + operator T() const + { return fRef; } + + T Get() const + { return fRef; } + +private: + T fRef; +}; + +@interface NSObject +- (id) alloc; +- (id)init; +@end + +@interface TFoo : NSObject +- (void) foo; +@end + +@implementation TFoo +- (void) foo {} +@end + +@interface TBar : NSObject +- (void) foo; +@end + +@implementation TBar +- (void) foo {} +@end + +int main () { + TNSAutoRef<TBar*> bar([[TBar alloc] init]); + [bar foo]; + return 0; +} diff --git a/clang/test/SemaObjCXX/cstyle-block-pointer-cast.mm b/clang/test/SemaObjCXX/cstyle-block-pointer-cast.mm new file mode 100644 index 0000000..0f982ba --- /dev/null +++ b/clang/test/SemaObjCXX/cstyle-block-pointer-cast.mm @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s +// radar 7562285 + +typedef int (^blocktype)(int a, int b); + +@interface A { + A* a; + id b; + Class c; +} +- (blocktype)Meth; +@end + +@implementation A +- (blocktype)Meth { + if (b) + return (blocktype)b; + else if (a) + return (blocktype)a; // expected-error {{C-style cast from 'A *' to 'blocktype' (aka 'int (^)(int, int)') is not allowed}} + else + return (blocktype)c; +} +@end + +@interface B { + blocktype a; + blocktype b; + blocktype c; +} +- (id)Meth; +@end + +@implementation B +- (id)Meth { + if (a) + return (A*)a; // expected-error {{C-style cast from 'blocktype' (aka 'int (^)(int, int)') to 'A *' is not allowed}} + if (b) + return (id)b; + if (c) + return (Class)b; +} +@end diff --git a/clang/test/SemaObjCXX/cstyle-cast.mm b/clang/test/SemaObjCXX/cstyle-cast.mm new file mode 100644 index 0000000..29a8404 --- /dev/null +++ b/clang/test/SemaObjCXX/cstyle-cast.mm @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@protocol P @end +@interface I @end + +struct X { X(); }; + +void test1(X x) { + void *cft; + id oct = (id)cft; + + Class ccct; + ccct = (Class)cft; + + I* iict = (I*)cft; + + id<P> qid = (id<P>)cft; + + I<P> *ip = (I<P>*)cft; + + (id)x; // expected-error {{cannot convert 'X' to 'id' without a conversion operator}} + + id *pid = (id*)ccct; + + id<P> *qpid = (id<P>*)ccct; + + int **pii; + + ccct = (Class)pii; + + qpid = (id<P>*)pii; + + iict = (I*)pii; + + pii = (int **)ccct; + + pii = (int **)qpid; + +} + diff --git a/clang/test/SemaObjCXX/cxxoperator-selector.mm b/clang/test/SemaObjCXX/cxxoperator-selector.mm new file mode 100644 index 0000000..f1aecab --- /dev/null +++ b/clang/test/SemaObjCXX/cxxoperator-selector.mm @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar:// 8328250 + +@class NSDate; + +@interface XSGraphDataSet +- and; +- xor; +- or; + +- ||; // expected-error {{expected selector for Objective-C method}} + +- &&; // expected-error {{expected selector for Objective-C method}} + +- (void)dataSetForValuesBetween:(NSDate *)startDate and:(NSDate *)endDate; +@end + +@implementation XSGraphDataSet +- (id) and{return 0; }; +- (id) xor{return 0; }; +- (id) or{return 0; }; + +- (void)dataSetForValuesBetween:(NSDate *)startDate and:(NSDate *)endDate { return; } +@end diff --git a/clang/test/SemaObjCXX/debugger-cast-result-to-id.mm b/clang/test/SemaObjCXX/debugger-cast-result-to-id.mm new file mode 100644 index 0000000..cd7aa7b --- /dev/null +++ b/clang/test/SemaObjCXX/debugger-cast-result-to-id.mm @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fdebugger-support -fdebugger-cast-result-to-id -funknown-anytype -fsyntax-only -verify %s + +// rdar://problem/9416370 +namespace test0 { + void test(id x) { + if ([x foo]) {} // expected-error {{no known method '-foo'; cast the message send to the method's return type}} + [x foo]; + } +} + +// rdar://10988847 +@class NSString; // expected-note {{forward declaration of class here}} +namespace test1 { + void rdar10988847() { + id s = [NSString stringWithUTF8String:"foo"]; // expected-warning {{receiver 'NSString' is a forward class and corresponding @interface may not exist}} + } +} diff --git a/clang/test/SemaObjCXX/deduction.mm b/clang/test/SemaObjCXX/deduction.mm new file mode 100644 index 0000000..220f368 --- /dev/null +++ b/clang/test/SemaObjCXX/deduction.mm @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@class NSString; + +// Reduced from WebKit. +namespace test0 { + template <typename T> struct RemovePointer { + typedef T Type; + }; + + template <typename T> struct RemovePointer<T*> { + typedef T Type; + }; + + template <typename T> struct RetainPtr { + typedef typename RemovePointer<T>::Type ValueType; + typedef ValueType* PtrType; + RetainPtr(PtrType ptr); + }; + + void test(NSString *S) { + RetainPtr<NSString*> ptr(S); + } + + void test(id S) { + RetainPtr<id> ptr(S); + } +} + +@class Test1Class; +@protocol Test1Protocol; +namespace test1 { + template <typename T> struct RemovePointer { + typedef T type; + }; + template <typename T> struct RemovePointer<T*> { + typedef T type; + }; + template <typename A, typename B> struct is_same {}; + template <typename A> struct is_same<A,A> { + static void foo(); + }; + template <typename T> struct tester { + void test() { + is_same<T, typename RemovePointer<T>::type*>::foo(); // expected-error 2 {{no member named 'foo'}} + } + }; + + template struct tester<id>; + template struct tester<id<Test1Protocol> >; + template struct tester<Class>; + template struct tester<Class<Test1Protocol> >; + template struct tester<Test1Class*>; + template struct tester<Test1Class<Test1Protocol>*>; + + template struct tester<Test1Class>; // expected-note {{in instantiation}} + template struct tester<Test1Class<Test1Protocol> >; // expected-note {{in instantiation}} +} + +namespace test2 { + template <typename T> void foo(const T* t) {} + void test(id x) { + foo(x); + } +} diff --git a/clang/test/SemaObjCXX/exceptions-fragile.mm b/clang/test/SemaObjCXX/exceptions-fragile.mm new file mode 100644 index 0000000..91b7077 --- /dev/null +++ b/clang/test/SemaObjCXX/exceptions-fragile.mm @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fobjc-fragile-abi -fsyntax-only -verify %s + +@interface NSException @end +void opaque(); + +namespace test0 { + void test() { + try { + } catch (NSException *e) { // expected-warning {{can not catch an exception thrown with @throw in C++ in the non-unified exception model}} + } + } +} diff --git a/clang/test/SemaObjCXX/expr-objcxx.mm b/clang/test/SemaObjCXX/expr-objcxx.mm new file mode 100644 index 0000000..e70a001 --- /dev/null +++ b/clang/test/SemaObjCXX/expr-objcxx.mm @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only + +// rdar://8366474 +void *P = @selector(foo::bar::); diff --git a/clang/test/SemaObjCXX/foreach-block.mm b/clang/test/SemaObjCXX/foreach-block.mm new file mode 100644 index 0000000..91bd0c8 --- /dev/null +++ b/clang/test/SemaObjCXX/foreach-block.mm @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s +// rdar://8295106 + +int main() { +id array; + + for (int (^b)(void) in array) { + if (b() == 10000) { + return 1; + } + } + + int (^b)(void) in array; // expected-error {{expected ';' at end of declaration}} +} diff --git a/clang/test/SemaObjCXX/fragile-abi-object-assign.m b/clang/test/SemaObjCXX/fragile-abi-object-assign.m new file mode 100644 index 0000000..5bb3ac6 --- /dev/null +++ b/clang/test/SemaObjCXX/fragile-abi-object-assign.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-fragile-abi -verify -Wno-objc-root-class %s +// rdar://10731065 + +@interface MyView {} +@end + +@implementation MyViewTemplate // expected-warning {{cannot find interface declaration for 'MyViewTemplate'}} +- (id) createRealObject { + id realObj; + *(MyView *) realObj = *(MyView *) self; // expected-error {{cannot assign to class object}} +} +@end + diff --git a/clang/test/SemaObjCXX/function-pointer-void-star.mm b/clang/test/SemaObjCXX/function-pointer-void-star.mm new file mode 100644 index 0000000..8d3d625 --- /dev/null +++ b/clang/test/SemaObjCXX/function-pointer-void-star.mm @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +extern "C" id (*_dealloc)(id) ; + +void foo() { + extern void *_original_dealloc; + if (_dealloc == _original_dealloc) { } + if (_dealloc != _original_dealloc) { } +} diff --git a/clang/test/SemaObjCXX/gc-attributes.mm b/clang/test/SemaObjCXX/gc-attributes.mm new file mode 100644 index 0000000..4549683 --- /dev/null +++ b/clang/test/SemaObjCXX/gc-attributes.mm @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-gc -fsyntax-only -verify %s + +@interface A +@end + +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; + static __weak A *a2; + f0(&a); + f0(&a2); // expected-error{{no matching function}} +} + +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; + __strong A *a2; + f1(&a); + f1(&a2); // expected-error{{no matching function}} +} diff --git a/clang/test/SemaObjCXX/goto.mm b/clang/test/SemaObjCXX/goto.mm new file mode 100644 index 0000000..55bde99 --- /dev/null +++ b/clang/test/SemaObjCXX/goto.mm @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +// PR9495 +struct NonPOD { NonPOD(); ~NonPOD(); }; + +@interface A +@end + +@implementation A +- (void)method:(bool)b { + NonPOD np; + if (b) { + goto undeclared; // expected-error{{use of undeclared label 'undeclared'}} + } +} +@end diff --git a/clang/test/SemaObjCXX/instantiate-expr.mm b/clang/test/SemaObjCXX/instantiate-expr.mm new file mode 100644 index 0000000..75a5b7e --- /dev/null +++ b/clang/test/SemaObjCXX/instantiate-expr.mm @@ -0,0 +1,75 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface A { +@public + int ivar; +} +@property int prop; +@end + +typedef struct objc_object { + Class isa; +} *id; + +// Test instantiation of value-dependent ObjCIvarRefExpr, +// ObjCIsaRefExpr, and ObjCPropertyRefExpr nodes. +A *get_an_A(unsigned); +id get_an_id(unsigned); + +template<unsigned N, typename T, typename U, typename V> +void f(U value, V value2) { + get_an_A(N)->ivar = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}} + get_an_A(N).prop = value2; // expected-error{{assigning to 'int' from incompatible type 'double *'}} + T c = get_an_id(N)->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}} \ + // expected-warning 5 {{direct access to objective-c's isa is deprecated in favor of object_setClass() and object_getClass()}} +} + +template void f<6, Class>(int, int); // expected-note{{in instantiation of}} +template void f<7, Class>(int*, int); // expected-note{{in instantiation of}} +template void f<8, Class>(int, double*); // expected-note{{in instantiation of}} +template void f<9, int>(int, int); // expected-note{{in instantiation of}} + +// Test instantiation of unresolved member reference expressions to an +// ivar reference. +template<typename T, typename U, typename V> +void f2(T ptr, U value, V value2) { + ptr->ivar = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}} + ptr.prop = value2; // expected-error{{assigning to 'int' from incompatible type 'double *'}} +} + +template void f2(A*, int, int); +template void f2(A*, int*, int); // expected-note{{instantiation of}} +template void f2(A*, int, double*); // expected-note{{instantiation of}} + +// Test instantiation of unresolved member referfence expressions to +// an isa. +template<typename T, typename U> +void f3(U ptr) { + T c = ptr->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}} \ + // expected-warning 2 {{direct access to objective-c's isa is deprecated in favor of object_setClass() and object_getClass()}} +} + +template void f3<Class>(id); // expected-note{{in instantiation of}} +template void f3<int>(id); // expected-note{{instantiation of}} + +// Implicit setter/getter +@interface B +- (int)foo; +- (void)setFoo:(int)value; +@end + +template<typename T> +void f4(B *b, T value) { + b.foo = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}} +} + +template void f4(B*, int); +template void f4(B*, int*); // expected-note{{in instantiation of function template specialization 'f4<int *>' requested here}} + +template<typename T, typename U> +void f5(T ptr, U value) { + ptr.foo = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}} +} + +template void f5(B*, int); +template void f5(B*, int*); // expected-note{{in instantiation of function template specialization 'f5<B *, int *>' requested here}} diff --git a/clang/test/SemaObjCXX/instantiate-message.mm b/clang/test/SemaObjCXX/instantiate-message.mm new file mode 100644 index 0000000..e09b182 --- /dev/null +++ b/clang/test/SemaObjCXX/instantiate-message.mm @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// Test template instantiation of Objective-C message sends. + +@interface ClassMethods ++ (ClassMethods *)method1:(void*)ptr; +@end + +template<typename T> +struct identity { + typedef T type; +}; + +template<typename R, typename T, typename Arg1> +void test_class_method(Arg1 arg1) { + R *result1 = [T method1:arg1]; + R *result2 = [typename identity<T>::type method1:arg1]; + R *result3 = [ClassMethods method1:arg1]; // expected-error{{cannot initialize a variable of type 'ClassMethods2 *' with an rvalue of type 'ClassMethods *'}} +} + +template void test_class_method<ClassMethods, ClassMethods>(void*); +template void test_class_method<ClassMethods, ClassMethods>(int*); + +@interface ClassMethods2 ++ (ClassMethods2 *)method1:(int*)ptr; +@end + +template void test_class_method<ClassMethods2, ClassMethods2>(int*); // expected-note{{in instantiation of}} + + +@interface InstanceMethods +- (InstanceMethods *)method1:(void*)ptr; +@end + +template<typename R, typename T, typename Arg1> +void test_instance_method(Arg1 arg1) { + T *receiver = 0; + InstanceMethods *im = 0; + R *result1 = [receiver method1:arg1]; + R *result2 = [im method1:arg1]; // expected-error{{cannot initialize a variable of type 'InstanceMethods2 *' with an rvalue of type 'InstanceMethods *'}} +} + +template void test_instance_method<InstanceMethods, InstanceMethods>(void*); +template void test_instance_method<InstanceMethods, InstanceMethods>(int*); + +@interface InstanceMethods2 +- (InstanceMethods2 *)method1:(void*)ptr; +@end + +template void test_instance_method<InstanceMethods2, InstanceMethods2>(int*); // expected-note{{in instantiation of}} diff --git a/clang/test/SemaObjCXX/instantiate-method-return.mm b/clang/test/SemaObjCXX/instantiate-method-return.mm new file mode 100644 index 0000000..2a3ae32 --- /dev/null +++ b/clang/test/SemaObjCXX/instantiate-method-return.mm @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// PR7386 + +@class NSObject; + +class A; +template<class T> class V {}; + +@protocol Protocol +- (V<A*>)protocolMethod; +@end + + +@interface I<Protocol> +@end + + +@implementation I +- (void)randomMethod:(id)info { + V<A*> vec([self protocolMethod]); +} + +- (V<A*>)protocolMethod { + V<A*> va; return va; +} +@end diff --git a/clang/test/SemaObjCXX/instantiate-stmt.mm b/clang/test/SemaObjCXX/instantiate-stmt.mm new file mode 100644 index 0000000..ff72858 --- /dev/null +++ b/clang/test/SemaObjCXX/instantiate-stmt.mm @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fobjc-exceptions %s + +@interface NSException +@end + +// @throw +template<typename T> +void throw_test(T value) { + @throw value; // expected-error{{@throw requires an Objective-C object type ('int' invalid)}} +} + +template void throw_test(NSException *); +template void throw_test(int); // expected-note{{in instantiation of}} + +// @synchronized +template<typename T> +void synchronized_test(T value) { + @synchronized (value) { // expected-error{{@synchronized requires an Objective-C object type ('int' invalid)}} + value = 0; + } +} + +template void synchronized_test(NSException *); +template void synchronized_test(int); // expected-note{{in instantiation of}} + +// fast enumeration +@interface NSArray +- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount; +@end + +@interface NSString +@end + +struct vector {}; + +template<typename T> void eat(T); + +template<typename E, typename T> +void fast_enumeration_test(T collection) { + for (E element in collection) { // expected-error{{selector element type 'int' is not a valid object}} \ + // expected-error{{collection expression type 'vector' is not a valid object}} + eat(element); + } + + E element; + for (element in collection) // expected-error{{selector element type 'int' is not a valid object}} \ + // expected-error{{collection expression type 'vector' is not a valid object}} + eat(element); + + for (NSString *str in collection) // expected-error{{collection expression type 'vector' is not a valid object}} + eat(str); + + NSString *str; + for (str in collection) // expected-error{{collection expression type 'vector' is not a valid object}} + eat(str); +} + +template void fast_enumeration_test<NSString *>(NSArray*); +template void fast_enumeration_test<int>(NSArray*); // expected-note{{in instantiation of}} +template void fast_enumeration_test<NSString *>(vector); // expected-note{{in instantiation of}} + +// @try/@catch/@finally + +template<typename T, typename U> +void try_catch_finally_test(U value) { + @try { + value = 1; // expected-error{{assigning to 'int *' from incompatible type 'int'}} + } + @catch (T obj) { // expected-error{{@catch parameter is not a pointer to an interface type}} + id x = obj; + } @finally { + value = 0; + } +} + +template void try_catch_finally_test<NSString *>(int); +template void try_catch_finally_test<NSString *>(int*); // expected-note{{in instantiation of}} +template void try_catch_finally_test<NSString>(int); // expected-note{{in instantiation of function template specialization 'try_catch_finally_test<NSString, int>' requested here}} diff --git a/clang/test/SemaObjCXX/ivar-construct.mm b/clang/test/SemaObjCXX/ivar-construct.mm new file mode 100644 index 0000000..a066fca --- /dev/null +++ b/clang/test/SemaObjCXX/ivar-construct.mm @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +struct Y { + Y(); + +private: + ~Y(); // expected-note 3{{declared private here}} +}; + +template<typename T> +struct X : T { }; // expected-error 2{{private destructor}} + +struct Z; // expected-note{{forward declaration}} + +@interface A { + X<Y> x; // expected-note{{implicit default destructor}} + Y y; // expected-error{{private destructor}} +} +@end + +@implementation A // expected-note{{implicit default constructor}} +@end + +@interface B { + Z z; // expected-error{{incomplete type}} +} +@end + +@implementation B +@end + +// <rdar://problem/11284902> +template<typename T> struct Incomplete; // expected-note{{declared here}} + +@interface C { + Incomplete<int> a[4][4][4]; // expected-error{{implicit instantiation of undefined template 'Incomplete<int>'}} +} +@end diff --git a/clang/test/SemaObjCXX/ivar-lookup.mm b/clang/test/SemaObjCXX/ivar-lookup.mm new file mode 100644 index 0000000..fc99c15 --- /dev/null +++ b/clang/test/SemaObjCXX/ivar-lookup.mm @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +@interface Ivar +- (float*)method; +@end + +@interface A { + A *Ivar; +} +- (int*)method; +@end + +@implementation A +- (int*)method { + int *ip = [Ivar method]; // Okay; calls A's method on the instance variable Ivar. + // Note that Objective-C calls Ivar's method. + return 0; +} +@end diff --git a/clang/test/SemaObjCXX/ivar-reference-type.mm b/clang/test/SemaObjCXX/ivar-reference-type.mm new file mode 100644 index 0000000..2b5df45 --- /dev/null +++ b/clang/test/SemaObjCXX/ivar-reference-type.mm @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +@interface A { + int &r; // expected-error {{instance variables cannot be of reference type}} +} +@end diff --git a/clang/test/SemaObjCXX/ivar-struct.mm b/clang/test/SemaObjCXX/ivar-struct.mm new file mode 100644 index 0000000..3f9c7eb --- /dev/null +++ b/clang/test/SemaObjCXX/ivar-struct.mm @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +@interface A { + struct X { + int x, y; + } X; +} +@end diff --git a/clang/test/SemaObjCXX/linkage-spec.mm b/clang/test/SemaObjCXX/linkage-spec.mm new file mode 100644 index 0000000..584571d --- /dev/null +++ b/clang/test/SemaObjCXX/linkage-spec.mm @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +extern "C" { +@class Protocol; +} + +// <rdar://problem/7827709> +extern "C" { +@class I; +} + +@interface I +@end + +// rdar://10015110 +@protocol VKAnnotation; +extern "C" { + +@protocol VKAnnotation + @property (nonatomic, assign) id coordinate; +@end +} diff --git a/clang/test/SemaObjCXX/literals.mm b/clang/test/SemaObjCXX/literals.mm new file mode 100644 index 0000000..6cdd207 --- /dev/null +++ b/clang/test/SemaObjCXX/literals.mm @@ -0,0 +1,187 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x -fblocks %s + +// rdar://11231426 +typedef signed char BOOL; + +void y(BOOL (^foo)()); + +void x() { + y(^{ + return __objc_yes; + }); +} + +@protocol NSCopying +- copy; +@end + +@interface NSObject +@end + +@interface NSNumber : NSObject <NSCopying> +-copy; +@end + +@interface NSNumber (NSNumberCreation) ++ (NSNumber *)numberWithChar:(char)value; ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; ++ (NSNumber *)numberWithShort:(short)value; ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; ++ (NSNumber *)numberWithInt:(int)value; ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; ++ (NSNumber *)numberWithLong:(long)value; ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; ++ (NSNumber *)numberWithLongLong:(long long)value; ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; ++ (NSNumber *)numberWithFloat:(float)value; ++ (NSNumber *)numberWithDouble:(double)value; ++ (NSNumber *)numberWithBool:(BOOL)value; +@end + +@interface NSArray : NSObject <NSCopying> +-copy; +@end + +@interface NSArray (NSArrayCreation) ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; +@end + +@interface NSDictionary ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(unsigned long)cnt; +@end + +template<typename T> +struct ConvertibleTo { + operator T(); +}; + +template<typename T> +struct ExplicitlyConvertibleTo { + explicit operator T(); +}; + +template<typename T> +class PrivateConvertibleTo { +private: + operator T(); // expected-note{{declared private here}} +}; + +template<typename T> ConvertibleTo<T> makeConvertible(); + +struct X { + ConvertibleTo<id> x; + ConvertibleTo<id> get(); +}; + +template<typename T> T test_numeric_instantiation() { + return @-17.42; +} + +template id test_numeric_instantiation(); + +void test_convertibility(ConvertibleTo<NSArray*> toArray, + ConvertibleTo<id> toId, + ConvertibleTo<int (^)(int)> toBlock, + ConvertibleTo<int> toInt, + ExplicitlyConvertibleTo<NSArray *> toArrayExplicit) { + id array = @[ + toArray, + toId, + toBlock, + toInt // expected-error{{collection element of type 'ConvertibleTo<int>' is not an Objective-C object}} + ]; + id array2 = @[ toArrayExplicit ]; // expected-error{{collection element of type 'ExplicitlyConvertibleTo<NSArray *>' is not an Objective-C object}} + + id array3 = @[ + makeConvertible<id>(), + makeConvertible<id>, // expected-error{{collection element of type 'ConvertibleTo<id> ()' is not an Objective-C object}} + ]; + + X x; + id array4 = @[ x.x ]; + id array5 = @[ x.get ]; // expected-error{{reference to non-static member function must be called}} + id array6 = @[ PrivateConvertibleTo<NSArray*>() ]; // expected-error{{operator NSArray *' is a private member of 'PrivateConvertibleTo<NSArray *>'}} +} + +template<typename T> +void test_array_literals(T t) { + id arr = @[ @17, t ]; // expected-error{{collection element of type 'int' is not an Objective-C object}} +} + +template void test_array_literals(id); +template void test_array_literals(NSArray*); +template void test_array_literals(int); // expected-note{{in instantiation of function template specialization 'test_array_literals<int>' requested here}} + +template<typename T, typename U> +void test_dictionary_literals(T t, U u) { + NSObject *object; + id dict = @{ + @17 : t, // expected-error{{collection element of type 'int' is not an Objective-C object}} + u : @42 // expected-error{{collection element of type 'int' is not an Objective-C object}} + }; + + id dict2 = @{ + object : @"object" // expected-error{{cannot initialize a parameter of type 'const id<NSCopying>' with an rvalue of type 'NSObject *'}} + }; +} + +template void test_dictionary_literals(id, NSArray*); +template void test_dictionary_literals(NSArray*, id); +template void test_dictionary_literals(int, id); // expected-note{{in instantiation of function template specialization 'test_dictionary_literals<int, id>' requested here}} +template void test_dictionary_literals(id, int); // expected-note{{in instantiation of function template specialization 'test_dictionary_literals<id, int>' requested here}} + +template<typename ...Args> +void test_bad_variadic_array_literal(Args ...args) { + id arr1 = @[ args ]; // expected-error{{initializer contains unexpanded parameter pack 'args'}} +} + +template<typename ...Args> +void test_variadic_array_literal(Args ...args) { + id arr1 = @[ args... ]; // expected-error{{collection element of type 'int' is not an Objective-C object}} +} +template void test_variadic_array_literal(id); +template void test_variadic_array_literal(id, NSArray*); +template void test_variadic_array_literal(id, int, NSArray*); // expected-note{{in instantiation of function template specialization 'test_variadic_array_literal<id, int, NSArray *>' requested here}} + +template<typename ...Args> +void test_bad_variadic_dictionary_literal(Args ...args) { + id dict = @{ args : @17 }; // expected-error{{initializer contains unexpanded parameter pack 'args'}} +} + +// Test array literal pack expansions. +template<typename T, typename U> +struct pair { + T first; + U second; +}; + +template<typename T, typename ...Ts, typename ... Us> +void test_variadic_dictionary_expansion(T t, pair<Ts, Us>... key_values) { + id dict = @{ + t : key_values.second ..., // expected-error{{collection element of type 'int' is not an Objective-C object}} + key_values.first : key_values.second ..., // expected-error{{collection element of type 'float' is not an Objective-C object}} + key_values.second : t ... + }; +} + +template void test_variadic_dictionary_expansion(id, + pair<NSNumber*, id>, + pair<id, ConvertibleTo<id>>); +template void test_variadic_dictionary_expansion(NSNumber *, // expected-note{{in instantiation of function template specialization}} + pair<NSNumber*, int>, + pair<id, ConvertibleTo<id>>); +template void test_variadic_dictionary_expansion(NSNumber *, // expected-note{{in instantiation of function template specialization}} + pair<NSNumber*, id>, + pair<float, ConvertibleTo<id>>); + +// Test parsing +struct key { + static id value; +}; + +id key; +id value; + +void test_dictionary_colon() { + id dict = @{ key : value }; +} diff --git a/clang/test/SemaObjCXX/message.mm b/clang/test/SemaObjCXX/message.mm new file mode 100644 index 0000000..5ac2f40 --- /dev/null +++ b/clang/test/SemaObjCXX/message.mm @@ -0,0 +1,127 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-fragile-abi -verify -Wno-objc-root-class %s +@interface I1 +- (int*)method; +@end + +@implementation I1 +- (int*)method { + struct x { }; + [x method]; // expected-error{{receiver type 'x' is not an Objective-C class}} + return 0; +} +@end + +typedef struct { int x; } ivar; + +@interface I2 { + id ivar; +} +- (int*)method; ++ (void)method; +@end + +struct I2_holder { + I2_holder(); + + I2 *get(); +}; + +I2 *operator+(I2_holder, int); + +@implementation I2 +- (int*)method { + [ivar method]; + + // Test instance messages that start with a simple-type-specifier. + [I2_holder().get() method]; + [I2_holder().get() + 17 method]; + return 0; +} ++ (void)method { + [ivar method]; // expected-error{{receiver type 'ivar' is not an Objective-C class}} +} +@end + +// Class message sends +@interface I3 ++ (int*)method; +@end + +@interface I4 : I3 ++ (int*)otherMethod; +@end + +template<typename T> +struct identity { + typedef T type; +}; + +@implementation I4 ++ (int *)otherMethod { + // Test class messages that use non-trivial simple-type-specifiers + // or typename-specifiers. + if (false) { + if (true) + return [typename identity<I3>::type method]; // expected-warning{{occurs outside of a template}} + + return [::I3 method]; + } + + int* ip1 = {[super method]}; + int* ip2 = {[::I3 method]}; + int* ip3 = {[typename identity<I3>::type method]}; // expected-warning{{occurs outside of a template}} + int* ip4 = {[typename identity<I2_holder>::type().get() method]}; // expected-warning{{occurs outside of a template}} + int array[5] = {[3] = 2}; + return [super method]; +} +@end + +struct String { + String(const char *); +}; + +struct MutableString : public String { }; + +// C++-specific parameter types +@interface I5 +- method:(const String&)str1 + other:(String&)str2; // expected-note{{passing argument to parameter 'str2' here}} +@end + +void test_I5(I5 *i5, String s) { + [i5 method:"hello" other:s]; + [i5 method:s other:"world"]; // expected-error{{non-const lvalue reference to type 'String' cannot bind to a value of unrelated type 'const char [6]'}} +} + +// <rdar://problem/8483253> +@interface A + +struct X { }; + ++ (A *)create:(void (*)(void *x, X r, void *data))callback + callbackData:(void *)callback_data; + +@end + + +void foo(void) +{ + void *fun; + void *ptr; + X r; + A *im = [A create:(void (*)(void *cgl_ctx, X r, void *data)) fun + callbackData:ptr]; +} + +// <rdar://problem/8807070> +template<typename T> struct X1; // expected-note{{template is declared here}} + +@interface B ++ (X1<int>)blah; ++ (X1<float>&)blarg; +@end + +void f() { + [B blah]; // expected-error{{implicit instantiation of undefined template 'X1<int>'}} + [B blarg]; +} diff --git a/clang/test/SemaObjCXX/namespace-lookup.mm b/clang/test/SemaObjCXX/namespace-lookup.mm new file mode 100644 index 0000000..205b443 --- /dev/null +++ b/clang/test/SemaObjCXX/namespace-lookup.mm @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// <rdar://problem/9388207> +@interface A +@end + +@interface A(N) +@end + +@protocol M +@end + +namespace N { } +namespace M { } diff --git a/clang/test/SemaObjCXX/null_objc_pointer.mm b/clang/test/SemaObjCXX/null_objc_pointer.mm new file mode 100644 index 0000000..0da9e50 --- /dev/null +++ b/clang/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/clang/test/SemaObjCXX/nullptr.mm b/clang/test/SemaObjCXX/nullptr.mm new file mode 100644 index 0000000..2b29b04 --- /dev/null +++ b/clang/test/SemaObjCXX/nullptr.mm @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++11 -fblocks -fsyntax-only -verify %s + +@interface A +@end + +void comparisons(A *a) { + (void)(a == nullptr); + (void)(nullptr == a); +} + +void assignment(A *a) { + a = nullptr; +} + +int PR10145a = (void(^)())0 == nullptr; +int PR10145b = nullptr == (void(^)())0; diff --git a/clang/test/SemaObjCXX/objc-container-subscripting.mm b/clang/test/SemaObjCXX/objc-container-subscripting.mm new file mode 100644 index 0000000..c835cbe --- /dev/null +++ b/clang/test/SemaObjCXX/objc-container-subscripting.mm @@ -0,0 +1,138 @@ +// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin11 -fsyntax-only -std=c++11 -verify %s + +@class NSArray; + +@interface NSMutableDictionary +- (id)objectForKeyedSubscript:(id)key; +- (void)setObject:(id)object forKeyedSubscript:(id)key; // expected-note {{passing argument to parameter 'object' here}} +@end + +template<typename T, typename U, typename O> +void test_dictionary_subscripts(T base, U key, O obj) { + base[key] = obj; // expected-error {{expected method to write array element not found on object of type 'NSMutableDictionary *'}} \ + // expected-error {{cannot initialize a parameter of type 'id' with an lvalue of type 'int'}} + obj = base[key]; // expected-error {{expected method to read array element not found on object of type 'NSMutableDictionary *'}} \ + // expected-error {{assigning to 'int' from incompatible type 'id'}} + +} + +template void test_dictionary_subscripts(NSMutableDictionary*, id, NSArray *ns); + +template void test_dictionary_subscripts(NSMutableDictionary*, NSArray *ns, id); + +template void test_dictionary_subscripts(NSMutableDictionary*, int, id); // expected-note {{in instantiation of function template specialization 'test_dictionary_subscripts<NSMutableDictionary *, int, id>' requested here}} + +template void test_dictionary_subscripts(NSMutableDictionary*, id, int); // expected-note {{in instantiation of function template specialization 'test_dictionary_subscripts<NSMutableDictionary *, id, int>' requested here}} + + +@interface NSMutableArray +- (id)objectAtIndexedSubscript:(int)index; +- (void)setObject:(id)object atIndexedSubscript:(int)index; +@end + +template<typename T, typename U, typename O> +void test_array_subscripts(T base, U index, O obj) { + base[index] = obj; // expected-error {{indexing expression is invalid because subscript type 'double' is not an integral or objective-C pointer type}} + obj = base[index]; // expected-error {{indexing expression is invalid because subscript type 'double' is not an integral or objective-C pointer type}} +} + +template void test_array_subscripts(NSMutableArray *, int, id); +template void test_array_subscripts(NSMutableArray *, short, id); +enum E { e }; + +template void test_array_subscripts(NSMutableArray *, E, id); + +template void test_array_subscripts(NSMutableArray *, double, id); // expected-note {{in instantiation of function template specialization 'test_array_subscripts<NSMutableArray *, double, id>' requested here}} + +template<typename T> +struct ConvertibleTo { + operator T(); +}; + +template<typename T> +struct ExplicitlyConvertibleTo { + explicit operator T(); +}; + +template<typename T> ConvertibleTo<T> makeConvertible(); + +struct X { + ConvertibleTo<id> x; + ConvertibleTo<id> get(); +}; + +NSMutableArray *test_array_convertibility(ConvertibleTo<NSMutableArray*> toArray, + ConvertibleTo<id> toId, + ConvertibleTo<int (^)(int)> toBlock, + ConvertibleTo<int> toInt, + ExplicitlyConvertibleTo<NSMutableArray *> toArrayExplicit) { + id array; + + array[1] = toArray; + + array[4] = array[1]; + + toArrayExplicit[2] = toId; // expected-error {{type 'ExplicitlyConvertibleTo<NSMutableArray *>' does not provide a subscript operator}} + + return array[toInt]; + +} + +id test_dict_convertibility(ConvertibleTo<NSMutableDictionary*> toDict, + ConvertibleTo<id> toId, + ConvertibleTo<int (^)(int)> toBlock, + ConvertibleTo<int> toInt, + ExplicitlyConvertibleTo<NSMutableDictionary *> toDictExplicit) { + + + NSMutableDictionary *Dict; + id Id; + Dict[toId] = toBlock; + + Dict[toBlock] = toBlock; + + Dict[toBlock] = Dict[toId] = Dict[toBlock]; + + Id = toDictExplicit[toId] = Id; // expected-error {{no viable overloaded operator[] for type 'ExplicitlyConvertibleTo<NSMutableDictionary *>'}} + + return Dict[toBlock]; +} + + +template<typename ...Args> +void test_bad_variadic_array_subscripting(Args ...args) { + id arr1; + arr1[3] = args; // expected-error {{expression contains unexpanded parameter pack 'args'}} +} + +template<typename ...Args> +void test_variadic_array_subscripting(Args ...args) { + id arr[] = {args[3]...}; // which means: {a[3], b[3], c[3]}; +} + +template void test_variadic_array_subscripting(id arg1, NSMutableArray* arg2, id arg3); + +@class Key; + +template<typename Index, typename ...Args> +void test_variadic_dictionary_subscripting(Index I, Args ...args) { + id arr[] = {args[I]...}; // which means: {a[3], b[3], c[3]}; +} + +template void test_variadic_dictionary_subscripting(Key *key, id arg1, NSMutableDictionary* arg2, id arg3); + +template<int N> +id get(NSMutableArray *array) { + return array[N]; // array[N] should be a value- and instantiation-dependent ObjCSubscriptRefExpr +} + +struct WeirdIndex { + operator int(); // expected-note {{type conversion function declared here}} + operator id(); // expected-note {{type conversion function declared here}} +}; + +id FUNC(WeirdIndex w) { + NSMutableArray *array; + return array[w]; // expected-error {{indexing expression is invalid because subscript type 'WeirdIndex' has multiple type conversion functions}} +} + diff --git a/clang/test/SemaObjCXX/objc-decls-inside-namespace.mm b/clang/test/SemaObjCXX/objc-decls-inside-namespace.mm new file mode 100644 index 0000000..0702071 --- /dev/null +++ b/clang/test/SemaObjCXX/objc-decls-inside-namespace.mm @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +namespace C { + +@protocol P; //expected-error{{Objective-C declarations may only appear in global scope}} + +@class Bar; //expected-error{{Objective-C declarations may only appear in global scope}} + +@compatibility_alias Foo Bar; //expected-error{{Objective-C declarations may only appear in global scope}} + +@interface A //expected-error{{Objective-C declarations may only appear in global scope}} +@end + +@implementation A //expected-error{{Objective-C declarations may only appear in global scope}} +@end + +@protocol P //expected-error{{Objective-C declarations may only appear in global scope}} +@end + +@interface A(C) //expected-error{{Objective-C declarations may only appear in global scope}} +@end + +@implementation A(C) //expected-error{{Objective-C declarations may only appear in global scope}} +@end + +@interface B @end //expected-error{{Objective-C declarations may only appear in global scope}} +@implementation B //expected-error{{Objective-C declarations may only appear in global scope}} ++ (void) foo {} +@end + +} + diff --git a/clang/test/SemaObjCXX/objc-extern-c.mm b/clang/test/SemaObjCXX/objc-extern-c.mm new file mode 100644 index 0000000..6bd3761 --- /dev/null +++ b/clang/test/SemaObjCXX/objc-extern-c.mm @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@protocol P // expected-note {{previous}} +-(void)meth1; +@end + +@interface I // expected-note {{previous}} +@end + +@interface I2 +@end +@interface I2(C) // expected-note {{previous}} +@end + +extern "C" { +@protocol P // expected-warning {{duplicate protocol definition of 'P' is ignored}} +-(void)meth2; +@end + +@interface I // expected-error {{duplicate}} +@end + +@interface I2(C) // expected-warning {{duplicate}} +@end +} + +void test(id<P> p) { + [p meth1]; + [p meth2]; // expected-warning {{not found}} +} diff --git a/clang/test/SemaObjCXX/objc-pointer-conv.mm b/clang/test/SemaObjCXX/objc-pointer-conv.mm new file mode 100644 index 0000000..611b7bc --- /dev/null +++ b/clang/test/SemaObjCXX/objc-pointer-conv.mm @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +typedef const void * VoidStar; + +typedef struct __CFDictionary * CFMDRef; + +void RandomFunc(CFMDRef theDict, const void *key, const void *value); + +@interface Foo +- (void)_apply:(void (*)(const void *, const void *, void *))func context:(void *)context; +- (void)a:(id *)objects b:(id *)keys; +@end + +@implementation Foo +- (void)_apply:(void (*)(const void *, const void *, void *))func context:(void *)context { + id item; + id obj; + func(item, obj, context); +} + +- (void)a:(id *)objects b:(id *)keys { + VoidStar dict; + id key; + RandomFunc((CFMDRef)dict, key, objects[3]); +} +@end + +@interface I +- (void) Meth : (I*) Arg; // expected-note{{passing argument to parameter 'Arg' here}} +@end + +void Func (I* arg); // expected-note {{candidate function not viable: no known conversion from 'const I *' to 'I *' for 1st argument}} + +void foo(const I *p, I* sel) { + [sel Meth : p]; // expected-error {{cannot initialize a parameter of type 'I *' with an lvalue of type 'const I *'}} + Func(p); // expected-error {{no matching function for call to 'Func'}} +} + +@interface DerivedFromI : I +@end + +void accept_derived(DerivedFromI*); + +void test_base_to_derived(I* i) { + accept_derived(i); // expected-warning{{incompatible pointer types passing 'I *' to parameter of type 'DerivedFromI *'}} + DerivedFromI *di = i; // expected-warning{{incompatible pointer types initializing 'DerivedFromI *' with an expression of type 'I *'}} + DerivedFromI *di2 = (DerivedFromI *)i; +} diff --git a/clang/test/SemaObjCXX/objc2-merge-gc-attribue-decl.mm b/clang/test/SemaObjCXX/objc2-merge-gc-attribue-decl.mm new file mode 100644 index 0000000..7be5f17 --- /dev/null +++ b/clang/test/SemaObjCXX/objc2-merge-gc-attribue-decl.mm @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-gc -fsyntax-only -verify %s +@interface INTF @end + +extern INTF* p2; +extern __strong INTF* p2; + +extern __strong id p1; +extern id p1; + +extern id CFRunLoopGetMain(); +extern __strong id CFRunLoopGetMain(); + +extern __strong id CFRunLoopGetMain2(); +extern id CFRunLoopGetMain2(); + +extern INTF* CFRunLoopGetMain3(); +extern __strong INTF* CFRunLoopGetMain3(); + +extern __strong INTF* CFRunLoopGetMain4(); +extern INTF* CFRunLoopGetMain4(); + +typedef id ID; +extern ID CFRunLoopGetMain5(); +extern __strong id CFRunLoopGetMain5(); + +extern __strong id CFRunLoopGetMain6(); +extern ID CFRunLoopGetMain6(); + +extern ID CFRunLoopGetMain7(); +extern __strong ID CFRunLoopGetMain7(); + +extern __strong ID CFRunLoopGetMain8(); +extern ID CFRunLoopGetMain8(); + +extern __weak id WLoopGetMain(); // expected-note {{previous declaration is here}} +extern id WLoopGetMain(); // expected-error {{functions that differ only in their return type cannot be overloaded}} + +extern id p3; // expected-note {{previous definition is here}} +extern __weak id p3; // expected-error {{redefinition of 'p3' with a different type}} + +extern void *p4; // expected-note {{previous definition is here}} +extern void * __strong p4; // expected-error {{redefinition of 'p4' with a different type}} + +extern id p5; +extern __strong id p5; + +extern char* __strong p6; // expected-note {{previous definition is here}} +extern char* p6; // expected-error {{redefinition of 'p6' with a different type}} + +extern __strong char* p7; // expected-note {{previous definition is here}} +extern char* p7; // expected-error {{redefinition of 'p7' with a different type}} diff --git a/clang/test/SemaObjCXX/overload-1.mm b/clang/test/SemaObjCXX/overload-1.mm new file mode 100644 index 0000000..fc17ca2 --- /dev/null +++ b/clang/test/SemaObjCXX/overload-1.mm @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@protocol Proto1 @end + +@protocol Proto2 @end + +void f(id<Proto1> *) { } // expected-note {{previous definition is here}} + +void f(id<Proto1, Proto2> *) { } // expected-error {{conflicting types for 'f'}} + +void f(Class<Proto1> *) { } // expected-note {{previous definition is here}} + +void f(Class<Proto1, Proto2> *) { } // expected-error {{conflicting types for 'f'}} + +@interface I @end + +void f(I<Proto1> *) { } // expected-note {{previous definition is here}} + +void f(I<Proto1, Proto2> *) { } // expected-error {{conflicting types for 'f'}} + +@interface I1 @end + +void f1(I<Proto1> *) { } + +void f1(I1<Proto1, Proto2> *) { } diff --git a/clang/test/SemaObjCXX/overload-gc.mm b/clang/test/SemaObjCXX/overload-gc.mm new file mode 100644 index 0000000..5488ea5 --- /dev/null +++ b/clang/test/SemaObjCXX/overload-gc.mm @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -triple i386-apple-darwin9 -fobjc-gc -verify %s + +void f0(__weak id *); + +void test_f0(id *x) { + f0(x); +} + +@interface A +@end + +void f1(__weak id*); +void test_f1(__weak A** a) { + f1(a); +} + +@interface B : A +@end + +void f2(__weak A**); +void test_f2(__weak B** b) { + f2(b); +} + diff --git a/clang/test/SemaObjCXX/overload.mm b/clang/test/SemaObjCXX/overload.mm new file mode 100644 index 0000000..6f24c59 --- /dev/null +++ b/clang/test/SemaObjCXX/overload.mm @@ -0,0 +1,179 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +@interface Foo +@end + +@implementation Foo + +void func(id); + ++ zone { + func(self); + return self; +} +@end + +@protocol P0 +@end + +@protocol P1 +@end + +@interface A <P0> +@end + +@interface B : A +@end + +@interface C <P1> +@end + +int& f(A*); // expected-note {{candidate}} +float& f(B*); // expected-note {{candidate}} +void g(A*); + +int& h(A*); +float& h(id); + +void test0(A* a, B* b, id val) { + int& i1 = f(a); + float& f1 = f(b); + + // GCC succeeds here, which is clearly ridiculous. + float& f2 = f(val); // expected-error {{ambiguous}} + + g(a); + g(b); + g(val); + int& i2 = h(a); + float& f3 = h(val); + + int& i3 = h(b); +} + +void test1(A* a) { + B* b = a; // expected-warning{{incompatible pointer types initializing 'B *' with an expression of type 'A *'}} + B *c; c = a; // expected-warning{{incompatible pointer types assigning to 'B *' from 'A *'}} +} + +void test2(A** ap) { + B** bp = ap; // expected-warning{{incompatible pointer types initializing 'B **' with an expression of type 'A **'}} + bp = ap; // expected-warning{{incompatible pointer types assigning to 'B **' from 'A **'}} +} + +// FIXME: we should either allow overloading here or give a better diagnostic +int& cv(A*); // expected-note {{previous declaration}} expected-note 2 {{not viable}} +float& cv(const A*); // expected-error {{cannot be overloaded}} + +int& cv2(void*); +float& cv2(const void*); + +void cv_test(A* a, B* b, const A* ac, const B* bc) { + int &i1 = cv(a); + int &i2 = cv(b); + float &f1 = cv(ac); // expected-error {{no matching function}} + float &f2 = cv(bc); // expected-error {{no matching function}} + int& i3 = cv2(a); + float& f3 = cv2(ac); +} + +// We agree with GCC that these can't be overloaded. +int& qualid(id<P0>); // expected-note {{previous declaration}} expected-note {{not viable}} +float& qualid(id<P1>); // expected-error {{cannot be overloaded}} + +void qualid_test(A *a, B *b, C *c) { + int& i1 = qualid(a); + int& i2 = qualid(b); + + // This doesn't work only because the overload was rejected above. + float& f1 = qualid(c); // expected-error {{no matching function}} + + id<P0> p1 = 0; + p1 = 0; +} + + +@class NSException; +typedef struct { + void (*throw_exc)(id); +} +objc_exception_functions_t; + +void (*_NSExceptionRaiser(void))(NSException *) { + objc_exception_functions_t exc_funcs; + return exc_funcs.throw_exc; // expected-warning{{incompatible pointer types returning 'void (*)(id)' from a function with result type 'void (*)(NSException *)'}} +} + +namespace test5 { + void foo(bool); + void foo(void *); + + void test(id p) { + foo(p); + } +} + +// rdar://problem/8592139 +namespace test6 { + void foo(id); // expected-note{{candidate function}} + void foo(A*) __attribute__((unavailable)); // expected-note {{explicitly made unavailable}} + + void test(B *b) { + foo(b); // expected-error {{call to unavailable function 'foo'}} + } +} + +namespace rdar8714395 { + int &f(const void*); + float &f(const Foo*); + + int &f2(const void*); + float &f2(Foo const* const *); + + int &f3(const void*); + float &f3(Foo const**); + + void g(Foo *p) { + float &fr = f(p); + float &fr2 = f2(&p); + int &ir = f3(&p); + } + + +} + +namespace rdar8734046 { + void f1(id); + void f2(id<P0>); + void g(const A *a) { + f1(a); + f2(a); + } +} + +namespace PR9735 { + int &f3(const A*); + float &f3(const void*); + + void test_f(B* b, const B* bc) { + int &ir1 = f3(b); + int &ir2 = f3(bc); + } +} + +@interface D : B +@end + +namespace rdar9327203 { + int &f(void* const&, int); + float &f(void* const&, long); + + void g(id x) { + int &fr = (f)(x, 0); + } +} + +namespace class_id { + // it's okay to overload Class with id. + void f(Class) { } + void f(id) { } +} diff --git a/clang/test/SemaObjCXX/parameters.mm b/clang/test/SemaObjCXX/parameters.mm new file mode 100644 index 0000000..1a7869d --- /dev/null +++ b/clang/test/SemaObjCXX/parameters.mm @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -verify %s + +@interface A +@end + +template<typename T> +struct X0 { + void f(T); // expected-error{{interface type 'A' cannot be passed by value}} +}; + +X0<A> x0a; // expected-note{{instantiation}} + + +struct test2 { virtual void foo() = 0; }; // expected-note {{unimplemented}} +@interface Test2 +- (void) foo: (test2) foo; // expected-error {{parameter type 'test2' is an abstract class}} +@end diff --git a/clang/test/SemaObjCXX/pointer-to-objc-pointer-conv.mm b/clang/test/SemaObjCXX/pointer-to-objc-pointer-conv.mm new file mode 100644 index 0000000..d0f8404 --- /dev/null +++ b/clang/test/SemaObjCXX/pointer-to-objc-pointer-conv.mm @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface G +@end + +@interface F +- (void)bar:(id *)objects; +- (void)foo:(G**)objects; +@end + + +void a() { + F *b; + G **keys; + [b bar:keys]; + + id *PID; + [b foo:PID]; + +} + + +// pr7936 +@interface I1 @end + +class Wrapper { +public: + operator id() const { return (id)_value; } + operator Class() const { return (Class)_value; } + operator I1*() const { return (I1*)_value; } + + bool Compare(id obj) { return *this == obj; } + bool CompareClass(Class obj) { return *this == obj; } + bool CompareI1(I1* obj) { return *this == obj; } + + Wrapper &operator*(); + Wrapper &operator[](int); + Wrapper& operator->*(int); + +private: + long _value; +}; + +void f() { + Wrapper w; + w[0]; + *w; + w->*(0); +} diff --git a/clang/test/SemaObjCXX/propert-dot-error.mm b/clang/test/SemaObjCXX/propert-dot-error.mm new file mode 100644 index 0000000..2237411 --- /dev/null +++ b/clang/test/SemaObjCXX/propert-dot-error.mm @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar: // 8379892 + +struct X { + X(); + X(const X&); + ~X(); + + static int staticData; + int data; + void method(); +}; + +@interface A { + X xval; +} + +- (X)x; +- (void)setx:(X)x; +@end + +void f(A* a) { + a.x = X(); // expected-error {{no setter method 'setX:' for assignment to property}} +} + +struct Y : X { }; + +@interface B { +@private + Y *y; +} +- (Y)value; +- (void)setValue : (Y) arg; +@property Y value; +@end + +void g(B *b) { + b.value.data = 17; // expected-error {{not assignable}} + b.value.staticData = 17; + b.value.method(); +} + +@interface C +@end + +@implementation C +- (void)method:(B *)b { + // <rdar://problem/8985943> + b.operator+ = 17; // expected-error{{'operator+' is not a valid property name (accessing an object of type 'B *')}} + b->operator+ = 17; // expected-error{{'B' does not have a member named 'operator+'}} +} +@end + +// PR9759 +class Forward; +@interface D { +@public + int ivar; +} + +@property int property; +@end + +void testD(D *d) { + d.Forward::property = 17; // expected-error{{property access cannot be qualified with 'Forward::'}} + d->Forward::ivar = 12; // expected-error{{ivar access cannot be qualified with 'Forward::'}} + d.D::property = 17; // expected-error{{expected a class or namespace}} + d->D::ivar = 12; // expected-error{{expected a class or namespace}} +} diff --git a/clang/test/SemaObjCXX/properties.mm b/clang/test/SemaObjCXX/properties.mm new file mode 100644 index 0000000..3c6b138 --- /dev/null +++ b/clang/test/SemaObjCXX/properties.mm @@ -0,0 +1,108 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wno-objc-root-class %s + +struct X { + void f() const; + ~X(); +}; + +@interface A { + X x_; +} + +- (const X&)x; +- (void)setx:(const X&)other; +@end + +@implementation A + +- (const X&)x { return x_; } +- (void)setx:(const X&)other { x_ = other; } +- (void)method { + self.x.f(); +} +@end + +// rdar://problem/10444030 +@interface Test2 +- (void) setY: (int) y; +- (int) z; +@end +void test2(Test2 *a) { + auto y = a.y; // expected-error {{expected getter method not found on object of type 'Test2 *'}} + auto z = a.z; +} + +// rdar://problem/10672108 +@interface Test3 +- (int) length; +@end +void test3(Test3 *t) { + char vla[t.length] = {}; // expected-error {{variable-sized object may not be initialized}} + char *heaparray = new char[t.length]; +} + +// <rdar://problem/10672501> +namespace std { + template<typename T> void count(); +} + +@interface Test4 +- (X&) prop; +@end + +void test4(Test4 *t) { + (void)const_cast<const X&>(t.prop); + (void)dynamic_cast<X&>(t.prop); + (void)reinterpret_cast<int&>(t.prop); +} + +@interface Test5 { +@public + int count; +} +@property int count; +@end + +void test5(Test5* t5) { + if (t5.count < 2) { } + if (t5->count < 2) { } +} + + +@interface Test6 ++ (Class)class; +- (Class)class; +@end + +void test6(Test6 *t6) { + Class x = t6.class; + Class x2 = Test6.class; +} + +template<typename T> +void test6_template(T *t6) { + Class x = t6.class; +} + +template void test6_template(Test6*); + +// rdar://problem/10965735 +struct Test7PointerMaker { + operator char *() const; +}; +@interface Test7 +- (char*) implicit_property; +- (char) bad_implicit_property; +- (Test7PointerMaker) implicit_struct_property; +@property int *explicit_property; +@property int bad_explicit_property; +@property Test7PointerMaker explicit_struct_property; +@end +void test7(Test7 *ptr) { + delete ptr.implicit_property; + delete ptr.bad_implicit_property; // expected-error {{cannot delete expression of type 'char'}} + delete ptr.explicit_property; + delete ptr.bad_explicit_property; // expected-error {{cannot delete expression of type 'int'}} + delete ptr.implicit_struct_property; + delete ptr.explicit_struct_property; +} diff --git a/clang/test/SemaObjCXX/property-reference.mm b/clang/test/SemaObjCXX/property-reference.mm new file mode 100644 index 0000000..b86ae5e --- /dev/null +++ b/clang/test/SemaObjCXX/property-reference.mm @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://9070460 + +class TCPPObject +{ +public: + TCPPObject(const TCPPObject& inObj); + TCPPObject(); + ~TCPPObject(); + + TCPPObject& operator=(const TCPPObject& inObj)const ; // expected-note {{'operator=' declared here}} + + void* Data(); + +private: + void* fData; +}; + + +typedef const TCPPObject& CREF_TCPPObject; + +@interface TNSObject +@property (assign, readwrite, nonatomic) CREF_TCPPObject cppObjectNonAtomic; +@property (assign, readwrite) CREF_TCPPObject cppObjectAtomic; +@property (assign, readwrite, nonatomic) const TCPPObject& cppObjectDynamic; +@end + + +@implementation TNSObject + +@synthesize cppObjectNonAtomic; +@synthesize cppObjectAtomic; // expected-error{{atomic property of reference type 'CREF_TCPPObject' (aka 'const TCPPObject &') cannot have non-trivial assignment operator}} +@dynamic cppObjectDynamic; + +- (const TCPPObject&) cppObjectNonAtomic +{ + return cppObjectNonAtomic; +} + +- (void) setCppObjectNonAtomic: (const TCPPObject&)cppObject +{ + cppObjectNonAtomic = cppObject; +} +@end + + +// <rdar://problem/11052352> +@interface NSObject ++ alloc; +- init; +- class; +@end + +template<typename T> void f() { + NSObject *o = [NSObject.alloc init]; + [o class]; +} + +template void f<int>(); diff --git a/clang/test/SemaObjCXX/property-synthesis-error.mm b/clang/test/SemaObjCXX/property-synthesis-error.mm new file mode 100644 index 0000000..4b726d8 --- /dev/null +++ b/clang/test/SemaObjCXX/property-synthesis-error.mm @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar: //8550657 + +@interface NSArray @end + +@interface NSMutableArray : NSArray @end + +@interface MyClass +{ + NSMutableArray * _array; +} + +@property (readonly) NSMutableArray * array; + +@end + +@interface MyClass () + +@property (readwrite) NSMutableArray * array; + +@end + +@implementation MyClass + +@synthesize array=_array; + +@end + +int main(void) +{ + return 0; +} + +// rdar://6137845 +class TCPPObject +{ +public: + TCPPObject(const TCPPObject& inObj); + TCPPObject(); + ~TCPPObject(); + TCPPObject& operator=(const TCPPObject& inObj); // expected-note {{'operator=' declared here}} +private: + void* fData; +}; + +class Trivial +{ +public: + Trivial(const Trivial& inObj); + Trivial(); + ~Trivial(); +private: + void* fData; +}; + +@interface MyDocument +{ +@private + TCPPObject _cppObject; + TCPPObject _ncppObject; + Trivial _tcppObject; +} +@property (assign, readwrite) const TCPPObject& cppObject; +@property (assign, readwrite, nonatomic) const TCPPObject& ncppObject; +@property (assign, readwrite) const Trivial& tcppObject; +@end + +@implementation MyDocument + +@synthesize cppObject = _cppObject; // expected-error {{atomic property of reference type 'const TCPPObject &' cannot have non-trivial assignment operator}} +@synthesize ncppObject = _ncppObject; + +@synthesize tcppObject = _tcppObject; +@end diff --git a/clang/test/SemaObjCXX/property-type-mismatch.mm b/clang/test/SemaObjCXX/property-type-mismatch.mm new file mode 100644 index 0000000..059793c --- /dev/null +++ b/clang/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/clang/test/SemaObjCXX/protocol-lookup.mm b/clang/test/SemaObjCXX/protocol-lookup.mm new file mode 100644 index 0000000..bd8444c --- /dev/null +++ b/clang/test/SemaObjCXX/protocol-lookup.mm @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +@protocol NSObject +- retain; +- release; +@end + +@interface NSObject +- init; +- dealloc; +@end + +@protocol Foo <NSObject> +@end + +@protocol Bar <Foo> +@end + +@interface Baz : NSObject { + id <Foo> _foo; + id <Bar> _bar; +} +- (id)initWithFoo:(id <Foo>)foo bar:(id <Bar>)bar; +@end + +@implementation Baz + +- (id)init +{ + return [self initWithFoo:0 bar:0]; +} + +- (id)initWithFoo:(id <Foo>)foo bar:(id <Bar>)bar +{ + self = [super init]; + if (self != 0) { + _foo = [foo retain]; + _bar = [bar retain]; + } + return self; +} + +- dealloc +{ + [_foo release]; + [_bar release]; + [super dealloc]; + return 0; +} + +@end + +void rdar8575095(id a) { + [id<NSObject>(a) retain]; + id<NSObject> x(id<NSObject>(0)); + id<NSObject> x2(id<NSObject>(y)); // expected-warning{{parentheses were disambiguated as a function declarator}} +} diff --git a/clang/test/SemaObjCXX/references.mm b/clang/test/SemaObjCXX/references.mm new file mode 100644 index 0000000..3a52200 --- /dev/null +++ b/clang/test/SemaObjCXX/references.mm @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -verify -emit-llvm -o - %s + +// Test reference binding. + +typedef struct { + int f0; + int f1; +} T; + +@interface A +@property (assign) T p0; +@property (assign) T& p1; +@end + +int f0(const T& t) { + return t.f0; +} + +int f1(A *a) { + return f0(a.p0); +} + +int f2(A *a) { + return f0(a.p1); +} + +// PR7740 +@class NSString; + +void f3(id); +void f4(NSString &tmpstr) { + f3(&tmpstr); +} + +// PR7741 +@protocol P1 @end +@protocol P2 @end +@protocol P3 @end +@interface foo<P1> {} @end +@interface bar : foo <P1, P2, P3> {} @end +typedef bar baz; + +struct ToBar { + operator bar&() const; +}; + +void f5(foo&); +void f5b(foo<P1>&); +void f5c(foo<P2>&); +void f5d(foo<P3>&); +void f6(baz* x) { + f5(*x); + f5b(*x); + f5c(*x); + f5d(*x); + (void)((foo&)*x); + f5(ToBar()); + f5b(ToBar()); + f5c(ToBar()); + f5d(ToBar()); + (void)((foo&)ToBar()); +} diff --git a/clang/test/SemaObjCXX/reinterpret-cast-objc-pointertype.mm b/clang/test/SemaObjCXX/reinterpret-cast-objc-pointertype.mm new file mode 100644 index 0000000..fcabade --- /dev/null +++ b/clang/test/SemaObjCXX/reinterpret-cast-objc-pointertype.mm @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface NSString @end + +typedef const struct __CFString * CFStringRef; +const NSString* fRef; + +CFStringRef func() { + return reinterpret_cast<CFStringRef>(fRef); +} + +CFStringRef fRef1; + +const NSString* func1() { + return reinterpret_cast<const NSString*>(fRef1); +} + +@interface I @end +const I *fRef2; + +const NSString* func2() { + return reinterpret_cast<const NSString*>(fRef2); +} diff --git a/clang/test/SemaObjCXX/related-result-type-inference.mm b/clang/test/SemaObjCXX/related-result-type-inference.mm new file mode 100644 index 0000000..675e6ac --- /dev/null +++ b/clang/test/SemaObjCXX/related-result-type-inference.mm @@ -0,0 +1,71 @@ +// RUN: %clang_cc1 -verify %s + +@interface Unrelated +@end + +@interface NSObject ++ (id)new; ++ (id)alloc; +- (NSObject *)init; + +- (id)retain; // expected-note 2{{instance method 'retain' is assumed to return an instance of its receiver type ('NSArray *')}} +- autorelease; + +- (id)self; + +- (id)copy; +- (id)mutableCopy; + +// Do not infer when instance/class mismatches +- (id)newNotInferred; +- (id)alloc; ++ (id)initWithBlarg; ++ (id)self; + +// Do not infer when the return types mismatch. +- (Unrelated *)initAsUnrelated; +@end + +@interface NSString : NSObject +- (id)init; +- (id)initWithCString:(const char*)string; +@end + +@interface NSArray : NSObject +- (unsigned)count; +@end + +@interface NSBlah +@end + +@interface NSMutableArray : NSArray +@end + +@interface NSBlah () ++ (Unrelated *)newUnrelated; +@end + +void test_inference() { + // Inference based on method family + __typeof__(([[NSString alloc] init])) *str = (NSString**)0; + __typeof__(([[[[NSString new] self] retain] autorelease])) *str2 = (NSString **)0; + __typeof__(([[NSString alloc] initWithCString:"blah"])) *str3 = (NSString**)0; + + // Not inferred + __typeof__(([[NSString new] copy])) *id1 = (id*)0; + + // Not inferred due to instance/class mismatches + __typeof__(([[NSString new] newNotInferred])) *id2 = (id*)0; + __typeof__(([[NSString new] alloc])) *id3 = (id*)0; + __typeof__(([NSString self])) *id4 = (id*)0; + __typeof__(([NSString initWithBlarg])) *id5 = (id*)0; + + // Not inferred due to return type mismatch + __typeof__(([[NSString alloc] initAsUnrelated])) *unrelated = (Unrelated**)0; + __typeof__(([NSBlah newUnrelated])) *unrelated2 = (Unrelated**)0; + + NSArray *arr = [[NSMutableArray alloc] init]; + NSMutableArray *marr = [arr retain]; // expected-warning{{incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *'}} + marr = [arr retain]; // expected-warning{{incompatible pointer types assigning to 'NSMutableArray *' from 'NSArray *'}} + arr = [marr retain]; +} diff --git a/clang/test/SemaObjCXX/reserved-keyword-methods.mm b/clang/test/SemaObjCXX/reserved-keyword-methods.mm new file mode 100644 index 0000000..1302128 --- /dev/null +++ b/clang/test/SemaObjCXX/reserved-keyword-methods.mm @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#define FOR_EACH_KEYWORD(macro) \ +macro(asm) \ +macro(bool) \ +macro(catch) \ +macro(class) \ +macro(const_cast) \ +macro(delete) \ +macro(dynamic_cast) \ +macro(explicit) \ +macro(export) \ +macro(false) \ +macro(friend) \ +macro(mutable) \ +macro(namespace) \ +macro(new) \ +macro(operator) \ +macro(private) \ +macro(protected) \ +macro(public) \ +macro(reinterpret_cast) \ +macro(static_cast) \ +macro(template) \ +macro(this) \ +macro(throw) \ +macro(true) \ +macro(try) \ +macro(typename) \ +macro(typeid) \ +macro(using) \ +macro(virtual) \ +macro(wchar_t) + + +#define DECLARE_METHOD(name) - (void)name; +#define DECLARE_PROPERTY_WITH_GETTER(name) @property (getter=name) int prop_##name; +@interface A +//FOR_EACH_KEYWORD(DECLARE_METHOD) +FOR_EACH_KEYWORD(DECLARE_PROPERTY_WITH_GETTER) +@end + diff --git a/clang/test/SemaObjCXX/standard-conversion-to-bool.mm b/clang/test/SemaObjCXX/standard-conversion-to-bool.mm new file mode 100644 index 0000000..2e69848 --- /dev/null +++ b/clang/test/SemaObjCXX/standard-conversion-to-bool.mm @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@class NSString; +id a; +NSString *b; + +void f() { + bool b1 = a; + bool b2 = b; +} + + diff --git a/clang/test/SemaObjCXX/static-cast.mm b/clang/test/SemaObjCXX/static-cast.mm new file mode 100644 index 0000000..e282702 --- /dev/null +++ b/clang/test/SemaObjCXX/static-cast.mm @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@protocol NSTextViewDelegate; + +@interface NSResponder @end + +class AutoreleaseObject +{ +public: + AutoreleaseObject(); + ~AutoreleaseObject(); + + + AutoreleaseObject& operator=(NSResponder* inValue); + AutoreleaseObject& operator=(const AutoreleaseObject& inValue); + + AutoreleaseObject(const AutoreleaseObject& inValue); + + operator NSResponder*() const; +}; + + +void InvokeSaveFocus() +{ + AutoreleaseObject mResolvedFirstResponder; + id<NSTextViewDelegate> Mydelegate; + mResolvedFirstResponder = static_cast<NSResponder*>(Mydelegate); +} + diff --git a/clang/test/SemaObjCXX/unknown-anytype.mm b/clang/test/SemaObjCXX/unknown-anytype.mm new file mode 100644 index 0000000..b28b135 --- /dev/null +++ b/clang/test/SemaObjCXX/unknown-anytype.mm @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fdebugger-support -funknown-anytype -fsyntax-only -verify %s + +// rdar://problem/9416370 +namespace test0 { + void test(id x) { + if ([x foo]) {} // expected-error {{no known method '-foo'; cast the message send to the method's return type}} + [x foo]; // expected-error {{no known method '-foo'; cast the message send to the method's return type}} + } +} diff --git a/clang/test/SemaObjCXX/vararg-non-pod.mm b/clang/test/SemaObjCXX/vararg-non-pod.mm new file mode 100644 index 0000000..5a6281d --- /dev/null +++ b/clang/test/SemaObjCXX/vararg-non-pod.mm @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-error=non-pod-varargs + +extern char version[]; + +@protocol P; + +class C { +public: + C(int); +}; + +@interface D +- (void)g:(int)a, ...; +@end + +void t1(D *d) +{ + C c(10); + + [d g:10, c]; // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} + [d g:10, version]; +} + +void t2(D *d, id p) +{ + [d g:10, p]; +} + +void t3(D *d, id<P> p) +{ + [d g:10, p]; +} diff --git a/clang/test/SemaObjCXX/vla.mm b/clang/test/SemaObjCXX/vla.mm new file mode 100644 index 0000000..d6da1c0 --- /dev/null +++ b/clang/test/SemaObjCXX/vla.mm @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface Data +- (unsigned)length; +- (void)getData:(void*)buffer; +@end + +void test(Data *d) { + char buffer[[d length]]; + [d getData:buffer]; +} + diff --git a/clang/test/SemaObjCXX/void_to_obj.mm b/clang/test/SemaObjCXX/void_to_obj.mm new file mode 100644 index 0000000..97151fd --- /dev/null +++ b/clang/test/SemaObjCXX/void_to_obj.mm @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +// <rdar://problem/6463729> +@class XX; + +void func() { + XX *obj; + void *vv; + + obj = vv; // expected-error{{assigning to 'XX *' from incompatible type 'void *'}} +} + +// <rdar://problem/7952457> +@interface I +{ + void* delegate; +} +- (I*) Meth; +- (I*) Meth1; +@end + +@implementation I +- (I*) Meth { return static_cast<I*>(delegate); } +- (I*) Meth1 { return reinterpret_cast<I*>(delegate); } +@end + diff --git a/clang/test/SemaObjCXX/warn-strict-selector-match.mm b/clang/test/SemaObjCXX/warn-strict-selector-match.mm new file mode 100644 index 0000000..330b10b --- /dev/null +++ b/clang/test/SemaObjCXX/warn-strict-selector-match.mm @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -Wstrict-selector-match -fsyntax-only -verify %s + +@interface Base +- (id) meth1: (Base *)arg1; // expected-note {{using}} +- (id) window; // expected-note {{using}} +@end + +@interface Derived: Base +- (id) meth1: (Derived *)arg1; // expected-note {{also found}} +- (Base *) window; // expected-note {{also found}} +@end + +void foo(void) { + id r; + + [r meth1:r]; // expected-warning {{multiple methods named 'meth1:' found}} + [r window]; // expected-warning {{multiple methods named 'window' found}} +} |