diff options
Diffstat (limited to 'clang/test/SemaObjC')
365 files changed, 15626 insertions, 0 deletions
diff --git a/clang/test/SemaObjC/ClassPropertyNotObject.m b/clang/test/SemaObjC/ClassPropertyNotObject.m new file mode 100644 index 0000000..02ed40a --- /dev/null +++ b/clang/test/SemaObjC/ClassPropertyNotObject.m @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://10565506 + +@protocol P @end + +@interface I +@property Class<P> MyClass; +@property Class MyClass1; +@property void * VOIDSTAR; +@end + +@implementation I +@synthesize MyClass, MyClass1, VOIDSTAR; +@end diff --git a/clang/test/SemaObjC/ContClassPropertyLookup.m b/clang/test/SemaObjC/ContClassPropertyLookup.m new file mode 100644 index 0000000..06a0ffa --- /dev/null +++ b/clang/test/SemaObjC/ContClassPropertyLookup.m @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface MyObject { + int _foo; +} +@end + +@interface MyObject(whatever) +@property (assign) int foo; +@end + +@interface MyObject() +@property (assign) int foo; +@end + +@implementation MyObject +@synthesize foo = _foo; +@end + +// rdar://10666594 +@interface MPMediaItem +@end + +@class MPMediaItem; + +@interface MPMediaItem () +@property (nonatomic, readonly) id title; +@end + +@interface PodcastEpisodesViewController +@end + +@implementation PodcastEpisodesViewController +- (id) Meth { + MPMediaItem *episode; + return episode.title; +} +@end diff --git a/clang/test/SemaObjC/DoubleMethod.m b/clang/test/SemaObjC/DoubleMethod.m new file mode 100644 index 0000000..4eca4c7 --- /dev/null +++ b/clang/test/SemaObjC/DoubleMethod.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -Wduplicate-method-match -fsyntax-only -verify -Wno-objc-root-class %s + +@interface Subclass +{ + int ivar; +} + +- (void) method; // expected-note {{previous declaration is here}} +- (void) method; // expected-warning {{multiple declarations of method 'method' found and ignored}} +@end + +@implementation Subclass +- (void) method {;} // expected-note {{previous declaration is here}} +- (void) method {;} // expected-error {{duplicate declaration of method 'method'}} +@end + +int main (void) { + return 0; +} diff --git a/clang/test/SemaObjC/Inputs/arc-system-header.h b/clang/test/SemaObjC/Inputs/arc-system-header.h new file mode 100644 index 0000000..5012a2a --- /dev/null +++ b/clang/test/SemaObjC/Inputs/arc-system-header.h @@ -0,0 +1,52 @@ +static inline void *test0(id x) { + return x; +} + +static inline void **test1(__strong id* x) { + return (void**) x; +} + + + + + +struct Test3 { + id *field; +}; + +@interface Test4 { +@public + id *field1; + __strong id *field2; +} +@end + +struct Test5 { + id field; +}; + + + + + + + +extern struct Test6 *const kMagicConstant; + + + + + +@interface Test7 +@property id *prop; +@end + + + + + + + +static inline void *test8(id ptr) { + return (__bridge_retain void*) ptr; +} diff --git a/clang/test/SemaObjC/NSString-type.m b/clang/test/SemaObjC/NSString-type.m new file mode 100644 index 0000000..3b4857a --- /dev/null +++ b/clang/test/SemaObjC/NSString-type.m @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -verify %s +// rdar://10907410 + +void test(id pid, Class pclass) { + void (^block)(void) = @"help"; // expected-error {{initializing 'void (^)(void)' with an expression of incompatible type 'NSString *'}} + void (^block1)(void) = pid; + void (^block2)(void) = @"help"; // expected-error {{initializing 'void (^)(void)' with an expression of incompatible type 'NSString *'}} + void (^block3)(void) = @"help"; // expected-error {{initializing 'void (^)(void)' with an expression of incompatible type 'NSString *'}} +} + diff --git a/clang/test/SemaObjC/access-property-getter.m b/clang/test/SemaObjC/access-property-getter.m new file mode 100644 index 0000000..afaf82e --- /dev/null +++ b/clang/test/SemaObjC/access-property-getter.m @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -verify %s + +@protocol NSObject +- (oneway void)release; +@end + +@protocol XCOutputStreams <NSObject> +@end + + +@interface XCWorkQueueCommandInvocation +{ + id <XCOutputStreams> _outputStream; +} +@end + +@interface XCWorkQueueCommandSubprocessInvocation : XCWorkQueueCommandInvocation +@end + +@interface XCWorkQueueCommandLocalSubprocessInvocation : XCWorkQueueCommandSubprocessInvocation +@end + +@interface XCWorkQueueCommandDistributedSubprocessInvocation : XCWorkQueueCommandSubprocessInvocation +@end + +@interface XCWorkQueueCommandCacheFetchInvocation : XCWorkQueueCommandSubprocessInvocation + +@end + +@implementation XCWorkQueueCommandCacheFetchInvocation +- (id)harvestPredictivelyProcessedOutputFiles +{ + _outputStream.release; // expected-warning {{property access result unused - getters should not be used for side effects}} + return 0; +} +@end diff --git a/clang/test/SemaObjC/alias-test-1.m b/clang/test/SemaObjC/alias-test-1.m new file mode 100644 index 0000000..2cea115 --- /dev/null +++ b/clang/test/SemaObjC/alias-test-1.m @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@compatibility_alias alias4 foo; // expected-warning {{cannot find interface declaration for 'foo'}} + +@class class2; // expected-note {{previous declaration is here}} +@class class3; + +typedef int I; // expected-note {{previous declaration is here}} + +@compatibility_alias alias1 I; // expected-warning {{cannot find interface declaration for 'I'}} + +@compatibility_alias alias class2; +@compatibility_alias alias class3; // expected-error {{conflicting types for alias 'alias'}} + + +typedef int alias2; // expected-note {{previous declaration is here}} +@compatibility_alias alias2 class3; // expected-error {{conflicting types for alias 'alias2'}} + +alias *p; +class2 *p2; + +int foo () +{ + + if (p == p2) { + int alias = 1; + } + + alias *p3; + return p3 == p2; +} diff --git a/clang/test/SemaObjC/alias-test-2.m b/clang/test/SemaObjC/alias-test-2.m new file mode 100644 index 0000000..6688db6 --- /dev/null +++ b/clang/test/SemaObjC/alias-test-2.m @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +// Note: GCC doesn't produce any of the following errors. +@interface Super @end // expected-note {{previous definition is here}} + +@interface MyWpModule @end // expected-note {{previous definition is here}} + +@compatibility_alias MyAlias MyWpModule; + +@compatibility_alias AliasForSuper Super; + +@implementation MyAlias : AliasForSuper // expected-error {{conflicting super class name 'Super'}} +@end + +@interface MyAlias : AliasForSuper // expected-error {{duplicate interface definition for class 'MyWpModule'}} +@end + diff --git a/clang/test/SemaObjC/arc-bridged-cast.m b/clang/test/SemaObjC/arc-bridged-cast.m new file mode 100644 index 0000000..56efe81 --- /dev/null +++ b/clang/test/SemaObjC/arc-bridged-cast.m @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -verify %s + +typedef const void *CFTypeRef; +CFTypeRef CFBridgingRetain(id X); +id CFBridgingRelease(CFTypeRef); +typedef const struct __CFString *CFStringRef; + +@interface NSString +@end + +CFTypeRef CFCreateSomething(); +CFStringRef CFCreateString(); +CFTypeRef CFGetSomething(); +CFStringRef CFGetString(); + +id CreateSomething(); +NSString *CreateNSString(); + +void from_cf() { + id obj1 = (__bridge_transfer id)CFCreateSomething(); + id obj2 = (__bridge_transfer NSString*)CFCreateString(); + (__bridge int*)CFCreateSomething(); // expected-error{{incompatible types casting 'CFTypeRef' (aka 'const void *') to 'int *' with a __bridge cast}} + id obj3 = (__bridge id)CFGetSomething(); + id obj4 = (__bridge NSString*)CFGetString(); +} + +void to_cf(id obj) { + CFTypeRef cf1 = (__bridge_retained CFTypeRef)CreateSomething(); + CFStringRef cf2 = (__bridge_retained CFStringRef)CreateNSString(); + CFTypeRef cf3 = (__bridge CFTypeRef)CreateSomething(); + CFStringRef cf4 = (__bridge CFStringRef)CreateNSString(); + + // rdar://problem/9629566 - temporary workaround + CFTypeRef cf5 = (__bridge_retain CFTypeRef)CreateSomething(); // expected-error {{unknown cast annotation __bridge_retain; did you mean __bridge_retained?}} +} + +void fixits() { + id obj1 = (id)CFCreateSomething(); // expected-error{{cast of C pointer type 'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'id' requires a bridged cast}} \ + // expected-note{{use __bridge to convert directly (no change in ownership)}} \ + // expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}} + CFTypeRef cf1 = (CFTypeRef)CreateSomething(); // expected-error{{cast of Objective-C pointer type 'id' to C pointer type 'CFTypeRef' (aka 'const void *') requires a bridged cast}} \ + // expected-note{{use __bridge to convert directly (no change in ownership)}} \ + // expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFTypeRef' (aka 'const void *')}} +} diff --git a/clang/test/SemaObjC/arc-cf.m b/clang/test/SemaObjC/arc-cf.m new file mode 100644 index 0000000..69662ea --- /dev/null +++ b/clang/test/SemaObjC/arc-cf.m @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -verify %s + +#if __has_feature(arc_cf_code_audited) +char _global[-1]; // expected-error {{declared as an array with a negative size}} +#endif + +typedef const void *CFTypeRef; +CFTypeRef CFBridgingRetain(id X); +id CFBridgingRelease(CFTypeRef); +typedef const struct __CFString *CFStringRef; + +extern CFStringRef CFMakeString0(void); +extern CFStringRef CFCreateString0(void); +void test0() { + id x; + x = (id) CFMakeString0(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}} + x = (id) CFCreateString0(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}} +} + +extern CFStringRef CFMakeString1(void) __attribute__((cf_returns_not_retained)); +extern CFStringRef CFCreateString1(void) __attribute__((cf_returns_retained)); +void test1() { + id x; + x = (id) CFMakeString1(); + x = (id) CFCreateString1(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}} +} + +#define CF_AUDIT_BEGIN _Pragma("clang arc_cf_code_audited begin") +#define CF_AUDIT_END _Pragma("clang arc_cf_code_audited end") +#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) +#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) + +CF_AUDIT_BEGIN +extern CFStringRef CFMakeString2(void); +extern CFStringRef CFCreateString2(void) CF_RETURNS_NOT_RETAINED; +extern CFStringRef CFMakeString3(void) CF_RETURNS_RETAINED; +extern CFStringRef CFCreateString3(void); +CF_AUDIT_END +void test2() { + id x; + x = (id) CFMakeString2(); + x = (id) CFCreateString2(); + x = (id) CFMakeString3(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}} + x = (id) CFCreateString3(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}} +} diff --git a/clang/test/SemaObjC/arc-decls.m b/clang/test/SemaObjC/arc-decls.m new file mode 100644 index 0000000..8d5cca2 --- /dev/null +++ b/clang/test/SemaObjC/arc-decls.m @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -fsyntax-only -fblocks -fobjc-arc -verify -Wno-objc-root-class %s + +// rdar://8843524 + +struct A { + id x; // expected-error {{ARC forbids Objective-C objects in structs or unions}} +}; + +union u { + id u; // expected-error {{ARC forbids Objective-C objects in structs or unions}} +}; + +@interface I { + struct A a; + struct B { + id y[10][20]; // expected-error {{ARC forbids Objective-C objects in structs or unions}} + id z; + } b; + + union u c; +}; +@end + +// rdar://10260525 +struct r10260525 { + id (^block) (); // expected-error {{ARC forbids blocks in structs or unions}} +}; + +struct S { + id __attribute__((objc_ownership(none))) i; + void * vp; + int i1; +}; + +// rdar://9046528 + +@class NSError; + +__autoreleasing id X; // expected-error {{global variables cannot have __autoreleasing ownership}} +__autoreleasing NSError *E; // expected-error {{global variables cannot have __autoreleasing ownership}} + + +extern id __autoreleasing X1; // expected-error {{global variables cannot have __autoreleasing ownership}} + +void func() +{ + id X; + static id __autoreleasing X1; // expected-error {{global variables cannot have __autoreleasing ownership}} + extern id __autoreleasing E; // expected-error {{global variables cannot have __autoreleasing ownership}} + +} + +// rdar://9157348 + +@interface J +@property (retain) id newFoo; // expected-note {{property declared here}} +@property (strong) id copyBar; // expected-note {{property declared here}} +@property (copy) id allocBaz; // expected-note {{property declared here}} +@property (copy, nonatomic) id new; +@end + +@implementation J +@synthesize newFoo; // expected-error {{property's synthesized getter follows Cocoa naming convention for returning}} +@synthesize copyBar; // expected-error {{property's synthesized getter follows Cocoa naming convention for returning}} +@synthesize allocBaz; // expected-error {{property's synthesized getter follows Cocoa naming convention for returning}} +@synthesize new; +- new {return 0; }; +@end + + +// rdar://10187884 +@interface Super +- (void)bar:(id)b; // expected-note {{parameter declared here}} +- (void)bar1:(id) __attribute((ns_consumed)) b; +- (void)ok:(id) __attribute((ns_consumed)) b; +- (id)ns_non; // expected-note {{method declared here}} +- (id)not_ret:(id) b __attribute((ns_returns_not_retained)); // expected-note {{method declared here}} +- (id)both__returns_not_retained:(id) b __attribute((ns_returns_not_retained)); +@end + +@interface Sub : Super +- (void)bar:(id) __attribute((ns_consumed)) b; // expected-error {{overriding method has mismatched ns_consumed attribute on its parameter}} +- (void)bar1:(id)b; +- (void)ok:(id) __attribute((ns_consumed)) b; +- (id)ns_non __attribute((ns_returns_not_retained)); // expected-error {{overriding method has mismatched ns_returns_not_retained attributes}} +- (id)not_ret:(id) b __attribute((ns_returns_retained)); // expected-error {{overriding method has mismatched ns_returns_retained attributes}} +- (id)both__returns_not_retained:(id) b __attribute((ns_returns_not_retained)); +@end + +// Test that we give a good diagnostic here that mentions the missing +// ownership qualifier. We don't want this to get suppressed because +// of an invalid conversion. +void test7(void) { + id x; + id *px = &x; // expected-error {{pointer to non-const type 'id' with no explicit ownership}} + + I *y; + J **py = &y; // expected-error {{pointer to non-const type 'J *' with no explicit ownership}} expected-warning {{incompatible pointer types initializing}} +} diff --git a/clang/test/SemaObjC/arc-invalid.m b/clang/test/SemaObjC/arc-invalid.m new file mode 100644 index 0000000..c736ed4 --- /dev/null +++ b/clang/test/SemaObjC/arc-invalid.m @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fblocks -verify %s + +// rdar://problem/10982793 +// [p foo] in ARC creates a cleanup. +// The plus is invalid and causes the cleanup to go unbound. +// Don't crash. +@interface A +- (id) foo; +@end +void takeBlock(void (^)(void)); +void test0(id p) { + takeBlock(^{ [p foo] + p; }); // expected-error {{invalid operands to binary expression}} +} + +void test1(void) { + __autoreleasing id p; // expected-note {{'p' declared here}} + takeBlock(^{ (void) p; }); // expected-error {{cannot capture __autoreleasing variable in a block}} +} diff --git a/clang/test/SemaObjC/arc-jump-block.m b/clang/test/SemaObjC/arc-jump-block.m new file mode 100644 index 0000000..26a1fc8 --- /dev/null +++ b/clang/test/SemaObjC/arc-jump-block.m @@ -0,0 +1,97 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class %s +// rdar://9535237 + +typedef struct dispatch_queue_s *dispatch_queue_t; + +typedef void (^dispatch_block_t)(void); + +void dispatch_async(dispatch_queue_t queue, dispatch_block_t block); + +extern __attribute__((visibility("default"))) struct dispatch_queue_s _dispatch_main_q; + +@interface SwitchBlockCrashAppDelegate +- (void)pageLeft; +- (void)pageRight;; +@end + +@implementation SwitchBlockCrashAppDelegate + +- (void)choose:(int)button { + switch (button) { + case 0: + dispatch_async((&_dispatch_main_q), ^{ [self pageLeft]; }); // expected-note 3 {{jump enters lifetime of block which strongly captures a variable}} + break; + case 2: // expected-error {{switch case is in protected scope}} + dispatch_async((&_dispatch_main_q), ^{ [self pageRight]; }); // expected-note 2 {{jump enters lifetime of block which strongly captures a variable}} + break; + case 3: // expected-error {{switch case is in protected scope}} + { + dispatch_async((&_dispatch_main_q), ^{ [self pageRight]; }); + break; + } + case 4: // expected-error {{switch case is in protected scope}} + break; + } + + __block SwitchBlockCrashAppDelegate *captured_block_obj; + switch (button) { + case 10: + { + dispatch_async((&_dispatch_main_q), ^{ [self pageLeft]; }); + break; + } + case 12: + if (button) + dispatch_async((&_dispatch_main_q), ^{ [captured_block_obj pageRight]; }); + break; + case 13: + while (button) + dispatch_async((&_dispatch_main_q), ^{ [self pageRight]; }); + break; + case 14: + break; + } + + switch (button) { + case 10: + { + dispatch_async((&_dispatch_main_q), ^{ [self pageLeft]; }); + break; + } + case 12: + if (button) + dispatch_async((&_dispatch_main_q), ^{ [self pageRight]; }); + switch (button) { + case 0: + { + dispatch_async((&_dispatch_main_q), ^{ [self pageLeft]; }); + break; + } + case 4: + break; + } + break; + case 13: + while (button) + dispatch_async((&_dispatch_main_q), ^{ [self pageRight]; }); + break; + case 14: + break; + } +} +- (void)pageLeft {} +- (void)pageRight {} +@end + +// Test 2. rdar://problem/11150919 +int test2(id obj, int state) { // expected-note {{jump enters lifetime of block}} FIXME: wierd location + switch (state) { + case 0: + (void) ^{ (void) obj; }; + return 0; + + default: // expected-error {{switch case is in protected scope}} + return 1; + } +} + diff --git a/clang/test/SemaObjC/arc-no-runtime.m b/clang/test/SemaObjC/arc-no-runtime.m new file mode 100644 index 0000000..b75064f --- /dev/null +++ b/clang/test/SemaObjC/arc-no-runtime.m @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fobjc-arc -verify -Wno-objc-root-class %s + +// rdar://problem/9150784 +void test(void) { + __weak id x; // expected-error {{the current deployment target does not support automated __weak references}} + __weak void *v; // expected-warning {{'__weak' only applies to objective-c object or block pointer types}} +} + +@interface A +@property (weak) id testObjectWeakProperty; // expected-note {{declared here}} +@end + +@implementation A +// rdar://9605088 +@synthesize testObjectWeakProperty; // expected-error {{the current deployment target does not support automated __weak references}} +@end diff --git a/clang/test/SemaObjC/arc-non-pod-memaccess.m b/clang/test/SemaObjC/arc-non-pod-memaccess.m new file mode 100644 index 0000000..2b1223a --- /dev/null +++ b/clang/test/SemaObjC/arc-non-pod-memaccess.m @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -fblocks -triple x86_64-apple-darwin10.0.0 %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -fblocks -triple x86_64-apple-darwin10.0.0 %s + +#ifdef __cplusplus +extern "C" { +#endif + +void *memset(void *, int, __SIZE_TYPE__); +void *memmove(void *s1, const void *s2, __SIZE_TYPE__ n); +void *memcpy(void *s1, const void *s2, __SIZE_TYPE__ n); + +#ifdef __cplusplus +} +#endif + +void test(id __strong *sip, id __weak *wip, id __autoreleasing *aip, + id __unsafe_unretained *uip, void *ptr) { + // All okay. + memset(sip, 0, 17); + memset(wip, 0, 17); + memset(aip, 0, 17); + memset(uip, 0, 17); + + memcpy(sip, ptr, 17); // expected-warning{{destination for this 'memcpy' call is a pointer to ownership-qualified type}} \ + // expected-note{{explicitly cast the pointer to silence this warning}} + memcpy(wip, ptr, 17); // expected-warning{{destination for this 'memcpy' call is a pointer to ownership-qualified type}} \ + // expected-note{{explicitly cast the pointer to silence this warning}} + memcpy(aip, ptr, 17); // expected-warning{{destination for this 'memcpy' call is a pointer to ownership-qualified type}} \ + // expected-note{{explicitly cast the pointer to silence this warning}} + memcpy(uip, ptr, 17); + + memcpy(ptr, sip, 17); // expected-warning{{source of this 'memcpy' call is a pointer to ownership-qualified type}} \ + // expected-note{{explicitly cast the pointer to silence this warning}} + memcpy(ptr, wip, 17); // expected-warning{{source of this 'memcpy' call is a pointer to ownership-qualified type}} \ + // expected-note{{explicitly cast the pointer to silence this warning}} + memcpy(ptr, aip, 17); // expected-warning{{source of this 'memcpy' call is a pointer to ownership-qualified type}} \ + // expected-note{{explicitly cast the pointer to silence this warning}} + memcpy(ptr, uip, 17); + + memmove(sip, ptr, 17); // expected-warning{{destination for this 'memmove' call is a pointer to ownership-qualified type}} \ + // expected-note{{explicitly cast the pointer to silence this warning}} + memmove(wip, ptr, 17); // expected-warning{{destination for this 'memmove' call is a pointer to ownership-qualified type}} \ + // expected-note{{explicitly cast the pointer to silence this warning}} + memmove(aip, ptr, 17); // expected-warning{{destination for this 'memmove' call is a pointer to ownership-qualified type}} \ + // expected-note{{explicitly cast the pointer to silence this warning}} + memmove(uip, ptr, 17); + + memmove(ptr, sip, 17); // expected-warning{{source of this 'memmove' call is a pointer to ownership-qualified type}} \ + // expected-note{{explicitly cast the pointer to silence this warning}} + memmove(ptr, wip, 17); // expected-warning{{source of this 'memmove' call is a pointer to ownership-qualified type}} \ + // expected-note{{explicitly cast the pointer to silence this warning}} + memmove(ptr, aip, 17); // expected-warning{{source of this 'memmove' call is a pointer to ownership-qualified type}} \ + // expected-note{{explicitly cast the pointer to silence this warning}} + memmove(ptr, uip, 17); +} + +void rdar9772982(int i, ...) { + __builtin_va_list ap; + + __builtin_va_start(ap, i); + __builtin_va_arg(ap, __strong id); // expected-error{{second argument to 'va_arg' is of ARC ownership-qualified type '__strong id'}} + __builtin_va_end(ap); +} diff --git a/clang/test/SemaObjC/arc-nsconsumed-errors.m b/clang/test/SemaObjC/arc-nsconsumed-errors.m new file mode 100644 index 0000000..62e74aa --- /dev/null +++ b/clang/test/SemaObjC/arc-nsconsumed-errors.m @@ -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 arg1, __attribute((ns_consumed)) id arg2); +typedef void (^blk1)(__attribute((ns_consumed))id arg1, __attribute((ns_consumed)) id arg2); +blk a = ^void (__attribute((ns_consumed)) id arg1, __attribute((ns_consumed)) id arg2){}; // expected-error {{incompatible block pointer types initializing}} + +blk b = ^void (id arg1, __attribute((ns_consumed)) id arg2){}; + +blk c = ^void (__attribute((ns_consumed)) id arg1, __attribute((ns_consumed)) id arg2){}; // expected-error {{incompatible block pointer types initializing}} + +blk d = ^void (id arg1, id arg2) {}; // expected-error {{incompatible block pointer types initializing}} + +blk1 a1 = ^void (__attribute((ns_consumed)) id arg1, id arg2){}; // expected-error {{incompatible block pointer types initializing}} + +blk1 b2 = ^void (id arg1, __attribute((ns_consumed)) id arg2){}; // expected-error {{incompatible block pointer types initializing}} + +blk1 c3 = ^void (__attribute((ns_consumed)) id arg1, __attribute((ns_consumed)) id arg2){}; + +blk1 d4 = ^void (id arg1, id arg2) {}; // expected-error {{incompatible block pointer types initializing}} diff --git a/clang/test/SemaObjC/arc-objc-lifetime.m b/clang/test/SemaObjC/arc-objc-lifetime.m new file mode 100644 index 0000000..03260e8 --- /dev/null +++ b/clang/test/SemaObjC/arc-objc-lifetime.m @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s +// rdar://10244607 + +typedef const struct __CFString * CFStringRef; +@class NSString; + +NSString *CFBridgingRelease(); + +typedef NSString * PNSString; + +typedef __autoreleasing NSString * AUTORELEASEPNSString; + +@interface I @end + +@implementation I +- (CFStringRef)myString +{ + CFStringRef myString = + (__bridge CFStringRef) (__strong NSString *)CFBridgingRelease(); // expected-error {{explicit ownership qualifier on cast result has no effect}} + + myString = + (__bridge CFStringRef) (__autoreleasing PNSString) CFBridgingRelease(); // expected-error {{explicit ownership qualifier on cast result has no effect}} + myString = + (__bridge CFStringRef) (AUTORELEASEPNSString) CFBridgingRelease(); // OK + myString = + (__bridge CFStringRef) (typeof(__strong NSString *)) CFBridgingRelease(); // expected-error {{explicit ownership qualifier on cast result has no effect}} + return myString; +} + +- (void)decodeValueOfObjCType:(const char *)type at:(void *)addr { + __autoreleasing id *stuff = (__autoreleasing id *)addr; +} +@end + +// rdar://problem/10711456 +__strong I *__strong test1; // expected-error {{the type 'I *__strong' is already explicitly ownership-qualified}} +__strong I *(__strong test2); // expected-error {{the type 'I *__strong' is already explicitly ownership-qualified}} +__strong I *(__strong (test3)); // expected-error {{the type 'I *__strong' is already explicitly ownership-qualified}} +__unsafe_unretained __typeof__(test3) test4; +typedef __strong I *strong_I; +__unsafe_unretained strong_I test5; diff --git a/clang/test/SemaObjC/arc-peformselector.m b/clang/test/SemaObjC/arc-peformselector.m new file mode 100644 index 0000000..dec09e3 --- /dev/null +++ b/clang/test/SemaObjC/arc-peformselector.m @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify %s +// rdar://9659270 + +@interface NSObject +- (id)copy; // expected-note {{method 'copy' declared here}} +- (id) test __attribute__((ns_returns_retained)); // expected-note {{method 'test' declared here}} ++ (id) new ; // expected-note {{method 'new' declared here}} +- (id) init __attribute__((ns_returns_not_retained)); +- (id)PlusZero; +- (id)PlusOne __attribute__((ns_returns_retained)); // expected-note {{method 'PlusOne' declared here}} +@end + +@interface I : NSObject +{ + SEL sel1; +} +- (id)performSelector:(SEL)aSelector; +- (id)performSelector:(SEL)aSelector withObject:(id)object; +- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2; +@end + +@implementation I +- (id) Meth { + return [self performSelector : @selector(copy)]; // expected-error {{performSelector names a selector which retains the object}} + return [self performSelector : @selector(test)]; // expected-error {{performSelector names a selector which retains the object}} + return [self performSelector : @selector(new)]; // expected-error {{performSelector names a selector which retains the object}} + return [self performSelector : @selector(init)]; + return [self performSelector : sel1]; // expected-warning {{performSelector may cause a leak because its selector is unknown}} \ + // expected-note {{used here}} + + return [self performSelector : @selector(PlusZero)]; + return [self performSelector : @selector(PlusOne)]; // expected-error {{performSelector names a selector which retains the object}} +} + +- (id)performSelector:(SEL)aSelector { return 0; } +- (id)performSelector:(SEL)aSelector withObject:(id)object { return 0; } +- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2 { return 0; } +@end diff --git a/clang/test/SemaObjC/arc-property-decl-attrs.m b/clang/test/SemaObjC/arc-property-decl-attrs.m new file mode 100644 index 0000000..1386241 --- /dev/null +++ b/clang/test/SemaObjC/arc-property-decl-attrs.m @@ -0,0 +1,81 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify %s +// rdar://9340606 + +@interface Foo { +@public + id __unsafe_unretained x; + id __weak y; + id __autoreleasing z; // expected-error {{ivars cannot have __autoreleasing ownership}} +} +@property(strong) id x; +@property(strong) id y; +@property(strong) id z; +@end + +@interface Bar { +@public + id __unsafe_unretained x; + id __weak y; + id __autoreleasing z; // expected-error {{ivars cannot have __autoreleasing ownership}} +} +@property(retain) id x; +@property(retain) id y; +@property(retain) id z; +@end + +@interface Bas { +@public + id __unsafe_unretained x; + id __weak y; + id __autoreleasing z; // expected-error {{ivars cannot have __autoreleasing ownership}} +} +@property(copy) id x; +@property(copy) id y; +@property(copy) id z; +@end + +// Errors should start about here :-) + +@interface Bat +@property(strong) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}} +@property(strong) __weak id y; // expected-error {{strong property 'y' may not also be declared __weak}} expected-error {{property attributes 'strong' and 'weak' are mutually exclusive}} +@property(strong) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}} +@end + +@interface Bau +@property(retain) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}} +@property(retain) __weak id y; // expected-error {{strong property 'y' may not also be declared __weak}} expected-error {{property attributes 'retain' and 'weak' are mutually exclusive}} +@property(retain) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}} +@end + +@interface Bav +@property(copy) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}} +@property(copy) __weak id y; // expected-error {{strong property 'y' may not also be declared __weak}} expected-error {{property attributes 'copy' and 'weak' are mutually exclusive}} +@property(copy) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}} +@end + +@interface Bingo +@property(assign) __unsafe_unretained id x; +@property(assign) __weak id y; // expected-error {{property attributes 'assign' and 'weak' are mutually exclusive}} +@property(assign) __autoreleasing id z; // expected-error {{unsafe_unretained property 'z' may not also be declared __autoreleasing}} +@end + +@interface Batman +@property(unsafe_unretained) __unsafe_unretained id x; +@property(unsafe_unretained) __weak id y; // expected-error {{property attributes 'unsafe_unretained' and 'weak' are mutually exclusive}} +@property(unsafe_unretained) __autoreleasing id z; // expected-error {{unsafe_unretained property 'z' may not also be declared __autoreleasing}} +@end + +// rdar://9396329 +@interface Super +@property (readonly, retain) id foo; +@property (readonly, weak) id fee; +@property (readonly, strong) id frr; +@end + +@interface Bugg : Super +@property (readwrite) id foo; +@property (readwrite) id fee; +@property (readwrite) id frr; +@end + diff --git a/clang/test/SemaObjC/arc-property-lifetime.m b/clang/test/SemaObjC/arc-property-lifetime.m new file mode 100644 index 0000000..fad37cc --- /dev/null +++ b/clang/test/SemaObjC/arc-property-lifetime.m @@ -0,0 +1,170 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s +// rdar://9340606 + +@interface Foo { +@public + id __unsafe_unretained x; + id __weak y; + id __autoreleasing z; // expected-error {{ivars cannot have __autoreleasing ownership}} +} +@property(strong) id x; // expected-note {{property declared here}} +@property(strong) id y; // expected-note {{property declared here}} +@property(strong) id z; +@end + +@implementation Foo +@synthesize x; // expected-error {{existing ivar 'x' for strong property 'x' may not be __unsafe_unretained}} +@synthesize y; // expected-error {{existing ivar 'y' for strong property 'y' may not be __weak}} +@synthesize z; // suppressed +@end + +@interface Bar { +@public + id __unsafe_unretained x; + id __weak y; + id __autoreleasing z; // expected-error {{ivars cannot have __autoreleasing ownership}} +} +@property(retain) id x; // expected-note {{property declared here}} +@property(retain) id y; // expected-note {{property declared here}} +@property(retain) id z; +@end + +@implementation Bar +@synthesize x; // expected-error {{existing ivar 'x' for strong property 'x' may not be __unsafe_unretained}} +@synthesize y; // expected-error {{existing ivar 'y' for strong property 'y' may not be __weak}} +@synthesize z; // suppressed +@end + +@interface Bas { +@public + id __unsafe_unretained x; + id __weak y; + id __autoreleasing z; // expected-error {{ivars cannot have __autoreleasing ownership}} +} +@property(copy) id x; // expected-note {{property declared here}} +@property(copy) id y; // expected-note {{property declared here}} +@property(copy) id z; +@end + +@implementation Bas +@synthesize x; // expected-error {{existing ivar 'x' for strong property 'x' may not be __unsafe_unretained}} +@synthesize y; // expected-error {{existing ivar 'y' for strong property 'y' may not be __weak}} +@synthesize z; // suppressed +@end + +@interface Bat +@property(strong) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}} +@property(strong) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}} +@end + +@interface Bau +@property(retain) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}} +@property(retain) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}} +@end + +@interface Bav +@property(copy) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}} +@property(copy) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}} +@end + +// rdar://9341593 +@interface Gorf { + id __unsafe_unretained x; + id y; +} +@property(assign) id __unsafe_unretained x; +@property(assign) id y; // expected-note {{property declared here}} +@property(assign) id z; +@end + +@implementation Gorf +@synthesize x; +@synthesize y; // expected-error {{existing ivar 'y' for property 'y' with assign attribute must be __unsafe_unretained}} +@synthesize z; +@end + +@interface Gorf2 { + id __unsafe_unretained x; + id y; +} +@property(unsafe_unretained) id __unsafe_unretained x; +@property(unsafe_unretained) id y; // expected-note {{property declared here}} +@property(unsafe_unretained) id z; +@end + +@implementation Gorf2 +@synthesize x; +@synthesize y; // expected-error {{existing ivar 'y' for property 'y' with unsafe_unretained attribute must be __unsafe_unretained}} +@synthesize z; +@end + +// rdar://9355230 +@interface I { + char _isAutosaving; +} +@property char isAutosaving; + +@end + +@implementation I +@synthesize isAutosaving = _isAutosaving; +@end + +// rdar://10239594 +// Test for 'Class' properties being unretained. +@interface MyClass { +@private + Class _controllerClass; + id _controllerId; +} +@property (copy) Class controllerClass; +@property (copy) id controllerId; +@end + +@implementation MyClass +@synthesize controllerClass = _controllerClass; +@synthesize controllerId = _controllerId; +@end + +// rdar://10630891 +@interface UIView @end +@class UIColor; + +@interface UIView(UIViewRendering) +@property(nonatomic,copy) UIColor *backgroundColor; +@end + +@interface UILabel : UIView +@end + +@interface MyView +@property (strong) UILabel *label; +@end + +@interface MyView2 : MyView @end + +@implementation MyView2 +- (void)foo { + super.label.backgroundColor = 0; +} +@end + +// rdar://10694932 +@interface Baz +@property id prop; +@property __strong id strong_prop; +@property (strong) id strong_attr_prop; +@property (strong) __strong id realy_strong_attr_prop; ++ (id) alloc; +- (id) init; +- (id) implicit; +- (void) setImplicit : (id) arg; +@end + +void foo(Baz *f) { + f.prop = [[Baz alloc] init]; + f.strong_prop = [[Baz alloc] init]; + f.strong_attr_prop = [[Baz alloc] init]; + f.realy_strong_attr_prop = [[Baz alloc] init]; + f.implicit = [[Baz alloc] init]; +} diff --git a/clang/test/SemaObjC/arc-property.m b/clang/test/SemaObjC/arc-property.m new file mode 100644 index 0000000..2599fb9 --- /dev/null +++ b/clang/test/SemaObjC/arc-property.m @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class %s +// rdar://9309489 + +@interface MyClass { + id __weak myString; + id StrongIvar; + id __weak myString2; + id __weak myString3; + id StrongIvar5; +} +@property (strong) id myString; // expected-note {{property declared here}} +@property (strong) id myString1; +@property (retain) id myString2; // expected-note {{property declared here}} +// +@property (weak) id myString3; +@property (weak) id myString4; +@property __weak id myString5; // expected-note {{property declared here}} +@end + +@implementation MyClass +@synthesize myString; // expected-error {{existing ivar 'myString' for strong property 'myString' may not be __weak}} +@synthesize myString1 = StrongIvar; // OK +@synthesize myString2 = myString2; // expected-error {{existing ivar 'myString2' for strong property 'myString2' may not be __weak}} +// +@synthesize myString3; // OK +@synthesize myString4; // OK +@synthesize myString5 = StrongIvar5; // expected-error {{existing ivar 'StrongIvar5' for __weak property 'myString5' must be __weak}} + +@end + +// rdar://9340692 +@interface Foo { +@public + id __unsafe_unretained x; // should be __weak + id __strong y; + id __autoreleasing z; // expected-error {{ivars cannot have __autoreleasing ownership}} +} +@property(weak) id x; // expected-note {{property declared here}} +@property(weak) id y; // expected-note {{property declared here}} +@property(weak) id z; +@end + +@implementation Foo +@synthesize x; // expected-error {{existing ivar 'x' for __weak property 'x' must be __weak}} +@synthesize y; // expected-error {{existing ivar 'y' for __weak property 'y' must be __weak}} +@synthesize z; // suppressed +@end + +// rdar://problem/10904479 +// Don't crash. +@interface Test2 +// Minor FIXME: kill the redundant error +@property (strong) UndeclaredClass *test2; // expected-error {{unknown type name 'UndeclaredClass'}} expected-error {{must be of object type}} +@end +@implementation Test2 +@synthesize test2; +@end diff --git a/clang/test/SemaObjC/arc-readonly-property-ivar-1.m b/clang/test/SemaObjC/arc-readonly-property-ivar-1.m new file mode 100644 index 0000000..c773f26 --- /dev/null +++ b/clang/test/SemaObjC/arc-readonly-property-ivar-1.m @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -fobjc-default-synthesize-properties -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fobjc-arc -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -fobjc-default-synthesize-properties -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fobjc-arc -fsyntax-only -verify -Wno-objc-root-class %s +// rdar:// 10558871 + +@interface PP +@property (readonly) id ReadOnlyPropertyNoBackingIvar; +@property (readonly) id ReadOnlyProperty; +@property (readonly) id ReadOnlyPropertyX; +@end + +@implementation PP { +__weak id _ReadOnlyProperty; +} +@synthesize ReadOnlyPropertyNoBackingIvar; +@synthesize ReadOnlyProperty = _ReadOnlyProperty; +@synthesize ReadOnlyPropertyX = _ReadOnlyPropertyX; +@end + +@interface DD +@property (readonly) id ReadOnlyProperty; +@property (readonly) id ReadOnlyPropertyStrong; +@property (readonly) id ReadOnlyPropertyNoBackingIvar; +@end + +@implementation DD { +__weak id _ReadOnlyProperty; +__strong id _ReadOnlyPropertyStrong; +} +@end diff --git a/clang/test/SemaObjC/arc-readonly-property-ivar.m b/clang/test/SemaObjC/arc-readonly-property-ivar.m new file mode 100644 index 0000000..635b9fe --- /dev/null +++ b/clang/test/SemaObjC/arc-readonly-property-ivar.m @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fobjc-arc -fsyntax-only -verify -Wno-objc-root-class %s +// rdar:// 10558871 + +@interface PP +@property (readonly) id ReadOnlyPropertyNoBackingIvar; +@property (readonly) id ReadOnlyProperty; +@property (readonly) id ReadOnlyPropertyX; +@end + +@implementation PP { +__weak id _ReadOnlyProperty; +} +@synthesize ReadOnlyPropertyNoBackingIvar; +@synthesize ReadOnlyProperty = _ReadOnlyProperty; +@synthesize ReadOnlyPropertyX = _ReadOnlyPropertyX; +@end diff --git a/clang/test/SemaObjC/arc-retain-block-property.m b/clang/test/SemaObjC/arc-retain-block-property.m new file mode 100644 index 0000000..3b66d14 --- /dev/null +++ b/clang/test/SemaObjC/arc-retain-block-property.m @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -fblocks -fobjc-arc -verify -Wno-objc-root-class %s +// rdar://9829425 + +extern void doSomething(); + +@interface Test +{ +@public + void (^aBlock)(void); +} +@property (retain) void (^aBlock)(void); // expected-warning {{retain'ed block property does not copy the block - use copy attribute instead}} +@property (weak, retain) void (^aBlockW)(void); // expected-error {{property attributes 'retain' and 'weak' are mutually exclusive}} +@property (strong, retain) void (^aBlockS)(void); // OK +@property (readonly, retain) void (^aBlockR)(void); // OK +@property (copy, retain) void (^aBlockC)(void); // expected-error {{property attributes 'copy' and 'retain' are mutually exclusive}} +@property (assign, retain) void (^aBlockA)(void); // expected-error {{property attributes 'assign' and 'retain' are mutually exclusive}} +@end + +@implementation Test +@synthesize aBlock; +@dynamic aBlockW, aBlockS, aBlockR, aBlockC, aBlockA; +@end + +int main() { + Test *t; + t.aBlock = ^{ doSomething(); }; + t.aBlockW = ^{ doSomething(); }; + t.aBlockS = ^{ doSomething(); }; +} + diff --git a/clang/test/SemaObjC/arc-setter-property-match.m b/clang/test/SemaObjC/arc-setter-property-match.m new file mode 100644 index 0000000..9158b09 --- /dev/null +++ b/clang/test/SemaObjC/arc-setter-property-match.m @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class %s +// rdar://10156674 + +@class NSArray; + +@interface MyClass2 { +@private + NSArray *_names1; + NSArray *_names2; + NSArray *_names3; + NSArray *_names4; +} +@property (readwrite, strong) NSArray *names1; // <-- warning: Type of property.... +- (void)setNames1:(NSArray *)names; +@property (readwrite, strong) __strong NSArray *names2; // <-- warning: Type of property.... +- (void)setNames2:(NSArray *)names; +@property (readwrite, strong) __strong NSArray *names3; // <-- OK +- (void)setNames3:(__strong NSArray *)names; +@property (readwrite, strong) NSArray *names4; // <-- warning: Type of property.... +- (void)setNames4:(__strong NSArray *)names; + +@end + +@implementation MyClass2 +- (NSArray *)names1 { return _names1; } +- (void)setNames1:(NSArray *)names {} +- (NSArray *)names2 { return _names2; } +- (void)setNames2:(NSArray *)names {} +- (NSArray *)names3 { return _names3; } +- (void)setNames3:(__strong NSArray *)names {} +- (NSArray *)names4 { return _names4; } +- (void)setNames4:(__strong NSArray *)names {} + +@end + diff --git a/clang/test/SemaObjC/arc-system-header.m b/clang/test/SemaObjC/arc-system-header.m new file mode 100644 index 0000000..1a7c39d --- /dev/null +++ b/clang/test/SemaObjC/arc-system-header.m @@ -0,0 +1,50 @@ +// silly workaround expected-note {{marked unavailable here}} +// RUN: %clang_cc1 -fobjc-arc -isystem %S/Inputs %s -DNO_USE +// RUN: %clang_cc1 -fobjc-arc -isystem %S/Inputs %s -verify + +// another silly workaround expected-note {{marked unavailable here}} +#include <arc-system-header.h> + +#ifndef NO_USE +void test(id op, void *cp) { + cp = test0(op); // expected-error {{'test0' is unavailable: converts between Objective-C and C pointers in -fobjc-arc}} + cp = *test1(&op); // expected-error {{'test1' is unavailable: converts between Objective-C and C pointers in -fobjc-arc}} +} + +// workaround expected-note {{marked unavailable here}} +void test3(struct Test3 *p) { + p->field = 0; // expected-error {{'field' is unavailable: this system declaration uses an unsupported type}} +} + +// workaround expected-note {{marked unavailable here}} +void test4(Test4 *p) { + p->field1 = 0; // expected-error {{'field1' is unavailable: this system declaration uses an unsupported type}} + p->field2 = 0; +} + +// workaround expected-note {{marked unavailable here}} +void test5(struct Test5 *p) { + p->field = 0; // expected-error {{'field' is unavailable: this system field has retaining ownership}} +} + +id test6() { + // This is actually okay to use if declared in a system header. + id x; + x = (id) kMagicConstant; + x = (id) (x ? kMagicConstant : kMagicConstant); + x = (id) (x ? kMagicConstant : (void*) 0); + + extern void test6_helper(); + x = (id) (test6_helper(), kMagicConstant); +} + +// workaround expected-note 4 {{marked unavailable here}} +void test7(Test7 *p) { + *p.prop = 0; // expected-error {{'prop' is unavailable: this system declaration uses an unsupported type}} + p.prop = 0; // expected-error {{'prop' is unavailable: this system declaration uses an unsupported type}} + *[p prop] = 0; // expected-error {{'prop' is unavailable: this system declaration uses an unsupported type}} + [p setProp: 0]; // expected-error {{'setProp:' is unavailable: this system declaration uses an unsupported type}} +} +#endif + +// test8 in header diff --git a/clang/test/SemaObjC/arc-type-conversion.m b/clang/test/SemaObjC/arc-type-conversion.m new file mode 100644 index 0000000..5cf2cf4 --- /dev/null +++ b/clang/test/SemaObjC/arc-type-conversion.m @@ -0,0 +1,98 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -fblocks %s + +typedef const void * CFTypeRef; +CFTypeRef CFBridgingRetain(id X); +id CFBridgingRelease(CFTypeRef); + +void * cvt(id arg) +{ + 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 {{cast of an Objective-C pointer to '__autoreleasing id *' is disallowed with ARC}} + (void)(id*)arg; // expected-error {{cast of an Objective-C pointer to '__strong id *' is disallowed with ARC}} + + (void)(__autoreleasing id**)voidp_val; + (void)(void*)voidp_val; + (void)(void**)arg; // expected-error {{cast of an Objective-C pointer to 'void **' is disallowed with ARC}} + cvt((void*)arg); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}} \ + // expected-error {{implicit conversion of C pointer type 'void *' to Objective-C pointer type 'id' requires a bridged cast}} \ + // expected-note 2 {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use CFBridgingRetain call to make an ARC object available as a +1 'void *'}} \ + // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'void *' into ARC}} + cvt(0); + (void)(__strong id**)(0); + return arg; // expected-error {{implicit conversion of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use CFBridgingRetain call to make an ARC object available as a +1 'void *'}} +} + +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)(void*)&sip; + (void)(void*)&wip; + (void)(void*)&aip; + (void)(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 **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{{implicit conversion of a non-Objective-C pointer type 'void *' to '__strong id *' is disallowed with ARC}} + wip = vp; // expected-error{{implicit conversion of a non-Objective-C pointer type 'void *' to '__weak id *' is disallowed with ARC}} + aip = vp; // expected-error{{implicit conversion of a non-Objective-C pointer type 'void *' to '__autoreleasing id *' is disallowed with ARC}} + uip = vp; // expected-error{{implicit conversion of a non-Objective-C pointer type 'void *' to '__unsafe_unretained id *' is disallowed with ARC}} +} + +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 **sip = (NSString**)(__strong id *)vp; + __weak NSString **wip = (NSString**)(__weak id *)vp; + __autoreleasing id *aip = (id*)(__autoreleasing id *)vp; + __unsafe_unretained id *uip = (id*)(__unsafe_unretained id *)vp; + + __strong id **sipp = (id**)(__strong id **)vp; + __weak id **wipp = (id**)(__weak id **)vp; + __autoreleasing id **aipp = (id**)(__autoreleasing id **)vp; + __unsafe_unretained id **uipp = (id**)(__unsafe_unretained id **)vp; + + Block_strong blk_strong1; + Block_strong blk_strong2 = (Block)blk_strong1; + Block_autoreleasing *blk_auto = (Block*)pblk; + + id lv; + (void)(id)&lv; // expected-error {{cast of an indirect pointer to an Objective-C pointer to 'id'}} + (void)(id*)lv; // expected-error {{cast of an Objective-C pointer to '__strong id *'}} + (void)(NSString*)&lv; // expected-error {{cast of an indirect pointer to an Objective-C pointer to 'NSString *'}} + (void)(NSString**)lv; // expected-error {{cast of an Objective-C pointer to 'NSString *__strong *'}} + (void)(Block)&lv; // expected-error {{cast of an indirect pointer to an Objective-C pointer to 'Block'}} + (void)(Block*)lv; // expected-error {{cast of an Objective-C pointer to '__strong Block *'}} +} + +// <rdar://problem/10486347> +void conversion_in_conditional(id a, void* b) { + id c = 1 ? a : b; // expected-error {{operands to conditional of types 'id' and 'void *' are incompatible in ARC mode}} + id d = 1 ? b : a; // expected-error {{operands to conditional of types 'void *' and 'id' are incompatible in ARC mode}} +} diff --git a/clang/test/SemaObjC/arc-unavailable-for-weakref.m b/clang/test/SemaObjC/arc-unavailable-for-weakref.m new file mode 100644 index 0000000..8498de6 --- /dev/null +++ b/clang/test/SemaObjC/arc-unavailable-for-weakref.m @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %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>)strong1; // expected-error {{cast of weak-unavailable object of type 'NOWEAK<P,P1> *' to a __weak object of type '__weak id<P>'}} \ + // expected-error {{explicit ownership qualifier on cast result has no effect}} +} + +// rdar://10535245 +__attribute__((objc_arc_weak_reference_unavailable)) +@interface NSFont +@end + +@interface I +{ +} +@property (weak) NSFont *font; // expected-note {{property declared here}} +@end + +@implementation I +@synthesize font = _font; // expected-error {{synthesis of a weak-unavailable property is disallowed because it requires synthesis of an ivar of the __weak object}} +@end diff --git a/clang/test/SemaObjC/arc-unavailable-system-function.m b/clang/test/SemaObjC/arc-unavailable-system-function.m new file mode 100644 index 0000000..b0b70db --- /dev/null +++ b/clang/test/SemaObjC/arc-unavailable-system-function.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin11 -fobjc-arc -verify %s +// rdar://10186625 + +# 1 "<command line>" +# 1 "/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h" 1 3 +id * foo(); // expected-note {{function has been explicitly marked unavailable here}} + +# 1 "arc-unavailable-system-function.m" 2 +void ret() { + foo(); // expected-error {{'foo' is unavailable: this system declaration uses an unsupported type}} +} + + diff --git a/clang/test/SemaObjC/arc-unbridged-cast.m b/clang/test/SemaObjC/arc-unbridged-cast.m new file mode 100644 index 0000000..7d5a6b0 --- /dev/null +++ b/clang/test/SemaObjC/arc-unbridged-cast.m @@ -0,0 +1,123 @@ +// // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify %s + +typedef const struct __CFString * CFStringRef; +typedef const void * CFTypeRef; +CFTypeRef CFBridgingRetain(id X); +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}} +} + +void testTakerFunctions_parens(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/SemaObjC/arc-unsafe-assigns.m b/clang/test/SemaObjC/arc-unsafe-assigns.m new file mode 100644 index 0000000..1805b85 --- /dev/null +++ b/clang/test/SemaObjC/arc-unsafe-assigns.m @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s +// rdar://9495837 + +@interface Foo { + __unsafe_unretained id unsafe_ivar; +} + +@property (assign,nonatomic) id unsafe_prop; + +- (id)init; ++ (id)new; ++ (id)alloc; + +-(void)Meth; +@end + +@implementation Foo +@synthesize unsafe_prop; +-(id)init { return self; } ++(id)new { return 0; } ++(id)alloc { return 0; } + +-(void)Meth { + self.unsafe_prop = [Foo new]; // expected-warning {{assigning retained object to unsafe property}} + self->unsafe_ivar = [Foo new]; // expected-warning {{assigning retained object to unsafe_unretained}} + self.unsafe_prop = [[Foo alloc] init]; // expected-warning {{assigning retained object to unsafe property}} + self->unsafe_ivar = [[Foo alloc] init]; // expected-warning {{assigning retained object to unsafe_unretained}} + + __unsafe_unretained id unsafe_var; + unsafe_var = [Foo new]; // expected-warning {{assigning retained object to unsafe_unretained}} + unsafe_var = [[Foo alloc] init]; // expected-warning {{assigning retained object to unsafe_unretained}} +} +@end + +void bar(Foo *f) { + f.unsafe_prop = [Foo new]; // expected-warning {{assigning retained object to unsafe property}} + + __unsafe_unretained id unsafe_var; + unsafe_var = [Foo new]; // expected-warning {{assigning retained object to unsafe_unretained}} + unsafe_var = [[Foo alloc] init]; // expected-warning {{assigning retained object to unsafe_unretained}} +} diff --git a/clang/test/SemaObjC/arc-unsafe_unretained.m b/clang/test/SemaObjC/arc-unsafe_unretained.m new file mode 100644 index 0000000..a6c5f98 --- /dev/null +++ b/clang/test/SemaObjC/arc-unsafe_unretained.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks %s +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fobjc-arc %s + +struct X { + __unsafe_unretained id object; + int (^ __unsafe_unretained block)(int, int); +}; + +void f(struct X x) { + x.object = 0; + x.block = ^(int x, int y) { return x + y; }; +} diff --git a/clang/test/SemaObjC/arc.m b/clang/test/SemaObjC/arc.m new file mode 100644 index 0000000..9c3b298 --- /dev/null +++ b/clang/test/SemaObjC/arc.m @@ -0,0 +1,698 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class %s + +typedef unsigned long NSUInteger; +typedef const void * CFTypeRef; +CFTypeRef CFBridgingRetain(id X); +id CFBridgingRelease(CFTypeRef); + +void test0(void (*fn)(int), int val) { + fn(val); +} + +@interface A +- (id)retain; +- (id)autorelease; +- (oneway void)release; +- (void)dealloc; +- (NSUInteger)retainCount; +@end + +void test1(A *a) { + SEL s = @selector(retain); // expected-error {{ARC forbids use of 'retain' in a @selector}} + s = @selector(release); // expected-error {{ARC forbids use of 'release' in a @selector}} + s = @selector(autorelease); // expected-error {{ARC forbids use of 'autorelease' in a @selector}} + s = @selector(dealloc); // expected-error {{ARC forbids use of 'dealloc' in a @selector}} + [a dealloc]; // expected-error {{ARC forbids explicit message send of 'dealloc'}} + [a retain]; // expected-error {{ARC forbids explicit message send of 'retain'}} + [a retainCount]; // expected-error {{ARC forbids explicit message send of 'retainCount'}} + [a release]; // expected-error {{ARC forbids explicit message send of 'release'}} + [a autorelease]; // expected-error {{ARC forbids explicit message send of 'autorelease'}} +} + +@interface Test2 : A +- (void) dealloc; +@end +@implementation Test2 +- (void) dealloc { + // This should maybe just be ignored. We're just going to warn about it for now. + [super dealloc]; // expected-error {{ARC forbids explicit message send of 'dealloc'}} +} +@end + +// rdar://8843638 + +@interface I +- (id)retain; // expected-note {{method 'retain' declared here}} +- (id)autorelease; // expected-note {{method 'autorelease' declared here}} +- (oneway void)release; // expected-note {{method 'release' declared here}} +- (NSUInteger)retainCount; // expected-note {{method 'retainCount' declared here}} +@end + +@implementation I +- (id)retain{return 0;} // expected-error {{ARC forbids implementation of 'retain'}} +- (id)autorelease{return 0;} // expected-error {{ARC forbids implementation of 'autorelease'}} +- (oneway void)release{} // expected-error {{ARC forbids implementation of 'release'}} +- (NSUInteger)retainCount{ return 0; } // expected-error {{ARC forbids implementation of 'retainCount'}} +@end + +@implementation I(CAT) +- (id)retain{return 0;} // expected-error {{ARC forbids implementation of 'retain'}} \ + // expected-warning {{category is implementing a method which will also be implemented by its primary class}} +- (id)autorelease{return 0;} // expected-error {{ARC forbids implementation of 'autorelease'}} \ + // expected-warning {{category is implementing a method which will also be implemented by its primary class}} +- (oneway void)release{} // expected-error {{ARC forbids implementation of 'release'}} \ + // expected-warning {{category is implementing a method which will also be implemented by its primary class}} +- (NSUInteger)retainCount{ return 0; } // expected-error {{ARC forbids implementation of 'retainCount'}} \ + // expected-warning {{category is implementing a method which will also be implemented by its primary class}} +@end + +// rdar://8861761 + +@interface B +-(id)alloc; +- (id)initWithInt: (int) i; +@end + +void rdar8861761() { + B *o1 = [[B alloc] initWithInt:0]; + B *o2 = [B alloc]; + [o2 initWithInt:0]; // expected-warning {{expression result unused}} +} + +// rdar://8925835 +@interface rdar8925835 +- (void)foo:(void (^)(unsigned captureCount, I * const capturedStrings[captureCount]))block; +@end + +void test5() { + extern void test5_helper(__autoreleasing id *); + id x; + + // Okay because of magic temporaries. + test5_helper(&x); + + __autoreleasing id *a = &x; // expected-error {{initializing '__autoreleasing id *' with an expression of type '__strong id *' changes retain/release properties of pointer}} + + a = &x; // expected-error {{assigning '__strong id *' to '__autoreleasing id *' changes retain/release properties of pointer}} + + extern void test5_helper2(id const *); + test5_helper2(&x); + + extern void test5_helper3(__weak id *); // expected-note {{passing argument to parameter here}} + test5_helper3(&x); // expected-error {{passing '__strong id *' to parameter of type '__weak id *' changes retain/release properties of pointer}} +} + +// rdar://problem/8937869 +void test6(unsigned cond) { + switch (cond) { + case 0: + ; + id x; // expected-note {{jump bypasses initialization of retaining variable}} + + case 1: // expected-error {{switch case is in protected scope}} + break; + } +} + +@class NSError; +void test7(void) { + extern void test7_helper(NSError **); + NSError *err; + test7_helper(&err); +} +void test7_weak(void) { + extern void test7_helper(NSError **); + __weak NSError *err; + test7_helper(&err); +} +void test7_unsafe(void) { + extern void test7_helper(NSError **); // expected-note {{passing argument to parameter here}} + __unsafe_unretained NSError *err; + test7_helper(&err); // expected-error {{passing 'NSError *__unsafe_unretained *' to parameter of type 'NSError *__autoreleasing *' changes retain/release properties of pointer}} +} + +@class Test8_incomplete; +@interface Test8_complete @end; +@interface Test8_super @end; +@interface Test8 : Test8_super +- (id) init00; +- (id) init01; // expected-note {{declaration in interface}} \ + // expected-note{{overridden method}} +- (id) init02; // expected-note{{overridden method}} +- (id) init03; // covariance +- (id) init04; // covariance +- (id) init05; // expected-note{{overridden method}} + +- (void) init10; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} +- (void) init11; +- (void) init12; +- (void) init13; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} +- (void) init14; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} +- (void) init15; + +// These should be invalid to actually call. +- (Test8_incomplete*) init20; +- (Test8_incomplete*) init21; // expected-note {{declaration in interface}} +- (Test8_incomplete*) init22; +- (Test8_incomplete*) init23; +- (Test8_incomplete*) init24; +- (Test8_incomplete*) init25; + +- (Test8_super*) init30; // id exception to covariance +- (Test8_super*) init31; // expected-note {{declaration in interface}} \ + // expected-note{{overridden method}} +- (Test8_super*) init32; // expected-note{{overridden method}} +- (Test8_super*) init33; +- (Test8_super*) init34; // covariance +- (Test8_super*) init35; // expected-note{{overridden method}} + +- (Test8*) init40; // id exception to covariance +- (Test8*) init41; // expected-note {{declaration in interface}} \ + // expected-note{{overridden method}} +- (Test8*) init42; // expected-note{{overridden method}} +- (Test8*) init43; // this should be a warning, but that's a general language thing, not an ARC thing +- (Test8*) init44; +- (Test8*) init45; // expected-note{{overridden method}} + +- (Test8_complete*) init50; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init51; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init52; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init53; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init54; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init55; // expected-error {{init methods must return a type related to the receiver type}} +@end +@implementation Test8 +- (id) init00 { return 0; } +- (id) init10 { return 0; } // expected-error {{method implementation does not match its declaration}} +- (id) init20 { return 0; } +- (id) init30 { return 0; } +- (id) init40 { return 0; } +- (id) init50 { return 0; } + +- (void) init01 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} \ + // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'void'}} +- (void) init11 {} +- (void) init21 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} +- (void) init31 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} \ + // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'void'}} +- (void) init41 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} \ + // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'void'}} +- (void) init51 {} + +- (Test8_incomplete*) init02 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \ + // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_incomplete *'}} +- (Test8_incomplete*) init12 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init22 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init32 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \ + // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_incomplete *'}} +- (Test8_incomplete*) init42 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \ + // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_incomplete *'}} +- (Test8_incomplete*) init52 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} + +- (Test8_super*) init03 { return 0; } +- (Test8_super*) init13 { return 0; } // expected-error {{method implementation does not match its declaration}} +- (Test8_super*) init23 { return 0; } +- (Test8_super*) init33 { return 0; } +- (Test8_super*) init43 { return 0; } +- (Test8_super*) init53 { return 0; } + +- (Test8*) init04 { return 0; } +- (Test8*) init14 { return 0; } // expected-error {{method implementation does not match its declaration}} +- (Test8*) init24 { return 0; } +- (Test8*) init34 { return 0; } +- (Test8*) init44 { return 0; } +- (Test8*) init54 { return 0; } + +- (Test8_complete*) init05 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \ + // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_complete *'}} +- (Test8_complete*) init15 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init25 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init35 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \ + // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_complete *'}} +- (Test8_complete*) init45 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \ + // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_complete *'}} +- (Test8_complete*) init55 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +@end + +@class Test9_incomplete; +@interface Test9 +- (Test9_incomplete*) init1; // expected-error {{init methods must return a type related to the receiver type}} +- (Test9_incomplete*) init2; +@end +id test9(Test9 *v) { + return [v init1]; +} + +// Test that the inference rules are different for fast enumeration variables. +void test10(id collection) { + for (id x in collection) { + __strong id *ptr = &x; // expected-warning {{initializing '__strong id *' with an expression of type 'const __strong id *' discards qualifiers}} + } + + for (__strong id x in collection) { + __weak id *ptr = &x; // expected-error {{initializing '__weak id *' with an expression of type '__strong id *' changes retain/release properties of pointer}} + } +} + +// rdar://problem/9078626 +#define nil ((void*) 0) +void test11(id op, void *vp) { + _Bool b; + b = (op == nil); + b = (nil == op); + + b = (vp == nil); + b = (nil == vp); + + b = (vp == op); // expected-error {{implicit conversion of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRetain call}} + b = (op == vp); // expected-error {{implicit conversion of C pointer type 'void *' to Objective-C pointer type 'id' requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRelease call}} +} + +void test12(id collection) { + for (id x in collection) { + x = 0; // expected-error {{fast enumeration variables can't be modified in ARC by default; declare the variable __strong to allow this}} + } + + for (const id x in collection) { + x = 0; // expected-error {{read-only variable is not assignable}} + } + + for (__strong id x in collection) { + x = 0; + } +} + +@interface Test13 +- (id) init0; +- (void) noninit; +@end +@implementation Test13 +- (id) init0 { + self = 0; +} +- (void) noninit { + self = 0; // expected-error {{cannot assign to 'self' outside of a method in the init family}} +} +@end + +// <rdar://problem/10274056> +@interface Test13_B +- (id) consumesSelf __attribute__((ns_consumes_self)); +@end +@implementation Test13_B +- (id) consumesSelf { + self = 0; // no-warning +} +@end + +// rdar://problem/9172151 +@class Test14A, Test14B; +void test14() { + extern void test14_consume(id *); + extern int test14_cond(void); + extern float test14_nowriteback(id __autoreleasing const *); // expected-note{{passing argument to parameter here}} + + Test14A *a; + Test14B *b; + id i; + id cla[10]; + id vla[test14_cond() + 10]; + + test14_consume((__strong id*) &a); + test14_consume((test14_cond() ? (__strong id*) &b : &i)); + test14_consume(test14_cond() ? 0 : &a); + test14_consume(test14_cond() ? (void*) 0 : (&a)); + test14_consume(cla); // expected-error {{passing address of non-scalar object to __autoreleasing parameter for write-back}} + test14_consume(vla); // expected-error {{passing address of non-scalar object to __autoreleasing parameter for write-back}} + test14_consume(&cla[5]); // expected-error {{passing address of non-scalar object to __autoreleasing parameter for write-back}} + + __strong id *test14_indirect(void); + test14_consume(test14_indirect()); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}} + + extern id test14_global; + test14_consume(&test14_global); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}} + + extern __strong id *test14_global_ptr; + test14_consume(test14_global_ptr); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}} + + static id static_local; + test14_consume(&static_local); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}} + + __weak id* wip; + test14_nowriteback(&static_local); // okay, not a write-back. + test14_nowriteback(wip); // expected-error{{passing '__weak id *' to parameter of type '__autoreleasing id const *' changes retain/release properties of pointer}} +} + +void test15() { + __block __autoreleasing id x; // expected-error {{__block variables cannot have __autoreleasing ownership}} +} + +struct Test16; +@interface Test16a +- (void) test16_0: (int) x; +- (int) test16_1: (int) x; // expected-note {{one possibility}} +- (int) test16_2: (int) x; // expected-note {{one possibility}} +- (id) test16_3: (int) x __attribute__((ns_returns_retained)); // expected-note {{one possibility}} +- (void) test16_4: (int) x __attribute__((ns_consumes_self)); // expected-note {{one possibility}} +- (void) test16_5: (id) __attribute__((ns_consumed)) x; // expected-note {{one possibility}} +- (void) test16_6: (id) x; +@end + +@interface Test16b +- (void) test16_0: (int) x; +- (int) test16_1: (char*) x; // expected-note {{also found}} +- (char*) test16_2: (int) x; // expected-note {{also found}} +- (id) test16_3: (int) x; // expected-note {{also found}} +- (void) test16_4: (int) x; // expected-note {{also found}} +- (void) test16_5: (id) x; // expected-note {{also found}} +- (void) test16_6: (struct Test16 *) x; +@end + +void test16(void) { + id v; + [v test16_0: 0]; + [v test16_1: 0]; // expected-error {{multiple methods named 'test16_1:' found with mismatched result, parameter type or attributes}} + [v test16_2: 0]; // expected-error {{multiple methods named}} + [v test16_3: 0]; // expected-error {{multiple methods named}} + [v test16_4: 0]; // expected-error {{multiple methods named}} + [v test16_5: 0]; // expected-error {{multiple methods named}} + [v test16_6: 0]; +} + +@class Test17; // expected-note 2{{forward declaration of class here}} +@protocol Test17p +- (void) test17; ++ (void) test17; +@end +void test17(void) { + Test17 *v0; + [v0 test17]; // expected-error {{receiver type 'Test17' for instance message is a forward declaration}} + + Test17<Test17p> *v1; + [v1 test17]; // expected-error {{receiver type 'Test17<Test17p>' for instance message is a forward declaration}} + + [Test17 test17]; // expected-error {{receiver 'Test17' for class message is a forward declaration}} +} + +void test18(void) { + id x; + [x test18]; // expected-error {{no known instance method for selector 'test18'}} +} + +extern struct Test19 *test19a; +struct Test19 *const test19b = 0; +void test19(void) { + id x; + x = (id) test19a; // expected-error {{bridged cast}} \ + // expected-note{{use __bridge to convert directly (no change in ownership)}} \ + // expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'struct Test19 *' into ARC}} + x = (id) test19b; // expected-error {{bridged cast}} \ + // expected-note{{use __bridge to convert directly (no change in ownership)}} \ + // expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'struct Test19 *' into ARC}} +} + +// rdar://problem/8951453 +static __thread id test20_implicit; // expected-error {{thread-local variable has non-trivial ownership: type is '__strong id'}} +static __thread __strong id test20_strong; // expected-error {{thread-local variable has non-trivial ownership: type is '__strong id'}} +static __thread __weak id test20_weak; // expected-error {{thread-local variable has non-trivial ownership: type is '__weak id'}} +static __thread __autoreleasing id test20_autoreleasing; // expected-error {{thread-local variable has non-trivial ownership: type is '__autoreleasing id'}} expected-error {{global variables cannot have __autoreleasing ownership}} +static __thread __unsafe_unretained id test20_unsafe; +void test20(void) { + static __thread id test20_implicit; // expected-error {{thread-local variable has non-trivial ownership: type is '__strong id'}} + static __thread __strong id test20_strong; // expected-error {{thread-local variable has non-trivial ownership: type is '__strong id'}} + static __thread __weak id test20_weak; // expected-error {{thread-local variable has non-trivial ownership: type is '__weak id'}} + static __thread __autoreleasing id test20_autoreleasing; // expected-error {{thread-local variable has non-trivial ownership: type is '__autoreleasing id'}} expected-error {{global variables cannot have __autoreleasing ownership}} + static __thread __unsafe_unretained id test20_unsafe; +} + +// rdar://9310049 +_Bool fn(id obj) { + return (_Bool)obj; +} + +// Check casting w/ ownership qualifiers. +void test21() { + __strong id *sip; + (void)(__weak id *)sip; // expected-error{{casting '__strong id *' to type '__weak id *' changes retain/release properties of pointer}} + (void)(__weak const id *)sip; // expected-error{{casting '__strong id *' to type '__weak id const *' changes retain/release properties of pointer}} + (void)(__autoreleasing id *)sip; // expected-error{{casting '__strong id *' to type '__autoreleasing id *' changes retain/release properties of pointer}} + (void)(__autoreleasing const id *)sip; // okay +} + +// rdar://problem/9340462 +void test22(id x[]) { // expected-error {{must explicitly describe intended ownership of an object array parameter}} +} + +// rdar://problem/9400219 +void test23(void) { + void *ptr; + ptr = @"foo"; + ptr = (ptr ? @"foo" : 0); + ptr = (ptr ? @"foo" : @"bar"); +} + +id test24(void) { + extern void test24_helper(void); + return test24_helper(), (void*) 0; +} + +// rdar://9400841 +@interface Base +@property (assign) id content; +@end + +@interface Foo : Base +-(void)test; +@end + +@implementation Foo +-(void)test { + super.content = 0; +} +@end + +// <rdar://problem/9398437> +void test25(Class *classes) { + Class *other_classes; + test25(other_classes); +} + +void test26(id y) { + extern id test26_var1; + __sync_swap(&test26_var1, 0, y); // expected-error {{cannot perform atomic operation on a pointer to type '__strong id': type has non-trivial ownership}} + + extern __unsafe_unretained id test26_var2; + __sync_swap(&test26_var2, 0, y); +} + +@interface Test26 +- (id) init; +- (id) initWithInt: (int) x; +@end +@implementation Test26 +- (id) init { return self; } +- (id) initWithInt: (int) x { + [self init]; // expected-error {{the result of a delegate init call must be immediately returned or assigned to 'self'}} + return self; +} +@end + +// rdar://9525555 +@interface Test27 { + __weak id _myProp1; + id myProp2; +} +@property id x; +@property (readonly) id ro; +@property (readonly) id custom_ro; +@property int y; + +@property (readonly) __weak id myProp1; +@property (readonly) id myProp2; +@property (readonly) __strong id myProp3; +@end + +@implementation Test27 +@synthesize x; +@synthesize ro; +@synthesize y; + +@synthesize myProp1 = _myProp1; +@synthesize myProp2; +@synthesize myProp3; + +-(id)custom_ro { return 0; } +@end + +// rdar://9569264 +@interface Test28 +@property (nonatomic, assign) __strong id a; // expected-error {{unsafe_unretained property 'a' may not also be declared __strong}} +@end + +@interface Test28 () +@property (nonatomic, assign) __strong id b; // expected-error {{unsafe_unretained property 'b' may not also be declared __strong}} +@end + +@implementation Test28 +@synthesize a; +@synthesize b; +@end + +// rdar://9573962 +typedef struct Bark Bark; +@interface Test29 +@property Bark* P; +@end + +@implementation Test29 +@synthesize P; +- (id)Meth { + Bark** f = &P; + return 0; +} +@end + +// rdar://9495837 +@interface Test30 ++ (id) new; +- (void)Meth; +@end + +@implementation Test30 ++ (id) new { return 0; } +- (void) Meth { + __weak id x = [Test30 new]; // expected-warning {{assigning retained object to weak variable}} + id __unsafe_unretained u = [Test30 new]; // expected-warning {{assigning retained object to unsafe_unretained variable}} + id y = [Test30 new]; + x = [Test30 new]; // expected-warning {{assigning retained object to weak variable}} + u = [Test30 new]; // expected-warning {{assigning retained object to unsafe_unretained variable}} + y = [Test30 new]; +} +@end + +// rdar://9411838 +@protocol PTest31 @end + +int Test31() { + Class cls; + id ids; + id<PTest31> pids; + Class<PTest31> pcls; + + int i = (ids->isa ? 1 : 0); // expected-error {{member reference base type 'id' is not a structure or union}} + int j = (pids->isa ? 1 : 0); // expected-error {{member reference base type 'id<PTest31>' is not a structure or union}} + int k = (pcls->isa ? i : j); // expected-error {{member reference base type 'Class<PTest31>' is not a structure or union}} + return cls->isa ? i : j; // expected-error {{member reference base type 'Class' is not a structure or union}} +} + +// rdar://9612030 +@interface ITest32 { +@public + id ivar; +} +@end + +id Test32(__weak ITest32 *x) { + __weak ITest32 *y; + x->ivar = 0; // expected-error {{dereferencing a __weak pointer is not allowed}} + return y ? y->ivar // expected-error {{dereferencing a __weak pointer is not allowed}} + : (*x).ivar; // expected-error {{dereferencing a __weak pointer is not allowed}} +} + +// rdar://9619861 +extern int printf(const char*, ...); +typedef long intptr_t; + +int Test33(id someid) { + printf( "Hello%ld", (intptr_t)someid); + return (int)someid; +} + +// rdar://9636091 +@interface I34 +@property (nonatomic, retain) id newName __attribute__((ns_returns_not_retained)) ; + +@property (nonatomic, retain) id newName1 __attribute__((ns_returns_not_retained)) ; +- (id) newName1 __attribute__((ns_returns_not_retained)); + +@property (nonatomic, retain) id newName2 __attribute__((ns_returns_not_retained)); // expected-note {{roperty declared here}} +- (id) newName2; // expected-warning {{property declared as returning non-retained objects; getter returning retained objects}} +@end + +@implementation I34 +@synthesize newName; + +@synthesize newName1; +- (id) newName1 { return 0; } + +@synthesize newName2; +@end + +void test35(void) { + extern void test36_helper(id*); + id x; + __strong id *xp = 0; + + test36_helper(&x); + test36_helper(xp); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}} + + // rdar://problem/9665710 + __block id y; + test36_helper(&y); + ^{ test36_helper(&y); }(); + + __strong int non_objc_type; // expected-warning {{'__strong' only applies to objective-c object or block pointer types}} +} + +void test36(int first, ...) { + // <rdar://problem/9758798> + __builtin_va_list arglist; + __builtin_va_start(arglist, first); + id obj = __builtin_va_arg(arglist, id); + __builtin_va_end(arglist); +} + +@class Test37; // expected-note{{forward declaration of class here}} +void test37(Test37 *c) { + for (id y in c) { // expected-error {{collection expression type 'Test37' is a forward declaration}} + (void) y; + } + + (void)sizeof(id*); // no error. +} + +// rdar://problem/9887979 +@interface Test38 +@property int value; +@end +void test38() { + extern Test38 *test38_helper(void); + switch (test38_helper().value) { + case 0: + case 1: + ; + } +} + +// rdar://10186536 +@class NSColor; +void _NSCalc(NSColor* color, NSColor* bezelColors[]) __attribute__((unavailable("not available in automatic reference counting mode"))); + +void _NSCalcBeze(NSColor* color, NSColor* bezelColors[]); // expected-error {{must explicitly describe intended ownership of an object array parameter}} + +// rdar://9970739 +@interface RestaurantTableViewCell +- (void) restaurantLocation; +@end + +@interface Radar9970739 +- (void) Meth; +@end + +@implementation Radar9970739 +- (void) Meth { + RestaurantTableViewCell *cell; + [cell restaurantLocatoin]; // expected-error {{no visible @interface for 'RestaurantTableViewCell' declares the selector 'restaurantLocatoin'}} +} +@end + diff --git a/clang/test/SemaObjC/argument-checking.m b/clang/test/SemaObjC/argument-checking.m new file mode 100644 index 0000000..9019a0f --- /dev/null +++ b/clang/test/SemaObjC/argument-checking.m @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s + +struct S { int a; }; + +extern int charStarFunc(char *); // expected-note{{passing argument to parameter here}} +extern int charFunc(char); // expected-note{{passing argument to parameter here}} + +@interface Test ++alloc; +-(int)charStarMeth:(char *)s; // expected-note{{passing argument to parameter 's' here}} +-structMeth:(struct S)s; // expected-note{{passing argument to parameter 's' here}} +-structMeth:(struct S)s + :(struct S)s2; // expected-note{{passing argument to parameter 's2' here}} +@end + +void test() { + id obj = [Test alloc]; + struct S sInst; + + charStarFunc(1); // expected-warning {{incompatible integer to pointer conversion passing 'int' to parameter of type 'char *'}} + charFunc("abc"); // expected-warning {{incompatible pointer to integer conversion passing 'char [4]' to parameter of type 'char'}} + + [obj charStarMeth:1]; // expected-warning {{incompatible integer to pointer conversion sending 'int'}} + [obj structMeth:1]; // expected-error {{sending 'int'}} + [obj structMeth:sInst :1]; // expected-error {{sending 'int'}} +} diff --git a/clang/test/SemaObjC/assign-rvalue-message.m b/clang/test/SemaObjC/assign-rvalue-message.m new file mode 100644 index 0000000..1105d5e --- /dev/null +++ b/clang/test/SemaObjC/assign-rvalue-message.m @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://9005189 + +@interface Foo +@end + +struct Bar { + int x; +}; + +@implementation Foo { + struct Bar bar; +} + +- (const struct Bar)bar { + return bar; +} + +- (void)baz { + bar.x = 0; + [self bar].x = 10; // expected-error {{assigning to 'readonly' return result of an objective-c message not allowed}} +} +@end diff --git a/clang/test/SemaObjC/at-defs.m b/clang/test/SemaObjC/at-defs.m new file mode 100644 index 0000000..4c0c586 --- /dev/null +++ b/clang/test/SemaObjC/at-defs.m @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -fobjc-fragile-abi %s -fsyntax-only + +@interface Test { + double a; +} +@end +@implementation Test +@end +@interface TestObject : Test { +@public + float bar; + int foo; +} +@end +@implementation TestObject +@end +struct wibble { + @defs(TestObject) +}; + + +int main(void) +{ + TestObject * a = (id)malloc(100); + a->foo = 12; + printf("12: %d\n", ((struct wibble*)a)->foo); + printf("%d: %d\n", ((char*)&(((struct wibble*)a)->foo)) - (char*)a, ((char*)&(a->foo)) - (char*)a); + return 0; +} diff --git a/clang/test/SemaObjC/atomoic-property-synnthesis-rules.m b/clang/test/SemaObjC/atomoic-property-synnthesis-rules.m new file mode 100644 index 0000000..b681558 --- /dev/null +++ b/clang/test/SemaObjC/atomoic-property-synnthesis-rules.m @@ -0,0 +1,377 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +/* + Conditions for warning: + 1. the property is atomic + 2. the current @implementation contains an @synthesize for the property + 3. the current @implementation contains a hand-written setter XOR getter + 4. the property is read-write + + Cases marked WARN should warn one the following: + warning: Atomic property 'x' has a synthesized setter and a + manually-implemented getter, which may break atomicity. + warning: Atomic property 'x' has a synthesized getter and a + manually-implemented setter, which may break atomicity. + + Cases not marked WARN only satisfy the indicated subset + of the conditions required to warn. + + There should be 8 warnings. +*/ + +@interface Foo +{ + /* 12 4 */ int GetSet; + /* WARN */ int Get; + /* WARN */ int Set; + /* 12 4 */ int None; + /* 2 4 */ int GetSet_Nonatomic; + /* 234 */ int Get_Nonatomic; + /* 234 */ int Set_Nonatomic; + /* 2 4 */ int None_Nonatomic; + + /* 12 */ int GetSet_ReadOnly; + /* 123 */ int Get_ReadOnly; + /* 123 */ int Set_ReadOnly; + /* 12 */ int None_ReadOnly; + /* 2 */ int GetSet_Nonatomic_ReadOnly; + /* 23 */ int Get_Nonatomic_ReadOnly; + /* 23 */ int Set_Nonatomic_ReadOnly; + /* 2 */ int None_Nonatomic_ReadOnly; + + /* 12 4 */ int GetSet_ReadWriteInExt; + /* WARN */ int Get_ReadWriteInExt; + /* WARN */ int Set_ReadWriteInExt; + /* 12 4 */ int None_ReadWriteInExt; + /* 2 4 */ int GetSet_Nonatomic_ReadWriteInExt; + /* 234 */ int Get_Nonatomic_ReadWriteInExt; + /* 234 */ int Set_Nonatomic_ReadWriteInExt; + /* 2 4 */ int None_Nonatomic_ReadWriteInExt; + + + /* 12 4 */ int GetSet_LateSynthesize; + /* WARN */ int Get_LateSynthesize; + /* WARN */ int Set_LateSynthesize; + /* 12 4 */ int None_LateSynthesize; + /* 2 4 */ int GetSet_Nonatomic_LateSynthesize; + /* 234 */ int Get_Nonatomic_LateSynthesize; + /* 234 */ int Set_Nonatomic_LateSynthesize; + /* 2 4 */ int None_Nonatomic_LateSynthesize; + + /* 12 */ int GetSet_ReadOnly_LateSynthesize; + /* 123 */ int Get_ReadOnly_LateSynthesize; + /* 123 */ int Set_ReadOnly_LateSynthesize; + /* 12 */ int None_ReadOnly_LateSynthesize; + /* 2 */ int GetSet_Nonatomic_ReadOnly_LateSynthesize; + /* 23 */ int Get_Nonatomic_ReadOnly_LateSynthesize; + /* 23 */ int Set_Nonatomic_ReadOnly_LateSynthesize; + /* 2 */ int None_Nonatomic_ReadOnly_LateSynthesize; + + /* 12 4 */ int GetSet_ReadWriteInExt_LateSynthesize; + /* WARN */ int Get_ReadWriteInExt_LateSynthesize; + /* WARN */ int Set_ReadWriteInExt_LateSynthesize; + /* 12 4 */ int None_ReadWriteInExt_LateSynthesize; + /* 2 4 */ int GetSet_Nonatomic_ReadWriteInExt_LateSynthesize; + /* 234 */ int Get_Nonatomic_ReadWriteInExt_LateSynthesize; + /* 234 */ int Set_Nonatomic_ReadWriteInExt_LateSynthesize; + /* 2 4 */ int None_Nonatomic_ReadWriteInExt_LateSynthesize; + + + /* 1 4 */ int GetSet_NoSynthesize; + /* 1 34 */ int Get_NoSynthesize; + /* 1 34 */ int Set_NoSynthesize; + /* 1 4 */ int None_NoSynthesize; + /* 4 */ int GetSet_Nonatomic_NoSynthesize; + /* 34 */ int Get_Nonatomic_NoSynthesize; + /* 34 */ int Set_Nonatomic_NoSynthesize; + /* 4 */ int None_Nonatomic_NoSynthesize; + + /* 1 */ int GetSet_ReadOnly_NoSynthesize; + /* 1 3 */ int Get_ReadOnly_NoSynthesize; + /* 1 3 */ int Set_ReadOnly_NoSynthesize; + /* 1 */ int None_ReadOnly_NoSynthesize; + /* */ int GetSet_Nonatomic_ReadOnly_NoSynthesize; + /* 3 */ int Get_Nonatomic_ReadOnly_NoSynthesize; + /* 3 */ int Set_Nonatomic_ReadOnly_NoSynthesize; + /* */ int None_Nonatomic_ReadOnly_NoSynthesize; + + /* 1 4 */ int GetSet_ReadWriteInExt_NoSynthesize; + /* 1 34 */ int Get_ReadWriteInExt_NoSynthesize; + /* 1 34 */ int Set_ReadWriteInExt_NoSynthesize; + /* 1 4 */ int None_ReadWriteInExt_NoSynthesize; + /* 4 */ int GetSet_Nonatomic_ReadWriteInExt_NoSynthesize; + /* 34 */ int Get_Nonatomic_ReadWriteInExt_NoSynthesize; + /* 34 */ int Set_Nonatomic_ReadWriteInExt_NoSynthesize; + /* 4 */ int None_Nonatomic_ReadWriteInExt_NoSynthesize; +} + +// read-write - might warn +@property int GetSet; +@property int Get; // expected-note {{property declared here}} \ + // expected-note {{setter and getter must both be synthesized}} +@property int Set; // expected-note {{property declared here}} \ + // expected-note {{setter and getter must both be synthesized}} +@property int None; +@property(nonatomic) int GetSet_Nonatomic; +@property(nonatomic) int Get_Nonatomic; +@property(nonatomic) int Set_Nonatomic; +@property(nonatomic) int None_Nonatomic; + +// read-only - must not warn +@property(readonly) int GetSet_ReadOnly; +@property(readonly) int Get_ReadOnly; +@property(readonly) int Set_ReadOnly; +@property(readonly) int None_ReadOnly; +@property(nonatomic,readonly) int GetSet_Nonatomic_ReadOnly; +@property(nonatomic,readonly) int Get_Nonatomic_ReadOnly; +@property(nonatomic,readonly) int Set_Nonatomic_ReadOnly; +@property(nonatomic,readonly) int None_Nonatomic_ReadOnly; + +// read-only in class, read-write in class extension - might warn +@property(readonly) int GetSet_ReadWriteInExt; +@property(readonly) int Get_ReadWriteInExt; // expected-note {{property declared here}} \ + // expected-note {{setter and getter must both be synthesized}} +@property(readonly) int Set_ReadWriteInExt; // expected-note {{property declared here}} \ + // expected-note {{setter and getter must both be synthesized}} +@property(readonly) int None_ReadWriteInExt; +@property(nonatomic,readonly) int GetSet_Nonatomic_ReadWriteInExt; +@property(nonatomic,readonly) int Get_Nonatomic_ReadWriteInExt; +@property(nonatomic,readonly) int Set_Nonatomic_ReadWriteInExt; +@property(nonatomic,readonly) int None_Nonatomic_ReadWriteInExt; + + +// same as above, but @synthesize follows the hand-written methods - might warn +@property int GetSet_LateSynthesize; +@property int Get_LateSynthesize; // expected-note {{property declared here}} \ + // expected-note {{setter and getter must both be synthesized}} +@property int Set_LateSynthesize; // expected-note {{property declared here}} \ + // expected-note {{setter and getter must both be synthesized}} +@property int None_LateSynthesize; +@property(nonatomic) int GetSet_Nonatomic_LateSynthesize; +@property(nonatomic) int Get_Nonatomic_LateSynthesize; +@property(nonatomic) int Set_Nonatomic_LateSynthesize; +@property(nonatomic) int None_Nonatomic_LateSynthesize; + +@property(readonly) int GetSet_ReadOnly_LateSynthesize; +@property(readonly) int Get_ReadOnly_LateSynthesize; +@property(readonly) int Set_ReadOnly_LateSynthesize; +@property(readonly) int None_ReadOnly_LateSynthesize; +@property(nonatomic,readonly) int GetSet_Nonatomic_ReadOnly_LateSynthesize; +@property(nonatomic,readonly) int Get_Nonatomic_ReadOnly_LateSynthesize; +@property(nonatomic,readonly) int Set_Nonatomic_ReadOnly_LateSynthesize; +@property(nonatomic,readonly) int None_Nonatomic_ReadOnly_LateSynthesize; + +@property(readonly) int GetSet_ReadWriteInExt_LateSynthesize; +@property(readonly) int Get_ReadWriteInExt_LateSynthesize; // expected-note {{property declared here}} \ + // expected-note {{setter and getter must both be synthesized}} +@property(readonly) int Set_ReadWriteInExt_LateSynthesize; // expected-note {{property declared here}} \ + // expected-note {{setter and getter must both be synthesized}} +@property(readonly) int None_ReadWriteInExt_LateSynthesize; +@property(nonatomic,readonly) int GetSet_Nonatomic_ReadWriteInExt_LateSynthesize; +@property(nonatomic,readonly) int Get_Nonatomic_ReadWriteInExt_LateSynthesize; +@property(nonatomic,readonly) int Set_Nonatomic_ReadWriteInExt_LateSynthesize; +@property(nonatomic,readonly) int None_Nonatomic_ReadWriteInExt_LateSynthesize; + + +// same as above, but with no @synthesize - must not warn +@property int GetSet_NoSynthesize; +@property int Get_NoSynthesize; +@property int Set_NoSynthesize; +@property int None_NoSynthesize; +@property(nonatomic) int GetSet_Nonatomic_NoSynthesize; +@property(nonatomic) int Get_Nonatomic_NoSynthesize; +@property(nonatomic) int Set_Nonatomic_NoSynthesize; +@property(nonatomic) int None_Nonatomic_NoSynthesize; + +@property(readonly) int GetSet_ReadOnly_NoSynthesize; +@property(readonly) int Get_ReadOnly_NoSynthesize; +@property(readonly) int Set_ReadOnly_NoSynthesize; +@property(readonly) int None_ReadOnly_NoSynthesize; +@property(nonatomic,readonly) int GetSet_Nonatomic_ReadOnly_NoSynthesize; +@property(nonatomic,readonly) int Get_Nonatomic_ReadOnly_NoSynthesize; +@property(nonatomic,readonly) int Set_Nonatomic_ReadOnly_NoSynthesize; +@property(nonatomic,readonly) int None_Nonatomic_ReadOnly_NoSynthesize; + +@property(readonly) int GetSet_ReadWriteInExt_NoSynthesize; +@property(readonly) int Get_ReadWriteInExt_NoSynthesize; +@property(readonly) int Set_ReadWriteInExt_NoSynthesize; +@property(readonly) int None_ReadWriteInExt_NoSynthesize; +@property(nonatomic,readonly) int GetSet_Nonatomic_ReadWriteInExt_NoSynthesize; +@property(nonatomic,readonly) int Get_Nonatomic_ReadWriteInExt_NoSynthesize; +@property(nonatomic,readonly) int Set_Nonatomic_ReadWriteInExt_NoSynthesize; +@property(nonatomic,readonly) int None_Nonatomic_ReadWriteInExt_NoSynthesize; + +@end + + +@interface Foo () + +@property(readwrite) int GetSet_ReadWriteInExt; +@property(readwrite) int Get_ReadWriteInExt; +@property(readwrite) int Set_ReadWriteInExt; +@property(readwrite) int None_ReadWriteInExt; +@property(nonatomic,readwrite) int GetSet_Nonatomic_ReadWriteInExt; +@property(nonatomic,readwrite) int Get_Nonatomic_ReadWriteInExt; +@property(nonatomic,readwrite) int Set_Nonatomic_ReadWriteInExt; +@property(nonatomic,readwrite) int None_Nonatomic_ReadWriteInExt; + +@property(readwrite) int GetSet_ReadWriteInExt_LateSynthesize; +@property(readwrite) int Get_ReadWriteInExt_LateSynthesize; +@property(readwrite) int Set_ReadWriteInExt_LateSynthesize; +@property(readwrite) int None_ReadWriteInExt_LateSynthesize; +@property(nonatomic,readwrite) int GetSet_Nonatomic_ReadWriteInExt_LateSynthesize; +@property(nonatomic,readwrite) int Get_Nonatomic_ReadWriteInExt_LateSynthesize; +@property(nonatomic,readwrite) int Set_Nonatomic_ReadWriteInExt_LateSynthesize; +@property(nonatomic,readwrite) int None_Nonatomic_ReadWriteInExt_LateSynthesize; + +@property(readwrite) int GetSet_ReadWriteInExt_NoSynthesize; +@property(readwrite) int Get_ReadWriteInExt_NoSynthesize; +@property(readwrite) int Set_ReadWriteInExt_NoSynthesize; +@property(readwrite) int None_ReadWriteInExt_NoSynthesize; +@property(nonatomic,readwrite) int GetSet_Nonatomic_ReadWriteInExt_NoSynthesize; +@property(nonatomic,readwrite) int Get_Nonatomic_ReadWriteInExt_NoSynthesize; +@property(nonatomic,readwrite) int Set_Nonatomic_ReadWriteInExt_NoSynthesize; +@property(nonatomic,readwrite) int None_Nonatomic_ReadWriteInExt_NoSynthesize; + +@end + +@implementation Foo + +@synthesize GetSet, Get, Set, None, GetSet_Nonatomic, Get_Nonatomic, Set_Nonatomic, None_Nonatomic; +@synthesize GetSet_ReadOnly, Get_ReadOnly, Set_ReadOnly, None_ReadOnly, GetSet_Nonatomic_ReadOnly, Get_Nonatomic_ReadOnly, Set_Nonatomic_ReadOnly, None_Nonatomic_ReadOnly; +@synthesize GetSet_ReadWriteInExt, Get_ReadWriteInExt, Set_ReadWriteInExt, None_ReadWriteInExt, GetSet_Nonatomic_ReadWriteInExt, Get_Nonatomic_ReadWriteInExt, Set_Nonatomic_ReadWriteInExt, None_Nonatomic_ReadWriteInExt; + +#define GET(x) \ + -(int) x { return self->x; } +#define SET(x) \ + -(void) set##x:(int)value { self->x = value; } + +GET(GetSet) +SET(GetSet) +GET(Get) // expected-warning {{writable atomic property 'Get' cannot pair a synthesized setter with a user defined getter}} +SET(Set) // expected-warning {{writable atomic property 'Set' cannot pair a synthesized getter with a user defined setter}} +GET(GetSet_Nonatomic) +SET(GetSet_Nonatomic) +GET(Get_Nonatomic) +SET(Set_Nonatomic) + +GET(GetSet_ReadOnly) +SET(GetSet_ReadOnly) +GET(Get_ReadOnly) +SET(Set_ReadOnly) +GET(GetSet_Nonatomic_ReadOnly) +SET(GetSet_Nonatomic_ReadOnly) +GET(Get_Nonatomic_ReadOnly) +SET(Set_Nonatomic_ReadOnly) + +GET(GetSet_ReadWriteInExt) +SET(GetSet_ReadWriteInExt) +GET(Get_ReadWriteInExt) // expected-warning {{writable atomic property 'Get_ReadWriteInExt' cannot pair a synthesized setter with a user defined getter}} +SET(Set_ReadWriteInExt) // expected-warning {{writable atomic property 'Set_ReadWriteInExt' cannot pair a synthesized getter with a user defined setter}} +GET(GetSet_Nonatomic_ReadWriteInExt) +SET(GetSet_Nonatomic_ReadWriteInExt) +GET(Get_Nonatomic_ReadWriteInExt) +SET(Set_Nonatomic_ReadWriteInExt) + + +GET(GetSet_LateSynthesize) +SET(GetSet_LateSynthesize) +GET(Get_LateSynthesize) // expected-warning {{writable atomic property 'Get_LateSynthesize' cannot pair a synthesized setter with a user defined getter}} +SET(Set_LateSynthesize) // expected-warning {{writable atomic property 'Set_LateSynthesize' cannot pair a synthesized getter with a user defined setter}} +GET(GetSet_Nonatomic_LateSynthesize) +SET(GetSet_Nonatomic_LateSynthesize) +GET(Get_Nonatomic_LateSynthesize) +SET(Set_Nonatomic_LateSynthesize) + +GET(GetSet_ReadOnly_LateSynthesize) +SET(GetSet_ReadOnly_LateSynthesize) +GET(Get_ReadOnly_LateSynthesize) +SET(Set_ReadOnly_LateSynthesize) +GET(GetSet_Nonatomic_ReadOnly_LateSynthesize) +SET(GetSet_Nonatomic_ReadOnly_LateSynthesize) +GET(Get_Nonatomic_ReadOnly_LateSynthesize) +SET(Set_Nonatomic_ReadOnly_LateSynthesize) + +GET(GetSet_ReadWriteInExt_LateSynthesize) +SET(GetSet_ReadWriteInExt_LateSynthesize) +GET(Get_ReadWriteInExt_LateSynthesize) // expected-warning {{writable atomic property 'Get_ReadWriteInExt_LateSynthesize' cannot pair a synthesized setter with a user defined getter}} +SET(Set_ReadWriteInExt_LateSynthesize) // expected-warning {{writable atomic property 'Set_ReadWriteInExt_LateSynthesize' cannot pair a synthesized getter with a user defined setter}} +GET(GetSet_Nonatomic_ReadWriteInExt_LateSynthesize) +SET(GetSet_Nonatomic_ReadWriteInExt_LateSynthesize) +GET(Get_Nonatomic_ReadWriteInExt_LateSynthesize) +SET(Set_Nonatomic_ReadWriteInExt_LateSynthesize) + + +GET(GetSet_NoSynthesize) +SET(GetSet_NoSynthesize) +GET(Get_NoSynthesize) +SET(Set_NoSynthesize) +GET(GetSet_Nonatomic_NoSynthesize) +SET(GetSet_Nonatomic_NoSynthesize) +GET(Get_Nonatomic_NoSynthesize) +SET(Set_Nonatomic_NoSynthesize) + +GET(GetSet_ReadOnly_NoSynthesize) +SET(GetSet_ReadOnly_NoSynthesize) +GET(Get_ReadOnly_NoSynthesize) +SET(Set_ReadOnly_NoSynthesize) +GET(GetSet_Nonatomic_ReadOnly_NoSynthesize) +SET(GetSet_Nonatomic_ReadOnly_NoSynthesize) +GET(Get_Nonatomic_ReadOnly_NoSynthesize) +SET(Set_Nonatomic_ReadOnly_NoSynthesize) + +GET(GetSet_ReadWriteInExt_NoSynthesize) +SET(GetSet_ReadWriteInExt_NoSynthesize) +GET(Get_ReadWriteInExt_NoSynthesize) +SET(Set_ReadWriteInExt_NoSynthesize) +GET(GetSet_Nonatomic_ReadWriteInExt_NoSynthesize) +SET(GetSet_Nonatomic_ReadWriteInExt_NoSynthesize) +GET(Get_Nonatomic_ReadWriteInExt_NoSynthesize) +SET(Set_Nonatomic_ReadWriteInExt_NoSynthesize) + + +// late synthesize - follows getter/setter implementations + +@synthesize GetSet_LateSynthesize, Get_LateSynthesize, Set_LateSynthesize, None_LateSynthesize, GetSet_Nonatomic_LateSynthesize, Get_Nonatomic_LateSynthesize, Set_Nonatomic_LateSynthesize, None_Nonatomic_LateSynthesize; +@synthesize GetSet_ReadOnly_LateSynthesize, Get_ReadOnly_LateSynthesize, Set_ReadOnly_LateSynthesize, None_ReadOnly_LateSynthesize, GetSet_Nonatomic_ReadOnly_LateSynthesize, Get_Nonatomic_ReadOnly_LateSynthesize, Set_Nonatomic_ReadOnly_LateSynthesize, None_Nonatomic_ReadOnly_LateSynthesize; +@synthesize GetSet_ReadWriteInExt_LateSynthesize, Get_ReadWriteInExt_LateSynthesize, Set_ReadWriteInExt_LateSynthesize, None_ReadWriteInExt_LateSynthesize, GetSet_Nonatomic_ReadWriteInExt_LateSynthesize, Get_Nonatomic_ReadWriteInExt_LateSynthesize, Set_Nonatomic_ReadWriteInExt_LateSynthesize, None_Nonatomic_ReadWriteInExt_LateSynthesize; + +// no synthesize - use dynamic instead + +@dynamic GetSet_NoSynthesize, Get_NoSynthesize, Set_NoSynthesize, None_NoSynthesize, GetSet_Nonatomic_NoSynthesize, Get_Nonatomic_NoSynthesize, Set_Nonatomic_NoSynthesize, None_Nonatomic_NoSynthesize; +@dynamic GetSet_ReadOnly_NoSynthesize, Get_ReadOnly_NoSynthesize, Set_ReadOnly_NoSynthesize, None_ReadOnly_NoSynthesize, GetSet_Nonatomic_ReadOnly_NoSynthesize, Get_Nonatomic_ReadOnly_NoSynthesize, Set_Nonatomic_ReadOnly_NoSynthesize, None_Nonatomic_ReadOnly_NoSynthesize; +@dynamic GetSet_ReadWriteInExt_NoSynthesize, Get_ReadWriteInExt_NoSynthesize, Set_ReadWriteInExt_NoSynthesize, None_ReadWriteInExt_NoSynthesize, GetSet_Nonatomic_ReadWriteInExt_NoSynthesize, Get_Nonatomic_ReadWriteInExt_NoSynthesize, Set_Nonatomic_ReadWriteInExt_NoSynthesize, None_Nonatomic_ReadWriteInExt_NoSynthesize; + +@end + +/* +// the following method should cause a warning along the lines of +// :warning: Atomic property 'x' cannot pair a synthesized setter/getter with a manually implemented setter/getter +- (void) setX: (int) aValue +{ + x = aValue; +} + +// no warning 'cause this is nonatomic +- (void) setY: (int) aValue +{ + y = aValue; +} + +// the following method should cause a warning along the lines of +// :warning: Atomic property 'x' cannot pair a synthesized setter/getter with a manually implemented setter/getter +- (int) j +{ + return j; +} + +// no warning 'cause this is nonatomic +- (int) k +{ + return k; +} +@end +*/ +int main (int argc, const char * argv[]) { + return 0; +} diff --git a/clang/test/SemaObjC/attr-availability.m b/clang/test/SemaObjC/attr-availability.m new file mode 100644 index 0000000..d857bda --- /dev/null +++ b/clang/test/SemaObjC/attr-availability.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9.0.0 -fsyntax-only -verify %s +@interface A +- (void)method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); +@end + +@interface B : A +- (void)method; +@end + +void f(A *a, B *b) { + [a method]; // expected-warning{{'method' is deprecated: first deprecated in Mac OS X 10.2}} + [b method]; +} diff --git a/clang/test/SemaObjC/attr-cleanup.m b/clang/test/SemaObjC/attr-cleanup.m new file mode 100644 index 0000000..8415c69 --- /dev/null +++ b/clang/test/SemaObjC/attr-cleanup.m @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only + +@class NSString; + +void c1(id *a); + +void t1() +{ + NSString *s __attribute((cleanup(c1))); +} diff --git a/clang/test/SemaObjC/attr-deprecated.m b/clang/test/SemaObjC/attr-deprecated.m new file mode 100644 index 0000000..db0b958 --- /dev/null +++ b/clang/test/SemaObjC/attr-deprecated.m @@ -0,0 +1,123 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface A { + int X __attribute__((deprecated)); +} ++ (void)F __attribute__((deprecated)); +- (void)f __attribute__((deprecated)); +@end + +@implementation A ++ (void)F __attribute__((deprecated)) +{ + [self F]; // no warning, since the caller is also deprecated. +} + +- (void)g +{ + X++; // expected-warning{{'X' is deprecated}} + self->X++; // expected-warning{{'X' is deprecated}} + [self f]; // expected-warning{{'f' is deprecated}} +} + +- (void)f +{ + [self f]; // no warning, the caller is deprecated in its interface. +} +@end + +@interface B: A +@end + +@implementation B ++ (void)G +{ + [super F]; // expected-warning{{'F' is deprecated}} +} + +- (void)g +{ + [super f]; // // expected-warning{{'f' is deprecated}} +} +@end + +@protocol P +- (void)p __attribute__((deprecated)); +@end + +void t1(A *a) +{ + [A F]; // expected-warning{{'F' is deprecated}} + [a f]; // expected-warning{{'f' is deprecated}} +} + +void t2(id a) +{ + [a f]; +} + +void t3(A<P>* a) +{ + [a f]; // expected-warning{{'f' is deprecated}} + [a p]; // expected-warning{{'p' is deprecated}} +} + +void t4(Class c) +{ + [c F]; +} + + + +@interface Bar + +@property (assign, setter = MySetter:) int FooBar __attribute__ ((deprecated)); +- (void) MySetter : (int) value; +@end + +int t5() { + Bar *f; + f.FooBar = 1; // expected-warning {{'FooBar' is deprecated}} + return f.FooBar; // expected-warning {{'FooBar' is deprecated}} +} + + +__attribute ((deprecated)) +@interface DEPRECATED { + @public int ivar; + DEPRECATED *ivar2; // no warning. +} +- (int) instancemethod; +- (DEPRECATED *) meth; // no warning. +@property int prop; +@end + +@interface DEPRECATED (Category) // no warning. +- (DEPRECATED *) meth2; // no warning. +@end + +@interface DEPRECATED (Category2) // no warning. +@end + +@implementation DEPRECATED (Category2) // expected-warning {{'DEPRECATED' is deprecated}} +@end + +@interface NS : DEPRECATED // expected-warning {{'DEPRECATED' is deprecated}} +@end + + +@interface Test2 +@property int test2 __attribute__((deprecated)); +@end + +void test(Test2 *foo) { + int x; + x = foo.test2; // expected-warning {{'test2' is deprecated}} + x = [foo test2]; // expected-warning {{'test2' is deprecated}} + foo.test2 = x; // expected-warning {{'test2' is deprecated}} + [foo setTest2: x]; // expected-warning {{'setTest2:' is deprecated}} +} + +__attribute__((deprecated)) +@interface A(Blah) // expected-error{{attributes may not be specified on a category}} +@end diff --git a/clang/test/SemaObjC/attr-malloc.m b/clang/test/SemaObjC/attr-malloc.m new file mode 100644 index 0000000..a504b33 --- /dev/null +++ b/clang/test/SemaObjC/attr-malloc.m @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -fblocks %s + +@interface TestAttrMallocOnMethods {} +- (id) test1 __attribute((malloc)); // expected-warning {{functions returning a pointer type}} +- (int) test2 __attribute((malloc)); // expected-warning {{functions returning a pointer type}} +@end + +id bar(void) __attribute((malloc)); // no-warning + +typedef void (^bptr)(void); +bptr baz(void) __attribute((malloc)); // no-warning + +__attribute((malloc)) id (*f)(); // expected-warning {{functions returning a pointer type}} +__attribute((malloc)) bptr (*g)(); // expected-warning {{functions returning a pointer type}} +__attribute((malloc)) void *(^h)(); // expected-warning {{functions returning a pointer type}} + diff --git a/clang/test/SemaObjC/attr-ns-bridged.m b/clang/test/SemaObjC/attr-ns-bridged.m new file mode 100644 index 0000000..1ab60a2 --- /dev/null +++ b/clang/test/SemaObjC/attr-ns-bridged.m @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef struct __attribute__((ns_bridged)) test0s *test0ref; + +void test0func(void) __attribute__((ns_bridged)); // expected-error {{'ns_bridged' attribute only applies to structs}} + +union __attribute__((ns_bridged)) test0u; // expected-error {{'ns_bridged' attribute only applies to structs}} + +struct __attribute__((ns_bridged(Test1))) test1s; + +@class Test2; +struct __attribute__((ns_bridged(Test2))) test2s; + +void Test3(void); // expected-note {{declared here}} +struct __attribute__((ns_bridged(Test3))) test3s; // expected-error {{parameter of 'ns_bridged' attribute does not name an Objective-C class}} diff --git a/clang/test/SemaObjC/attr-objc-exception.m b/clang/test/SemaObjC/attr-objc-exception.m new file mode 100644 index 0000000..b497271 --- /dev/null +++ b/clang/test/SemaObjC/attr-objc-exception.m @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify + +__attribute__((__objc_exception__)) +@interface NSException { + int x; +} + +@end + + +__attribute__((__objc_exception__)) // expected-error {{attribute may only be applied to an Objective-C interface}} +int X; + +__attribute__((__objc_exception__)) // expected-error {{attribute may only be applied to an Objective-C interface}} +void foo(); + diff --git a/clang/test/SemaObjC/attr-objc-gc.m b/clang/test/SemaObjC/attr-objc-gc.m new file mode 100644 index 0000000..9ca12c9 --- /dev/null +++ b/clang/test/SemaObjC/attr-objc-gc.m @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify %s +static id __attribute((objc_gc(weak))) a; +static id __attribute((objc_gc(strong))) b; + +static id __attribute((objc_gc())) c; // expected-error{{'objc_gc' attribute requires parameter 1 to be a string}} +static id __attribute((objc_gc(123))) d; // expected-error{{'objc_gc' attribute requires parameter 1 to be a string}} +static id __attribute((objc_gc(foo, 456))) e; // expected-error{{attribute takes one argument}} +static id __attribute((objc_gc(hello))) f; // expected-warning{{'objc_gc' attribute argument not supported: 'hello'}} + +static int __attribute__((objc_gc(weak))) g; // expected-warning {{'objc_gc' only applies to pointer types; type here is 'int'}} + +static __weak int h; // expected-warning {{'__weak' only applies to pointer types; type here is 'int'}} + +// TODO: it would be great if this reported as __weak +#define WEAK __weak +static WEAK int h; // expected-warning {{'objc_gc' only applies to pointer types; type here is 'int'}} + +/* expected-warning {{'__weak' only applies to pointer types; type here is 'int'}}*/ static __we\ +ak int i; + +// rdar://problem/9126213 +void test2(id __attribute((objc_gc(strong))) *strong, + id __attribute((objc_gc(weak))) *weak) { + void *opaque; + opaque = strong; + strong = opaque; + + opaque = weak; + weak = opaque; +} diff --git a/clang/test/SemaObjC/attr-root-class.m b/clang/test/SemaObjC/attr-root-class.m new file mode 100644 index 0000000..195cd66 --- /dev/null +++ b/clang/test/SemaObjC/attr-root-class.m @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wattributes -Wobjc-root-class %s +@interface RootClass {} // expected-warning {{class 'RootClass' defined without specifying a base class}} \ + // expected-note {{add a super class to fix this problem}} +@end +@implementation RootClass +@end + +__attribute__((objc_root_class)) +@interface NonRootClass : RootClass // expected-error {{objc_root_class attribute may only be specified on a root class declaration}} +@end +@implementation NonRootClass +@end + +__attribute__((objc_root_class)) static void nonClassDeclaration() // expected-error {{attribute may only be applied to an Objective-C interface}} +{ +} diff --git a/clang/test/SemaObjC/autoreleasepool.m b/clang/test/SemaObjC/autoreleasepool.m new file mode 100644 index 0000000..45c749e --- /dev/null +++ b/clang/test/SemaObjC/autoreleasepool.m @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +void *objc_autoreleasepool_push(); +void autoreleasepool_pop(void*); + +@interface AUTORP @end + +@implementation AUTORP +- (void) unregisterTask:(id) task { + goto L; // expected-error {{goto into protected scope}} + + @autoreleasepool { // expected-note {{jump bypasses auto release push of @autoreleasepool block}} + void *tmp = objc_autoreleasepool_push(); + L: + autoreleasepool_pop(tmp); + @autoreleasepool { + return; + } + } +} +@end + diff --git a/clang/test/SemaObjC/bad-property-synthesis-crash.m b/clang/test/SemaObjC/bad-property-synthesis-crash.m new file mode 100644 index 0000000..ea4e004 --- /dev/null +++ b/clang/test/SemaObjC/bad-property-synthesis-crash.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://10177744 + +@interface Foo +@property (nonatomic, retain) NSString* what; // expected-error {{unknown type name 'NSString'}} \ + // expected-error {{property with}} \ + // expected-note {{previous definition is here}} +@end + +@implementation Foo +- (void) setWhat: (NSString*) value { // expected-error {{expected a type}} \ + // expected-warning {{conflicting parameter types in implementation of}} + __what; // expected-error {{use of undeclared identifier}} \ + // expected-warning {{expression result unused}} +} +@synthesize what; // expected-note 2 {{'what' declared here}} +@end + +@implementation Bar // expected-warning {{cannot find interface declaration for}} +- (NSString*) what { // expected-error {{expected a type}} + return __what; // expected-error {{use of undeclared identifier}} +} +@end diff --git a/clang/test/SemaObjC/bad-receiver-1.m b/clang/test/SemaObjC/bad-receiver-1.m new file mode 100644 index 0000000..fe3eecf --- /dev/null +++ b/clang/test/SemaObjC/bad-receiver-1.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface I +- (id) retain; +@end + +int objc_lookUpClass(const char*); + +void __raiseExc1() { + [objc_lookUpClass("NSString") retain]; // expected-warning {{receiver type 'int' is not 'id'}} \ + expected-warning {{method '-retain' not found}} +} + +typedef const struct __CFString * CFStringRef; + +void func() { + CFStringRef obj; + + [obj self]; // expected-warning {{receiver type 'CFStringRef' (aka 'const struct __CFString *') is not 'id'}} \\ + expected-warning {{method '-self' not found}} +} diff --git a/clang/test/SemaObjC/block-as-object.m b/clang/test/SemaObjC/block-as-object.m new file mode 100644 index 0000000..a85b606 --- /dev/null +++ b/clang/test/SemaObjC/block-as-object.m @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks + +@interface Whatever +- copy; +@end + +typedef long (^MyBlock)(id obj1, id obj2); + +void foo(MyBlock b) { + id bar = [b copy]; +} + +void foo2(id b) { +} + +void foo3(void (^block)(void)) { + foo2(block); + id x; + foo(x); +} diff --git a/clang/test/SemaObjC/block-attr.m b/clang/test/SemaObjC/block-attr.m new file mode 100644 index 0000000..80092fc --- /dev/null +++ b/clang/test/SemaObjC/block-attr.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -fobjc-gc-only %s +// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -fobjc-gc-only %s + +@interface Thing {} + +@property void(^someBlock)(void); // expected-warning {{'copy' attribute must be specified for the block property}} +@property(copy) void(^OK)(void); + +// rdar://8820813 +@property (readonly) void (^block)(void); // readonly property is OK + +@end diff --git a/clang/test/SemaObjC/block-explicit-return-type.m b/clang/test/SemaObjC/block-explicit-return-type.m new file mode 100644 index 0000000..22e5b6f --- /dev/null +++ b/clang/test/SemaObjC/block-explicit-return-type.m @@ -0,0 +1,77 @@ +// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks +// FIXME: should compile +// Test for blocks with explicit return type specified. + +typedef float * PF; +float gf; + +@interface NSView + - (id) some_method_that_returns_id; +@end + +NSView *some_object; + +void some_func (NSView * (^) (id)); + +typedef struct dispatch_item_s *dispatch_item_t; +typedef void (^completion_block_t)(void); + +typedef double (^myblock)(int); +double test(myblock I); + +int main() { + __block int x = 1; + __block int y = 2; + + (void)^void *{ return 0; }; + + (void)^float(float y){ return y; }; + + (void)^double (float y, double d) { + if (y) + return d; + else + return y; + }; + + const char * (^chb) (int flag, const char *arg, char *arg1) = ^ const char * (int flag, const char *arg, char *arg1) { + if (flag) + return 0; + if (flag == 1) + return arg; + else if (flag == 2) + return ""; + return arg1; + }; + + (void)^PF { return &gf; }; + + some_func(^ NSView * (id whatever) { return [some_object some_method_that_returns_id]; }); + + double res = test(^(int z){x = y+z; return (double)z; }); +} + +void func() { + completion_block_t X; + + completion_block_t (^blockx)(dispatch_item_t) = ^completion_block_t (dispatch_item_t item) { + return X; + }; + + completion_block_t (^blocky)(dispatch_item_t) = ^(dispatch_item_t item) { + return X; + }; + + blockx = blocky; +} + + +// intent: block taking int returning block that takes char,int and returns int +int (^(^block)(double x))(char, short); + +void foo() { + int one = 1; + block = ^(double x){ return ^(char c, short y) { return one + c + y; };}; // expected-error {{returning block that lives on the local stack}} + // or: + block = ^(double x){ return ^(char c, short y) { return one + (int)c + y; };}; // expected-error {{returning block that lives on the local stack}} +} diff --git a/clang/test/SemaObjC/block-id-as-block-argtype.m b/clang/test/SemaObjC/block-id-as-block-argtype.m new file mode 100644 index 0000000..20bb6ad --- /dev/null +++ b/clang/test/SemaObjC/block-id-as-block-argtype.m @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks +// rdar://10734265 + +@class NSObject; +typedef void (^block1_t)(int arg); +typedef void (^block2_t)(block1_t arg); +typedef void (^block3_t)(NSObject *arg); +typedef void (^block4_t)(id arg); + +void fn(block4_t arg); // expected-note {{passing argument to parameter 'arg' here}} + +void another_fn(block2_t arg); + +int main() { + block1_t b1; + block2_t b2; + block3_t b3; + block3_t b4; + block4_t b5; + + fn(b1); // expected-error {{incompatible block pointer types passing 'block1_t' (aka 'void (^)(int)') to parameter of type 'block4_t' (aka 'void (^)(id)')}} + fn(b2); // must succeed: block1_t *is* compatible with id + fn(b3); // succeeds: NSObject* compatible with id + fn(b4); // succeeds: id compatible with id + + another_fn(b5); +} diff --git a/clang/test/SemaObjC/block-ivar.m b/clang/test/SemaObjC/block-ivar.m new file mode 100644 index 0000000..c7ea1d9 --- /dev/null +++ b/clang/test/SemaObjC/block-ivar.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks + +@interface NSObject { + struct objc_object *isa; +} +@end +@interface Foo : NSObject { + int _prop; +} +@end + +@implementation Foo +- (int)doSomething { + int (^blk)(void) = ^{ return _prop; }; + return blk(); +} + +@end + diff --git a/clang/test/SemaObjC/block-on-method-param.m b/clang/test/SemaObjC/block-on-method-param.m new file mode 100644 index 0000000..d5cbc8a --- /dev/null +++ b/clang/test/SemaObjC/block-on-method-param.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s + +// rdar://10681443 +@interface I +- (void) compileSandboxProfileAndReturnError:(__attribute__((__blocks__(byref))) id)errorp; // expected-error {{__block attribute not allowed, only allowed on local variables}} +@end + +@implementation I +- (void) compileSandboxProfileAndReturnError:(__attribute__((__blocks__(byref))) id)errorp {} // expected-error {{__block attribute not allowed, only allowed on local variables}} +@end + diff --git a/clang/test/SemaObjC/block-return.m b/clang/test/SemaObjC/block-return.m new file mode 100644 index 0000000..15c3fb6 --- /dev/null +++ b/clang/test/SemaObjC/block-return.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -fobjc-gc-only %s +// rdar://8979379 + +@interface NSString +- (__attribute__((objc_gc(strong))) const char *)UTF8String; +@end + +int main() { +__attribute__((objc_gc(strong))) char const *(^libraryNameForIndex)() = ^() { + NSString *moduleName; + return [moduleName UTF8String]; + }; +} diff --git a/clang/test/SemaObjC/block-type-safety.m b/clang/test/SemaObjC/block-type-safety.m new file mode 100644 index 0000000..56342ba --- /dev/null +++ b/clang/test/SemaObjC/block-type-safety.m @@ -0,0 +1,157 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s +// test for block type safety. + +@interface Super @end +@interface Sub : Super @end + +void f2(void(^f)(Super *)) { // expected-note{{passing argument to parameter 'f' here}} + Super *o; + f(o); +} + +void f3(void(^f)(Sub *)) { + Sub *o; + f(o); +} + +void r0(Super* (^f)()) { + Super *o = f(); +} + +void r1(Sub* (^f)()) { // expected-note{{passing argument to parameter 'f' here}} + Sub *o = f(); +} + +@protocol NSObject; + +void r2 (id<NSObject> (^f) (void)) { + id o = f(); +} + +void test1() { + f2(^(Sub *o) { }); // expected-error {{incompatible block pointer types passing}} + f3(^(Super *o) { }); // OK, block taking Super* may be called with a Sub* + + r0(^Super* () { return 0; }); // OK + r0(^Sub* () { return 0; }); // OK, variable of type Super* gets return value of type Sub* + r0(^id () { return 0; }); + + r1(^Super* () { return 0; }); // expected-error {{incompatible block pointer types passing}} + r1(^Sub* () { return 0; }); // OK + r1(^id () { return 0; }); + + r2(^id<NSObject>() { return 0; }); +} + + +@interface A @end +@interface B @end + +void f0(void (^f)(A* x)) { + A* a; + f(a); +} + +void f1(void (^f)(id x)) { + B *b; + f(b); +} + +void test2(void) +{ + f0(^(id a) { }); // OK + f1(^(A* a) { }); + f1(^(id<NSObject> a) { }); // OK +} + +@interface NSArray + // Calls block() with every object in the array + -enumerateObjectsWithBlock:(void (^)(id obj))block; +@end + +@interface MyThing +-(void) printThing; +@end + +@implementation MyThing + static NSArray* myThings; // array of MyThing* + + -(void) printThing { } + +// programmer wants to write this: + -printMyThings1 { + [myThings enumerateObjectsWithBlock: ^(MyThing *obj) { + [obj printThing]; + }]; + } + +// strict type safety requires this: + -printMyThings { + [myThings enumerateObjectsWithBlock: ^(id obj) { + MyThing *obj2 = (MyThing *)obj; + [obj2 printThing]; + }]; + } +@end + +@protocol P, P2; +void f4(void (^f)(id<P> x)) { // expected-note{{passing argument to parameter 'f' here}} + NSArray<P2> *b; + f(b); // expected-warning {{passing 'NSArray<P2> *' to parameter of incompatible type 'id<P>'}} +} + +void test3() { + f4(^(NSArray<P2>* a) { }); // expected-error {{incompatible block pointer types passing 'void (^)(NSArray<P2> *)' to parameter of type 'void (^)(id<P>)'}} +} + +// rdar : //8302845 +@protocol Foo @end + +@interface Baz @end + +@interface Baz(FooConformance) <Foo> +@end + +@implementation Baz @end + +int test4 () { + id <Foo> (^b)() = ^{ // Doesn't work + return (Baz *)0; + }; + return 0; +} + +// rdar:// 9118343 + +@protocol NSCopying @end + +@interface NSAllArray <NSCopying> +@end + +@interface NSAllArray (FooConformance) <Foo> +@end + +int test5() { + NSAllArray *(^block)(id); + id <Foo> (^genericBlock)(id); + genericBlock = block; + return 0; +} + +// rdar://10798770 +typedef int NSInteger; + +typedef enum : NSInteger {NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending} NSComparisonResult; + +typedef NSComparisonResult (^NSComparator)(id obj1, id obj2); + +@interface radar10798770 +- (void)sortUsingComparator:(NSComparator)c; +@end + +void f() { + radar10798770 *f; + [f sortUsingComparator:^(id a, id b) { + return NSOrderedSame; + }]; +} diff --git a/clang/test/SemaObjC/blocks.m b/clang/test/SemaObjC/blocks.m new file mode 100644 index 0000000..7beec19 --- /dev/null +++ b/clang/test/SemaObjC/blocks.m @@ -0,0 +1,75 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s + +#define bool _Bool +@protocol NSObject; + +void bar(id(^)(void)); +void foo(id <NSObject>(^objectCreationBlock)(void)) { + return bar(objectCreationBlock); +} + +void bar2(id(*)(void)); +void foo2(id <NSObject>(*objectCreationBlock)(void)) { + return bar2(objectCreationBlock); +} + +void bar3(id(*)()); +void foo3(id (*objectCreationBlock)(int)) { + return bar3(objectCreationBlock); +} + +void bar4(id(^)()); +void foo4(id (^objectCreationBlock)(int)) { + return bar4(objectCreationBlock); +} + +void bar5(id(^)(void)); // expected-note 3{{passing argument to parameter here}} +void foo5(id (^objectCreationBlock)(bool)) { + bar5(objectCreationBlock); // expected-error {{incompatible block pointer types passing 'id (^)(bool)' to parameter of type 'id (^)(void)'}} +#undef bool + bar5(objectCreationBlock); // expected-error {{incompatible block pointer types passing 'id (^)(_Bool)' to parameter of type 'id (^)(void)'}} +#define bool int + bar5(objectCreationBlock); // expected-error {{incompatible block pointer types passing 'id (^)(_Bool)' to parameter of type 'id (^)(void)'}} +} + +void bar6(id(^)(int)); +void foo6(id (^objectCreationBlock)()) { + return bar6(objectCreationBlock); +} + +void foo7(id (^x)(int)) { + if (x) { } +} + +@interface itf +@end + +void foo8() { + void *P = ^(itf x) {}; // expected-error {{interface type 'itf' cannot be passed by value; did you forget * in 'itf'}} + P = ^itf(int x) {}; // expected-error {{interface type 'itf' cannot be returned by value; did you forget * in 'itf'}} + P = ^itf() {}; // expected-error {{interface type 'itf' cannot be returned by value; did you forget * in 'itf'}} + P = ^itf{}; // expected-error {{interface type 'itf' cannot be returned by value; did you forget * in 'itf'}} +} + + +int foo9() { + typedef void (^DVTOperationGroupScheduler)(); + id _suboperationSchedulers; + + for (DVTOperationGroupScheduler scheduler in _suboperationSchedulers) { + ; + } + +} + +// rdar 7725203 +@class NSString; + +extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); + +void foo10() { + void(^myBlock)(void) = ^{ + }; + NSLog(@"%@", myBlock); +} + diff --git a/clang/test/SemaObjC/builtin_objc_assign_ivar.m b/clang/test/SemaObjC/builtin_objc_assign_ivar.m new file mode 100644 index 0000000..5839bf4 --- /dev/null +++ b/clang/test/SemaObjC/builtin_objc_assign_ivar.m @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -x objective-c %s -fsyntax-only -verify +// rdar://9362887 + +typedef __typeof__(((int*)0)-((int*)0)) ptrdiff_t; +extern id objc_assign_ivar(id value, id dest, ptrdiff_t offset); + diff --git a/clang/test/SemaObjC/builtin_objc_lib_functions.m b/clang/test/SemaObjC/builtin_objc_lib_functions.m new file mode 100644 index 0000000..956ee12 --- /dev/null +++ b/clang/test/SemaObjC/builtin_objc_lib_functions.m @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -x objective-c %s -fsyntax-only -verify +// rdar://8592641 +Class f0() { return objc_getClass("a"); } // expected-warning {{implicitly declaring library function 'objc_getClass' with type 'id (const char *)'}} \ + // expected-note {{please include the header <objc/runtime.h> or explicitly provide a declaration for 'objc_getClass'}} + +// rdar://8735023 +Class f1() { return objc_getMetaClass("a"); } // expected-warning {{implicitly declaring library function 'objc_getMetaClass' with type 'id (const char *)'}} \ + // expected-note {{please include the header <objc/runtime.h> or explicitly provide a declaration for 'objc_getMetaClass'}} + +void f2(id val) { objc_enumerationMutation(val); } // expected-warning {{implicitly declaring library function 'objc_enumerationMutation' with type 'void (id)'}} \ + // expected-note {{please include the header <objc/runtime.h> or explicitly provide a declaration for 'objc_enumerationMutation'}} + +long double f3(id self, SEL op) { return objc_msgSend_fpret(self, op); } // expected-warning {{implicitly declaring library function 'objc_msgSend_fpret' with type 'long double (id, SEL, ...)'}} \ + // expected-note {{please include the header <objc/message.h> or explicitly provide a declaration for 'objc_msgSend_fpret'}} + +id f4(struct objc_super *super, SEL op) { // expected-warning {{declaration of 'struct objc_super' will not be visible outside of this function}} + return objc_msgSendSuper(super, op); // expected-warning {{implicitly declaring library function 'objc_msgSendSuper' with type 'id (void *, SEL, ...)'}} \ + // expected-note {{please include the header <objc/message.h> or explicitly provide a declaration for 'objc_msgSendSuper'}} +} + +id f5(id val, id *dest) { + return objc_assign_strongCast(val, dest); // expected-warning {{implicitly declaring library function 'objc_assign_strongCast' with type 'id (id, id *)'}} \ + // expected-note {{please include the header <objc/objc-auto.h> or explicitly provide a declaration for 'objc_assign_strongCast'}} +} + +int f6(Class exceptionClass, id exception) { + return objc_exception_match(exceptionClass, exception); // expected-warning {{implicitly declaring library function 'objc_exception_match' with type 'int (id, id)'}} \ + // expected-note {{please include the header <objc/objc-exception.h> or explicitly provide a declaration for 'objc_exception_match'}} +} diff --git a/clang/test/SemaObjC/builtin_objc_msgSend.m b/clang/test/SemaObjC/builtin_objc_msgSend.m new file mode 100644 index 0000000..bf17225 --- /dev/null +++ b/clang/test/SemaObjC/builtin_objc_msgSend.m @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify +// rdar://8632525 +extern id objc_msgSend(id self, SEL op, ...); diff --git a/clang/test/SemaObjC/builtin_objc_nslog.m b/clang/test/SemaObjC/builtin_objc_nslog.m new file mode 100644 index 0000000..c940b16 --- /dev/null +++ b/clang/test/SemaObjC/builtin_objc_nslog.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -x objective-c %s -fsyntax-only -verify + +#include <stdarg.h> + +void f1(id arg) { + NSLog(@"%@", arg); // expected-warning {{implicitly declaring library function 'NSLog' with type 'void (id, ...)'}} \ + // expected-note {{please include the header <Foundation/NSObjCRuntime.h> or explicitly provide a declaration for 'NSLog'}} +} + +void f2(id str, va_list args) { + NSLogv(@"%@", args); // expected-warning {{implicitly declaring library function 'NSLogv' with type }} \ + // expected-note {{please include the header <Foundation/NSObjCRuntime.h> or explicitly provide a declaration for 'NSLogv'}} +} diff --git a/clang/test/SemaObjC/call-super-2.m b/clang/test/SemaObjC/call-super-2.m new file mode 100644 index 0000000..3c45a2c --- /dev/null +++ b/clang/test/SemaObjC/call-super-2.m @@ -0,0 +1,108 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#include <stddef.h> + +typedef struct objc_object *id; +id objc_getClass(const char *s); + +@interface Object +- (id) initWithInt: (int) i; +@end + +@protocol Func ++ (int) class_func0; +- (int) instance_func0; +@end + +@interface Derived: Object ++ (int) class_func1; ++ (int) class_func2; ++ (int) class_func3; ++ (int) class_func4; ++ (int) class_func5; ++ (int) class_func6; ++ (int) class_func7; +- (int) instance_func1; +- (int) instance_func2; +- (int) instance_func3; +- (int) instance_func4; +- (int) instance_func5; +- (int) instance_func6; +- (int) instance_func7; +- (id) initWithInt: (int) i; +@end + +@implementation Derived ++ (int) class_func1 +{ + int i = (size_t)[self class_func0]; // expected-warning {{class method '+class_func0' not found (return type defaults to 'id')}} + return i + (size_t)[super class_func0]; // expected-warning {{class method '+class_func0' not found (return type defaults to 'id')}} +} ++ (int) class_func2 +{ + int i = [(id <Func>)self class_func0]; + i += [(id <Func>)super class_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}} + i += [(Class <Func>)self class_func0]; // + return i + [(Class <Func>)super class_func0]; // // expected-error {{cannot cast 'super' (it isn't an expression)}} +} ++ (int) class_func3 +{ + return [(Object <Func> *)super class_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}} +} ++ (int) class_func4 +{ + return [(Derived <Func> *)super class_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}} +} ++ (int) class_func5 +{ + int i = (size_t)[Derived class_func0]; // expected-warning {{class method '+class_func0' not found (return type defaults to 'id')}} + return i + (size_t)[Object class_func0]; // expected-warning {{class method '+class_func0' not found (return type defaults to 'id')}} +} ++ (int) class_func6 +{ + return (size_t)[objc_getClass("Object") class_func1]; // GCC warns about this +} ++ (int) class_func7 +{ + return [objc_getClass("Derived") class_func1]; +} +- (int) instance_func1 +{ + int i = (size_t)[self instance_func0]; // expected-warning {{instance method '-instance_func0' not found (return type defaults to 'id')}} + return i + (size_t)[super instance_func0]; // expected-warning {{'Object' may not respond to 'instance_func0'}} +} +- (int) instance_func2 +{ + return [(id <Func>)super instance_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}} +} +- (int) instance_func3 +{ + return [(Object <Func> *)super instance_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}} +} +- (int) instance_func4 +{ + return [(Derived <Func> *)super instance_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}} +} +- (int) instance_func5 +{ + int i = (size_t)[Derived instance_func1]; // expected-warning {{class method '+instance_func1' not found (return type defaults to 'id')}} + return i + (size_t)[Object instance_func1]; // expected-warning {{class method '+instance_func1' not found (return type defaults to 'id')}} +} +- (int) instance_func6 +{ + return (size_t)[objc_getClass("Object") class_func1]; +} +- (int) instance_func7 +{ + return [objc_getClass("Derived") class_func1]; +} +- (id) initWithInt: (int) i +{ + // Don't warn about parentheses here. + if (self = [super initWithInt: i]) { + [self instance_func1]; + } + return self; +} +@end + diff --git a/clang/test/SemaObjC/catch-stmt.m b/clang/test/SemaObjC/catch-stmt.m new file mode 100644 index 0000000..dcb4764 --- /dev/null +++ b/clang/test/SemaObjC/catch-stmt.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -verify -fobjc-exceptions %s +@interface A @end +@protocol P; + +void f() { + @try { + } @catch (void a) { // expected-error{{@catch parameter is not a pointer to an interface type}} + } @catch (int) { // expected-error{{@catch parameter is not a pointer to an interface type}} + } @catch (int *b) { // expected-error{{@catch parameter is not a pointer to an interface type}} + } @catch (id <P> c) { // expected-error{{illegal qualifiers on @catch parameter}} + } @catch(A* a) { } +} + diff --git a/clang/test/SemaObjC/category-1.m b/clang/test/SemaObjC/category-1.m new file mode 100644 index 0000000..f842278 --- /dev/null +++ b/clang/test/SemaObjC/category-1.m @@ -0,0 +1,101 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface MyClass1 @end + +@protocol p1,p2,p3; + +@interface MyClass1 (Category1) <p1> // expected-warning {{cannot find protocol definition for 'p1'}} expected-note {{previous definition is here}} +@end + +@interface MyClass1 (Category1) // expected-warning {{duplicate definition of category 'Category1' on interface 'MyClass1'}} +@end + +@interface MyClass1 (Category3) +@end + +@interface MyClass1 (Category4) @end // expected-note {{previous definition is here}} +@interface MyClass1 (Category5) @end +@interface MyClass1 (Category6) @end +@interface MyClass1 (Category7) @end // expected-note {{previous definition is here}} +@interface MyClass1 (Category8) @end // expected-note {{previous definition is here}} + + +@interface MyClass1 (Category4) @end // expected-warning {{duplicate definition of category 'Category4' on interface 'MyClass1'}} +@interface MyClass1 (Category7) @end // expected-warning {{duplicate definition of category 'Category7' on interface 'MyClass1'}} +@interface MyClass1 (Category8) @end // expected-warning {{duplicate definition of category 'Category8' on interface 'MyClass1'}} + + +@protocol p3 @end + +@interface MyClass1 (Category) <p2, p3> @end // expected-warning {{cannot find protocol definition for 'p2'}} + +@interface UnknownClass (Category) @end // expected-error {{cannot find interface declaration for 'UnknownClass'}} + +@class MyClass2; // expected-note{{forward declaration of class here}} + +@interface MyClass2 (Category) @end // expected-error {{cannot define category for undefined class 'MyClass2'}} + +@interface XCRemoteComputerManager +@end + +@interface XCRemoteComputerManager() +@end + +@interface XCRemoteComputerManager() +@end + +@interface XCRemoteComputerManager(x) // expected-note {{previous definition is here}} +@end + +@interface XCRemoteComputerManager(x) // expected-warning {{duplicate definition of category 'x' on interface 'XCRemoteComputerManager'}} +@end + +@implementation XCRemoteComputerManager +@end + +@implementation XCRemoteComputerManager(x) // expected-note {{previous definition is here}} +@end + +@implementation XCRemoteComputerManager(x) // expected-error {{reimplementation of category 'x' for class 'XCRemoteComputerManager'}} +@end + +// <rdar://problem/7249233> + +@protocol MultipleCat_P +-(void) im0; // expected-note {{method 'im0' declared here}} +@end + +@interface MultipleCat_I @end // expected-note {{required for direct or indirect protocol 'MultipleCat_P'}} + +@interface MultipleCat_I() @end + +@interface MultipleCat_I() <MultipleCat_P> @end + +@implementation MultipleCat_I // expected-warning {{incomplete implementation}} \ + // expected-warning {{method 'im0' in protocol not implemented}} +@end + +// <rdar://problem/7680391> - Handle nameless categories with no name that refer +// to an undefined class +@interface RDar7680391 () @end // expected-error{{cannot find interface declaration}} + +// <rdar://problem/8891119> - Handle @synthesize being used in conjunction +// with explicitly declared accessor. +@interface RDar8891119 { + id _name; +} +@end +@interface RDar8891119 () +- (id)name; +@end +@interface RDar8891119 () +@property (copy) id name; +@end +@implementation RDar8891119 +@synthesize name = _name; +@end + +// rdar://10968158 +@class I; // expected-note {{forward declaration}} +@implementation I(cat) // expected-error{{cannot find interface declaration}} +@end diff --git a/clang/test/SemaObjC/category-method-lookup-2.m b/clang/test/SemaObjC/category-method-lookup-2.m new file mode 100644 index 0000000..a31d824 --- /dev/null +++ b/clang/test/SemaObjC/category-method-lookup-2.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef struct objc_class *Class; +@interface NSObject +- (Class)class; +@end +@interface Bar : NSObject +@end +@interface Bar (Cat) +@end + +// NOTE: No class implementation for Bar precedes this category definition. +@implementation Bar (Cat) + +// private method. ++ classMethod { return self; } + +- instanceMethod { + [[self class] classMethod]; + return 0; +} + +@end diff --git a/clang/test/SemaObjC/category-method-lookup.m b/clang/test/SemaObjC/category-method-lookup.m new file mode 100644 index 0000000..4223a74 --- /dev/null +++ b/clang/test/SemaObjC/category-method-lookup.m @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface Foo +@end +@implementation Foo +@end + +@implementation Foo(Whatever) ++(float)returnsFloat { return 7.0; } +@end + +@interface Foo (MoreStuff) ++(int)returnsInt; +@end + +@implementation Foo (MoreStuff) ++(int)returnsInt { + return 0; +} + ++(void)returnsNothing { +} +-(int)callsReturnsInt { + float f = [Foo returnsFloat]; // GCC doesn't find this method (which is a bug IMHO). + [Foo returnsNothing]; + return [Foo returnsInt]; +} +@end + +int main() {return 0;} + diff --git a/clang/test/SemaObjC/check-dup-decl-methods-1.m b/clang/test/SemaObjC/check-dup-decl-methods-1.m new file mode 100644 index 0000000..3895667 --- /dev/null +++ b/clang/test/SemaObjC/check-dup-decl-methods-1.m @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -Wduplicate-method-match -fsyntax-only -verify %s + +@interface SUPER +- (int) meth; ++ (int) foobar; +@end + +@interface T @end + +@interface class1 : SUPER +- (int) meth; // expected-note {{previous declaration is here}} +- (int*) meth; // expected-error {{duplicate declaration of method 'meth'}} +- (T*) meth1; // expected-note {{previous declaration is here}} +- (T*) meth1; // expected-warning {{multiple declarations of method 'meth1' found and ignored}} ++ (T*) meth1; +@end + +@interface class1(cat) +- (int) catm : (char)ch1; // expected-note {{previous declaration is here}} +- (int) catm1 : (char)ch : (int)i; +- (int) catm : (char*)ch1; // expected-error {{duplicate declaration of method 'catm:'}} ++ (int) catm1 : (char)ch : (int)i; ++ (T*) meth1; +@end + +@interface class1(cat1) ++ (int) catm1 : (char)ch : (int)i; // expected-note {{previous declaration is here}} ++ (T*) meth1; // expected-note {{previous declaration is here}} ++ (int) catm1 : (char)ch : (int*)i; // expected-error {{duplicate declaration of method 'catm1::'}} ++ (T**) meth1; // expected-error {{duplicate declaration of method 'meth1'}} ++ (int) foobar; +@end + +@protocol P +- (int) meth; // expected-note {{previous declaration is here}} +- (int*) meth; // expected-error {{duplicate declaration of method 'meth'}} +@end + diff --git a/clang/test/SemaObjC/check-dup-objc-decls-1.m b/clang/test/SemaObjC/check-dup-objc-decls-1.m new file mode 100644 index 0000000..d6fa53a --- /dev/null +++ b/clang/test/SemaObjC/check-dup-objc-decls-1.m @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface Foo // expected-note {{previous definition is here}} +@end + +float Foo; // expected-error {{redefinition of 'Foo' as different kind of symbol}} + +@class Bar; // expected-note {{previous definition is here}} + +typedef int Bar; // expected-error {{redefinition of 'Bar' as different kind of symbol}} + +@implementation FooBar // expected-warning {{cannot find interface declaration for 'FooBar'}} +@end + + +typedef int OBJECT; // expected-note {{previous definition is here}} + +@class OBJECT ; // expected-error {{redefinition of 'OBJECT' as different kind of symbol}} + + +typedef int Gorf; // expected-note {{previous definition is here}} + +@interface Gorf @end // expected-error {{redefinition of 'Gorf' as different kind of symbol}} expected-note {{previous definition is here}} + +void Gorf() // expected-error {{redefinition of 'Gorf' as different kind of symbol}} +{ + int Bar, Foo, FooBar; +} + +@protocol P -im1; @end +@protocol Q -im2; @end +@interface A<P> @end // expected-note {{previous definition is here}} +@interface A<Q> @end // expected-error {{duplicate interface definition for class 'A'}} + +@protocol PP<P> @end // expected-note {{previous definition is here}} +@protocol PP<Q> @end // expected-warning {{duplicate protocol definition of 'PP'}} + +@interface A(Cat)<P> @end // expected-note {{previous definition is here}} +@interface A(Cat)<Q> @end // expected-warning {{duplicate definition of category 'Cat' on interface 'A'}} + +// rdar 7626768 +@class NSString; +NSString * TestBaz; // expected-note {{previous definition is here}} +NSString * const TestBaz; // expected-error {{redefinition of 'TestBaz' with a different type}} diff --git a/clang/test/SemaObjC/class-bitfield.m b/clang/test/SemaObjC/class-bitfield.m new file mode 100644 index 0000000..ae12e04 --- /dev/null +++ b/clang/test/SemaObjC/class-bitfield.m @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 %s -fobjc-fragile-abi -fsyntax-only -verify + +@interface X +{ + int a : -1; // expected-error{{bit-field 'a' has negative width}} + + // rdar://6081627 + int b : 33; // expected-error{{size of bit-field 'b' (33 bits) exceeds size of its type (32 bits)}} + + int c : (1 + 0.25); // expected-error{{expression is not an integer constant expression}} + int d : (int)(1 + 0.25); + + // rdar://6138816 + int e : 0; // expected-error {{bit-field 'e' has zero width}} +} +@end + +@interface Base { + int i; +} +@end + +@interface WithBitFields: Base { + void *isa; // expected-note {{previous definition is here}} + unsigned a: 5; + signed b: 4; + int c: 5; // expected-note {{previous definition is here}} +} +@end + +@implementation WithBitFields { + char *isa; // expected-error {{instance variable 'isa' has conflicting type: 'char *' vs 'void *'}} + unsigned a: 5; + signed b: 4; + int c: 3; // expected-error {{instance variable 'c' has conflicting bit-field width}} +} +@end diff --git a/clang/test/SemaObjC/class-conforming-protocol-1.m b/clang/test/SemaObjC/class-conforming-protocol-1.m new file mode 100644 index 0000000..115ddd2 --- /dev/null +++ b/clang/test/SemaObjC/class-conforming-protocol-1.m @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -Wduplicate-method-match -fsyntax-only -verify %s + +@protocol P1 @end +@protocol P2 @end +@protocol P3 @end + +@interface INTF +- (INTF*) METH1; // expected-note {{previous declaration is here}} +- (INTF<P1>*) METH1; // expected-error {{duplicate declaration of method 'METH1'}} + +- (INTF<P2,P1>*) METH2; // expected-note {{previous declaration is here}} +- (INTF<P2,P1,P3>*) METH2; // expected-error {{duplicate declaration of method 'METH2'}} + +- (INTF<P2,P1,P3>*) METH3; // expected-note {{previous declaration is here}} +- (INTF<P3,P1,P2, P3>*) METH3; // expected-warning {{multiple declarations of method 'METH3' found and ignored}} + +@end + +INTF<P2,P1,P3>* p1; + diff --git a/clang/test/SemaObjC/class-conforming-protocol-2.m b/clang/test/SemaObjC/class-conforming-protocol-2.m new file mode 100644 index 0000000..a3bd0b1 --- /dev/null +++ b/clang/test/SemaObjC/class-conforming-protocol-2.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -Wmethod-signatures -fsyntax-only -verify %s + +@protocol NSWindowDelegate @end + +@protocol IBStringsTableWindowDelegate <NSWindowDelegate> +@end + +@interface NSWindow +- (void)setDelegate:(id <NSWindowDelegate>)anObject; // expected-note {{previous definition is here}} +- (id <IBStringsTableWindowDelegate>) delegate; // expected-note {{previous definition is here}} +@end + + +@interface IBStringsTableWindow : NSWindow {} +@end + +@implementation IBStringsTableWindow +- (void)setDelegate:(id <IBStringsTableWindowDelegate>)delegate { // expected-warning {{conflicting parameter types in implementation of 'setDelegate:'}} +} +- (id <NSWindowDelegate>)delegate { // expected-warning {{conflicting return type in implementation of 'delegate':}} + return 0; +} +@end diff --git a/clang/test/SemaObjC/class-def-test-1.m b/clang/test/SemaObjC/class-def-test-1.m new file mode 100644 index 0000000..0d114b9 --- /dev/null +++ b/clang/test/SemaObjC/class-def-test-1.m @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@protocol SUPER; + +@interface SUPER <SUPER> @end // expected-warning {{cannot find protocol definition for 'SUPER'}} + +typedef int INTF; // expected-note {{previous definition is here}} + +@interface INTF @end // expected-error {{redefinition of 'INTF' as different kind of symbol}} + +@interface OBJECT @end // expected-note {{previous definition is here}} + +@interface INTF1 : OBJECT @end // expected-note {{previous definition is here}} + +@interface INTF1 : OBJECT @end // expected-error {{duplicate interface definition for class 'INTF1'}} + +typedef int OBJECT; // expected-error {{redefinition of 'OBJECT' as different kind of symbol}} + +typedef int OBJECT2; // expected-note {{previous definition is here}} +@interface INTF2 : OBJECT2 @end // expected-error {{redefinition of 'OBJECT2' as different kind of symbol}} + + +@protocol PROTO; + +@interface INTF3 : PROTO @end // expected-error {{cannot find interface declaration for 'PROTO', superclass of 'INTF3'}} + +// Make sure we allow the following (for GCC compatibility). +@interface NSObject @end +typedef NSObject TD_NSObject; +@interface XCElementUnit : TD_NSObject {} +@end + +// Make sure we don't typo-correct to ourselves. +@interface SomeClassSub : SomeClassSup // expected-error{{cannot find interface declaration for 'SomeClassSup', superclass of 'SomeClassSub'}} +@end diff --git a/clang/test/SemaObjC/class-extension-after-implementation.m b/clang/test/SemaObjC/class-extension-after-implementation.m new file mode 100644 index 0000000..ccfd3ef --- /dev/null +++ b/clang/test/SemaObjC/class-extension-after-implementation.m @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://7822210 + +@interface A @end + +@implementation A @end // expected-note {{class implementation is declared here}} + +@interface A () // expected-error {{cannot declare class extension for 'A' after class implementation}} +-(void) im0; +@end + diff --git a/clang/test/SemaObjC/class-extension-dup-methods.m b/clang/test/SemaObjC/class-extension-dup-methods.m new file mode 100644 index 0000000..692ff8c --- /dev/null +++ b/clang/test/SemaObjC/class-extension-dup-methods.m @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface Foo +- (int) garf; // expected-note {{previous declaration is here}} +- (int) OK; ++ (int) cgarf; // expected-note {{previous declaration is here}} +- (int) InstMeth; +@end + +@interface Foo() +- (void) garf; // expected-error {{duplicate declaration of method 'garf'}} ++ (void) cgarf; // expected-error {{duplicate declaration of method 'cgarf'}} ++ (int) InstMeth; +- (int) OK; +@end diff --git a/clang/test/SemaObjC/class-getter-using-dotsyntax.m b/clang/test/SemaObjC/class-getter-using-dotsyntax.m new file mode 100644 index 0000000..4ff9428 --- /dev/null +++ b/clang/test/SemaObjC/class-getter-using-dotsyntax.m @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +typedef struct objc_class *Class; + +struct objc_class { + Class isa; +}; + +typedef struct objc_object { + Class isa; +} *id; + +@interface XCActivityLogSection ++ (unsigned)serializationFormatVersion; ++ (unsigned)sectionByDeserializingData; ++ (Class)retursClass; +@end + +@implementation XCActivityLogSection + ++ (unsigned)serializationFormatVersion +{ + + return 0; +} ++ (unsigned)sectionByDeserializingData { + unsigned version; + return self.serializationFormatVersion; +} + ++ (Class)retursClass { + Class version; + // FIXIT. (*version).isa does not work. Results in compiler error. + return version->isa; +} + +@end + + diff --git a/clang/test/SemaObjC/class-impl-1.m b/clang/test/SemaObjC/class-impl-1.m new file mode 100644 index 0000000..68becaf --- /dev/null +++ b/clang/test/SemaObjC/class-impl-1.m @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +typedef int INTF3; // expected-note {{previous definition is here}} + +@interface SUPER @end // expected-note {{previous definition is here}} + +@interface OBJECT @end + +@interface INTF : OBJECT +@end + +@implementation INTF @end // expected-note {{previous definition is here}} + +@implementation INTF // expected-error {{reimplementation of class 'INTF'}} +@end + + +@interface INTF1 : OBJECT +@end + +@implementation INTF1 : SUPER // expected-error {{conflicting super class name 'SUPER'}} +@end + +@interface INTF2 +@end + +@implementation INTF2 : SUPR // expected-error {{cannot find interface declaration for 'SUPR', superclass of 'INTF2'}} +@end + +@implementation INTF3 @end // expected-error {{redefinition of 'INTF3' as different kind of symbol}} + +@implementation INTF4 @end // expected-warning {{cannot find interface declaration for 'INTF4'}} + +@class INTF5; // expected-note{{forward declaration of class here}} + +@implementation INTF5 { // expected-warning {{cannot find interface declaration for 'INTF5'}} + int x; +} +@end + diff --git a/clang/test/SemaObjC/class-message-protocol-lookup.m b/clang/test/SemaObjC/class-message-protocol-lookup.m new file mode 100644 index 0000000..37df7a6 --- /dev/null +++ b/clang/test/SemaObjC/class-message-protocol-lookup.m @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://9224670 + +@interface RandomObject { +@private +} ++ (id)alloc; +@end + +@protocol TestProtocol +- (void)nothingInteresting; +@end + +@protocol Test2Protocol ++ (id)alloc; +- (id)alloc2; // expected-note 2 {{method 'alloc2' declared here}} +@end + +@implementation RandomObject +- (void) Meth { + Class<TestProtocol> c = [c alloc]; // expected-warning {{class method '+alloc' not found (return type defaults to 'id')}} + Class<Test2Protocol> c1 = [c1 alloc2]; // expected-warning {{instance method 'alloc2' found instead of class method 'alloc2'}} + Class<Test2Protocol> c2 = [c2 alloc]; // ok +} ++ (id)alloc { return 0; } +@end + +int main () +{ + Class<TestProtocol> c = [c alloc]; // expected-warning {{class method '+alloc' not found (return type defaults to 'id')}} + Class<Test2Protocol> c1 = [c1 alloc2]; // expected-warning {{instance method 'alloc2' found instead of class method 'alloc2'}} + Class<Test2Protocol> c2 = [c2 alloc]; // ok + return 0; +} diff --git a/clang/test/SemaObjC/class-method-lookup.m b/clang/test/SemaObjC/class-method-lookup.m new file mode 100644 index 0000000..8c8c216 --- /dev/null +++ b/clang/test/SemaObjC/class-method-lookup.m @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface MyBase +- (void) rootInstanceMethod; +@end + +@interface MyIntermediate: MyBase +@end + +@interface MyDerived: MyIntermediate +- (void) instanceMethod; ++ (void) classMethod; +@end + +@implementation MyDerived +- (void) instanceMethod { +} + ++ (void) classMethod { /* If a class method is not found, the root */ + [self rootInstanceMethod]; /* class is searched for an instance method */ + [MyIntermediate rootInstanceMethod]; /* with the same name. */ + + [self instanceMethod];// expected-warning {{'+instanceMethod' not found (return type defaults to 'id')}} + [MyDerived instanceMethod];// expected-warning {{'+instanceMethod' not found (return type defaults to 'id')}} +} +@end + +@interface Object @end + +@interface Class1 +- (void)setWindow:(Object *)wdw; +@end + +@interface Class2 +- (void)setWindow:(Class1 *)window; +@end + +#define nil (void*)0 + +id foo(void) { + Object *obj; + id obj2 = obj; + [obj setWindow:nil]; // expected-warning {{'Object' may not respond to 'setWindow:'}} + + return obj; +} diff --git a/clang/test/SemaObjC/class-method-self.m b/clang/test/SemaObjC/class-method-self.m new file mode 100644 index 0000000..b1e37bf --- /dev/null +++ b/clang/test/SemaObjC/class-method-self.m @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -verify -Wno-objc-root-class %s + +typedef struct objc_class *Class; +@interface XX + +- (void)addObserver:(XX*)o; // expected-note 2{{passing argument to parameter 'o' here}} + +@end + +@interface YY + ++ (void)classMethod; + +@end + +@implementation YY + +static XX *obj; + ++ (void)classMethod { + [obj addObserver:self]; // expected-warning {{incompatible pointer types sending 'Class' to parameter of type 'XX *'}} + Class whatever; + [obj addObserver:whatever]; // expected-warning {{incompatible pointer types sending 'Class' to parameter of type 'XX *'}} +} +@end + diff --git a/clang/test/SemaObjC/class-property-access.m b/clang/test/SemaObjC/class-property-access.m new file mode 100644 index 0000000..c46d3fb --- /dev/null +++ b/clang/test/SemaObjC/class-property-access.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface Test {} ++ (Test*)one; +- (int)two; +@end + +int main () +{ + return Test.one.two; +} + diff --git a/clang/test/SemaObjC/class-proto-1.m b/clang/test/SemaObjC/class-proto-1.m new file mode 100644 index 0000000..02c40aa --- /dev/null +++ b/clang/test/SemaObjC/class-proto-1.m @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface INTF1 @end + +@protocol p1,p2,p3; + +@protocol p1; + +@protocol PROTO1 +- (INTF1<p1>*) meth; +@end + +@protocol p1 @end + +@interface I1 <p1> @end + +@interface E1 <p2> @end // expected-warning {{cannot find protocol definition for 'p2'}} + +@protocol p2 @end + + +@interface I2 <p1,p2> @end + +@interface E2 <p1,p2,p3> @end // expected-warning {{cannot find protocol definition for 'p3'}} + +@class U1, U2; // expected-note {{forward declaration of class here}} + +@interface E3 : U1 @end // expected-error {{attempting to use the forward class 'U1' as superclass of 'E3'}} + + +@interface I3 : E3 @end + +@interface U2 @end + +@interface I4 : U2 <p1,p2> +@end diff --git a/clang/test/SemaObjC/class-protocol-method-match.m b/clang/test/SemaObjC/class-protocol-method-match.m new file mode 100644 index 0000000..7c936e6 --- /dev/null +++ b/clang/test/SemaObjC/class-protocol-method-match.m @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -Woverriding-method-mismatch -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://9352731 + +@protocol Bar +@required +- (bycopy id)bud; // expected-note {{previous declaration is here}} +- (unsigned char) baz; // expected-note {{previous declaration is here}} +- (char) ok; +- (void) also_ok; +@end + +@protocol Bar1 +@required +- (unsigned char) baz; // expected-note {{previous declaration is here}} +- (unsigned char) also_ok; // expected-note {{previous declaration is here}} +- (void) ban : (int) arg, ...; // expected-note {{previous declaration is here}} +@end + +@protocol Baz <Bar, Bar1> +- (void) bar : (unsigned char)arg; // expected-note {{previous declaration is here}} +- (void) ok; +- (char) bak; // expected-note {{previous declaration is here}} +@end + +@interface Foo <Baz> +- (id)bud; // expected-warning {{conflicting distributed object modifiers on return type in declaration of 'bud'}} +- (void) baz; // expected-warning 2 {{conflicting return type in declaration of 'baz': 'unsigned char' vs 'void'}} +- (void) bar : (unsigned char*)arg; // expected-warning {{conflicting parameter types in declaration of 'bar:': 'unsigned char' vs 'unsigned char *'}} +- (void) ok; +- (void) also_ok; // expected-warning {{conflicting return type in declaration of 'also_ok': 'unsigned char' vs 'void'}} +- (void) still_ok; +- (void) ban : (int) arg; // expected-warning {{conflicting variadic declaration of method and its implementation}} +@end + +@interface Foo() +- (void) bak; +@end + +@implementation Foo +- (bycopy id)bud { return 0; } +- (void) baz {} +- (void) bar : (unsigned char*)arg {} +- (void) ok {} +- (void) also_ok {} +- (void) still_ok {} +- (void) ban : (int) arg {} +- (void) bak {} // expected-warning {{conflicting return type in declaration of 'bak': 'char' vs 'void'}} +@end diff --git a/clang/test/SemaObjC/class-protocol.m b/clang/test/SemaObjC/class-protocol.m new file mode 100644 index 0000000..91cd138 --- /dev/null +++ b/clang/test/SemaObjC/class-protocol.m @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// pr5552 + +@interface Protocol +@end + diff --git a/clang/test/SemaObjC/class-unavail-warning.m b/clang/test/SemaObjC/class-unavail-warning.m new file mode 100644 index 0000000..b2bd388 --- /dev/null +++ b/clang/test/SemaObjC/class-unavail-warning.m @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://9092208 + +__attribute__((unavailable("not available"))) +@interface MyClass { // expected-note 8 {{declaration has been explicitly marked unavailable here}} +@public + void *_test; + MyClass *ivar; // no error. +} + +- (id)self; +- new; ++ (void)addObject:(id)anObject; +- (MyClass *)meth; // no error. + +@end + +@interface Foo { + MyClass *ivar; // expected-error {{unavailable}} +} +- (MyClass *)meth; // expected-error {{unavailable}} +@end + +@interface MyClass (Cat1) +- (MyClass *)meth; // no error. +@end + +@interface MyClass (Cat2) // no error. +@end + +@implementation MyClass (Cat2) // expected-error {{unavailable}} +@end + +int main() { + [MyClass new]; // expected-error {{'MyClass' is unavailable: not available}} + [MyClass self]; // expected-error {{'MyClass' is unavailable: not available}} + [MyClass addObject:((void *)0)]; // expected-error {{'MyClass' is unavailable: not available}} + + MyClass *foo = [MyClass new]; // expected-error 2 {{'MyClass' is unavailable: not available}} + + return 0; +} diff --git a/clang/test/SemaObjC/cocoa-api-usage.m b/clang/test/SemaObjC/cocoa-api-usage.m new file mode 100644 index 0000000..85e2115 --- /dev/null +++ b/clang/test/SemaObjC/cocoa-api-usage.m @@ -0,0 +1,88 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -fsyntax-only -Wobjc-cocoa-api -verify +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %s -fsyntax-only -Wobjc-cocoa-api -verify +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c %s.fixed -fsyntax-only +// RUN: cp %s %t.m +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %t.m -fixit -Wobjc-cocoa-api +// RUN: diff %s.fixed %t.m +// RUN: cp %s %t.m +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %t.m -fixit -Wobjc-cocoa-api +// RUN: diff %s.fixed %t.m + +typedef signed char BOOL; +#define nil ((void*) 0) + +@interface NSObject ++ (id)alloc; +@end + +@interface NSString : NSObject ++ (id)stringWithString:(NSString *)string; +- (id)initWithString:(NSString *)aString; +@end + +@interface NSArray : NSObject +- (id)objectAtIndex:(unsigned long)index; +- (id)objectAtIndexedSubscript:(int)index; +@end + +@interface NSArray (NSArrayCreation) ++ (id)array; ++ (id)arrayWithObject:(id)anObject; ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; ++ (id)arrayWithObjects:(id)firstObj, ...; ++ (id)arrayWithArray:(NSArray *)array; + +- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; +- (id)initWithObjects:(id)firstObj, ...; +- (id)initWithArray:(NSArray *)array; + +- (id)objectAtIndex:(unsigned long)index; +@end + +@interface NSMutableArray : NSArray +- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; +- (void)setObject:(id)object atIndexedSubscript:(int)index; +@end + +@interface NSDictionary : NSObject +- (id)objectForKeyedSubscript:(id)key; +@end + +@interface NSDictionary (NSDictionaryCreation) ++ (id)dictionary; ++ (id)dictionaryWithObject:(id)object forKey:(id)key; ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; ++ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...; ++ (id)dictionaryWithDictionary:(NSDictionary *)dict; ++ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; + +- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; +- (id)initWithObjectsAndKeys:(id)firstObject, ...; +- (id)initWithDictionary:(NSDictionary *)otherDictionary; +- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; + +- (id)objectForKey:(id)aKey; +@end + +@interface NSMutableDictionary : NSDictionary +- (void)setObject:(id)anObject forKey:(id)aKey; +- (void)setObject:(id)object forKeyedSubscript:(id)key; +@end + +@interface NSNumber : NSObject +@end + +@interface NSNumber (NSNumberCreation) ++ (NSNumber *)numberWithInt:(int)value; +@end + +#define M(x) (x) +#define PAIR(x) @#x, [NSNumber numberWithInt:(x)] +#define TWO(x) ((x), (x)) + +void foo() { + NSString *str = M([NSString stringWithString:@"foo"]); // expected-warning {{redundant}} + str = [[NSString alloc] initWithString:@"foo"]; + NSArray *arr = [NSArray arrayWithArray:@[str]]; // expected-warning {{redundant}} + NSDictionary *dict = [NSDictionary dictionaryWithDictionary:@{str: arr}]; // expected-warning {{redundant}} +} diff --git a/clang/test/SemaObjC/cocoa-api-usage.m.fixed b/clang/test/SemaObjC/cocoa-api-usage.m.fixed new file mode 100644 index 0000000..55e060a --- /dev/null +++ b/clang/test/SemaObjC/cocoa-api-usage.m.fixed @@ -0,0 +1,88 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -fsyntax-only -Wobjc-cocoa-api -verify +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %s -fsyntax-only -Wobjc-cocoa-api -verify +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c %s.fixed -fsyntax-only +// RUN: cp %s %t.m +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %t.m -fixit -Wobjc-cocoa-api +// RUN: diff %s.fixed %t.m +// RUN: cp %s %t.m +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %t.m -fixit -Wobjc-cocoa-api +// RUN: diff %s.fixed %t.m + +typedef signed char BOOL; +#define nil ((void*) 0) + +@interface NSObject ++ (id)alloc; +@end + +@interface NSString : NSObject ++ (id)stringWithString:(NSString *)string; +- (id)initWithString:(NSString *)aString; +@end + +@interface NSArray : NSObject +- (id)objectAtIndex:(unsigned long)index; +- (id)objectAtIndexedSubscript:(int)index; +@end + +@interface NSArray (NSArrayCreation) ++ (id)array; ++ (id)arrayWithObject:(id)anObject; ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; ++ (id)arrayWithObjects:(id)firstObj, ...; ++ (id)arrayWithArray:(NSArray *)array; + +- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; +- (id)initWithObjects:(id)firstObj, ...; +- (id)initWithArray:(NSArray *)array; + +- (id)objectAtIndex:(unsigned long)index; +@end + +@interface NSMutableArray : NSArray +- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; +- (void)setObject:(id)object atIndexedSubscript:(int)index; +@end + +@interface NSDictionary : NSObject +- (id)objectForKeyedSubscript:(id)key; +@end + +@interface NSDictionary (NSDictionaryCreation) ++ (id)dictionary; ++ (id)dictionaryWithObject:(id)object forKey:(id)key; ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; ++ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...; ++ (id)dictionaryWithDictionary:(NSDictionary *)dict; ++ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; + +- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; +- (id)initWithObjectsAndKeys:(id)firstObject, ...; +- (id)initWithDictionary:(NSDictionary *)otherDictionary; +- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; + +- (id)objectForKey:(id)aKey; +@end + +@interface NSMutableDictionary : NSDictionary +- (void)setObject:(id)anObject forKey:(id)aKey; +- (void)setObject:(id)object forKeyedSubscript:(id)key; +@end + +@interface NSNumber : NSObject +@end + +@interface NSNumber (NSNumberCreation) ++ (NSNumber *)numberWithInt:(int)value; +@end + +#define M(x) (x) +#define PAIR(x) @#x, [NSNumber numberWithInt:(x)] +#define TWO(x) ((x), (x)) + +void foo() { + NSString *str = M(@"foo"); // expected-warning {{redundant}} + str = [[NSString alloc] initWithString:@"foo"]; + NSArray *arr = @[str]; // expected-warning {{redundant}} + NSDictionary *dict = @{str: arr}; // expected-warning {{redundant}} +} diff --git a/clang/test/SemaObjC/cocoa.m b/clang/test/SemaObjC/cocoa.m new file mode 100644 index 0000000..a8cfb72 --- /dev/null +++ b/clang/test/SemaObjC/cocoa.m @@ -0,0 +1,5 @@ +// RUN: %clang -arch x86_64 %s -fsyntax-only -Xclang -print-stats +#ifdef __APPLE__ +#include <Cocoa/Cocoa.h> +#endif + diff --git a/clang/test/SemaObjC/compare-qualified-class.m b/clang/test/SemaObjC/compare-qualified-class.m new file mode 100644 index 0000000..0f415b6 --- /dev/null +++ b/clang/test/SemaObjC/compare-qualified-class.m @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://8191774 + +@protocol SomeProtocol +@end + +@protocol SomeProtocol1 +@end + +@interface SomeObject <SomeProtocol> +@end + +int main () { + Class <SomeProtocol> classA; + Class <SomeProtocol> classB; + Class <SomeProtocol, SomeProtocol1> classC; + Class <SomeProtocol1> classD; + void * pv = 0; + Class c = (Class)0;; + if (pv) + return classA == pv; + + if (c) + return classA == c; + + return classA == classB || classA == classC || + classC == classA || + classA == classD; // expected-warning {{comparison of distinct pointer types ('Class<SomeProtocol> *' and 'Class<SomeProtocol1> *')}} +} + diff --git a/clang/test/SemaObjC/compare-qualified-id.m b/clang/test/SemaObjC/compare-qualified-id.m new file mode 100644 index 0000000..d31dfae --- /dev/null +++ b/clang/test/SemaObjC/compare-qualified-id.m @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef signed char BOOL; +typedef unsigned int NSUInteger; +typedef struct _NSZone NSZone; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; +@protocol NSObject - (BOOL)isEqual:(id)object; @end +@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end // expected-note {{method 'copyWithZone:' declared here}} +@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end +@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end +@interface NSObject <NSObject> {} @end +typedef struct {} NSFastEnumerationState; +@protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; @end +@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count; @end +@interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey; @end +extern NSString * const NSTaskDidTerminateNotification; + +@interface XCPropertyExpansionContext : NSObject <NSCopying> { // expected-note {{required for direct or indirect protocol 'NSCopying'}} + NSMutableDictionary * _propNamesToPropValuesCache; +} @end + +@protocol XCPropertyValues <NSObject, NSCopying> +- (NSString *)evaluateAsStringInContext:(XCPropertyExpansionContext *)context withNestingState:(const void *)state; +@end + +@implementation XCPropertyExpansionContext // expected-warning {{incomplete implementation}} \ + // expected-warning {{method 'copyWithZone:' in protocol not implemented}} +- (NSString *)expandedValueForProperty:(NSString *)property { + id <XCPropertyValues> cachedValueNode = [_propNamesToPropValuesCache objectForKey:property]; // expected-warning {{method '-objectForKey:' not found (return type defaults to 'id')}} + if (cachedValueNode == ((void *)0)) { } + NSString * expandedValue = [cachedValueNode evaluateAsStringInContext:self withNestingState:((void *)0)]; + return expandedValue; +} +@end diff --git a/clang/test/SemaObjC/compatible-protocol-qualified-types.m b/clang/test/SemaObjC/compatible-protocol-qualified-types.m new file mode 100644 index 0000000..c0b929d --- /dev/null +++ b/clang/test/SemaObjC/compatible-protocol-qualified-types.m @@ -0,0 +1,76 @@ +// RUN: %clang_cc1 -pedantic -fsyntax-only -verify -Wno-objc-root-class %s +typedef signed char BOOL; + +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; + +@protocol NSObject +- (BOOL)isEqual:(id)object; +@end + +@protocol NSCoding +- (void)encodeWithCoder:(NSCoder *)aCoder; +@end + +@interface NSObject <NSObject> {} +@end + +typedef float CGFloat; + +@interface NSResponder : NSObject <NSCoding> {} +@end + +@protocol XCSelectionSource; + +@interface XCSelection : NSResponder {} +- (NSObject <XCSelectionSource> *) source; +@end + +extern NSString * const XCActiveSelectionLevel; + +@interface XCActionManager : NSResponder {} ++defaultActionManager; +-selectionAtLevel:(NSString *const)s; +@end + +@implementation XDMenuItemsManager // expected-warning {{cannot find interface declaration for 'XDMenuItemsManager'}} ++ (void)initialize { + id<XCSelectionSource, NSObject> source = + [[[XCActionManager defaultActionManager] selectionAtLevel:XCActiveSelectionLevel] source]; +} +@end + +@protocol NSTextStorageDelegate; +@class NSNotification; + +@interface NSTextStorage : NSObject + +- (void)setDelegate:(id <NSTextStorageDelegate>)delegate; // expected-note{{passing argument to parameter 'delegate' here}} +- (id <NSTextStorageDelegate>)delegate; + +@end + +@protocol NSTextStorageDelegate <NSObject> +@optional + +- (void)textStorageWillProcessEditing:(NSNotification *)notification; +- (void)textStorageDidProcessEditing:(NSNotification *)notification; + +@end + +@interface SKTText : NSObject { + @private + + + NSTextStorage *_contents; +} +@end + +@implementation SKTText + + +- (NSTextStorage *)contents { + [_contents setDelegate:self]; // expected-warning {{sending 'SKTText *' to parameter of incompatible type 'id<NSTextStorageDelegate>'}} + return 0; +} + +@end diff --git a/clang/test/SemaObjC/compound-init.m b/clang/test/SemaObjC/compound-init.m new file mode 100644 index 0000000..7b288bb --- /dev/null +++ b/clang/test/SemaObjC/compound-init.m @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +@interface A +@end + +void f() { + (A){ 0 }; // expected-error{{cannot initialize Objective-C class type 'A'}} +} diff --git a/clang/test/SemaObjC/comptypes-1.m b/clang/test/SemaObjC/comptypes-1.m new file mode 100644 index 0000000..997ef19 --- /dev/null +++ b/clang/test/SemaObjC/comptypes-1.m @@ -0,0 +1,89 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s + +#define nil (void *)0; +#define Nil (void *)0; + +extern void foo(); + +@protocol MyProtocol +- (void) foo; +@end + +@interface MyClass +@end + +@interface MyOtherClass <MyProtocol> +- (void) foo; +@end + +int main() +{ + id obj = nil; + id<MyProtocol> obj_p = nil; + MyClass *obj_c = nil; + MyOtherClass *obj_cp = nil; + Class obj_C = Nil; + + /* Assigning to an 'id' variable should never + generate a warning. */ + obj = obj_p; /* Ok */ + obj = obj_c; /* Ok */ + obj = obj_cp; /* Ok */ + obj = obj_C; /* Ok */ + + /* Assigning to a 'MyClass *' variable should always generate a + warning, unless done from an 'id'. */ + obj_c = obj; /* Ok */ + obj_c = obj_cp; // // expected-warning {{incompatible pointer types assigning to 'MyClass *' from 'MyOtherClass *'}} + obj_c = obj_C; // expected-warning {{incompatible pointer types assigning to 'MyClass *' from 'Class'}} + + /* Assigning to an 'id<MyProtocol>' variable should generate a + warning if done from a 'MyClass *' (which doesn't implement + MyProtocol), but not from an 'id' or from a 'MyOtherClass *' + (which implements MyProtocol). */ + obj_p = obj; /* Ok */ + obj_p = obj_c; // expected-warning {{assigning to 'id<MyProtocol>' from incompatible type 'MyClass *'}} + obj_p = obj_cp; /* Ok */ + obj_p = obj_C; // expected-warning {{incompatible pointer types assigning to 'id<MyProtocol>' from 'Class'}} + + /* Assigning to a 'MyOtherClass *' variable should always generate + a warning, unless done from an 'id' or an 'id<MyProtocol>' (since + MyOtherClass implements MyProtocol). */ + obj_cp = obj; /* Ok */ + obj_cp = obj_c; // expected-warning {{incompatible pointer types assigning to 'MyOtherClass *' from 'MyClass *'}} + obj_cp = obj_p; /* Ok */ + obj_cp = obj_C; // expected-warning {{incompatible pointer types assigning to 'MyOtherClass *' from 'Class'}} + + /* Any comparison involving an 'id' must be without warnings. */ + if (obj == obj_p) foo() ; /* Ok */ /*Bogus warning here in 2.95.4*/ + if (obj_p == obj) foo() ; /* Ok */ + if (obj == obj_c) foo() ; /* Ok */ + if (obj_c == obj) foo() ; /* Ok */ + if (obj == obj_cp) foo() ; /* Ok */ + if (obj_cp == obj) foo() ; /* Ok */ + if (obj == obj_C) foo() ; /* Ok */ + if (obj_C == obj) foo() ; /* Ok */ + + /* Any comparison between 'MyClass *' and anything which is not an 'id' + must generate a warning. */ + if (obj_p == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('id<MyProtocol>' and 'MyClass *')}} + + if (obj_c == obj_cp) foo() ; // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'MyOtherClass *')}} + if (obj_cp == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('MyOtherClass *' and 'MyClass *')}} + + if (obj_c == obj_C) foo() ; + if (obj_C == obj_c) foo() ; + + /* Any comparison between 'MyOtherClass *' (which implements + MyProtocol) and an 'id' implementing MyProtocol are Ok. */ + if (obj_cp == obj_p) foo() ; /* Ok */ + if (obj_p == obj_cp) foo() ; /* Ok */ + + + if (obj_p == obj_C) foo() ; + if (obj_C == obj_p) foo() ; + if (obj_cp == obj_C) foo() ; + if (obj_C == obj_cp) foo() ; + + return 0; +} diff --git a/clang/test/SemaObjC/comptypes-10.m b/clang/test/SemaObjC/comptypes-10.m new file mode 100644 index 0000000..5f16a6e --- /dev/null +++ b/clang/test/SemaObjC/comptypes-10.m @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +//rdar: //8591619 +// pr8453 + +@protocol NSCopying @end +@protocol NSPROTO @end +@protocol NSPROTO1 @end +@protocol NSPROTO2 @end + +@interface NSObject <NSCopying, NSPROTO, NSPROTO1> { + Class isa; +} +@end + +void gorf(NSObject <NSCopying> *); // expected-note {{passing argument to parameter here}} + +NSObject <NSCopying> *foo(id <NSCopying> bar, id id_obj) +{ + NSObject <NSCopying> *Init = bar; // expected-warning {{initializing 'NSObject<NSCopying> *' with an expression of incompatible type 'id<NSCopying>'}} + NSObject *Init1 = bar; // expected-warning {{initializing 'NSObject *' with an expression of incompatible type 'id<NSCopying>'}} + + NSObject <NSCopying> *I = id_obj; + NSObject *I1 = id_obj; + gorf(bar); // expected-warning {{passing 'id<NSCopying>' to parameter of incompatible type 'NSObject<NSCopying> *'}} + + gorf(id_obj); + + return bar; // expected-warning {{returning 'id<NSCopying>' from a function with incompatible result type 'NSObject<NSCopying> *'}} +} + +void test(id <NSCopying, NSPROTO, NSPROTO2> bar) +{ + NSObject <NSCopying> *Init = bar; // expected-warning {{initializing 'NSObject<NSCopying> *' with an expression of incompatible type 'id<NSCopying,NSPROTO,NSPROTO2>'}} +} + +// rdar://8843851 +@interface NSObject (CAT) ++ (struct S*)Meth : (struct S*)arg; +@end + +struct S { + char *types; +}; + +@interface I +@end + +@implementation I +- (struct S *)Meth : (struct S*)a { + return [NSObject Meth : a]; +} +@end diff --git a/clang/test/SemaObjC/comptypes-2.m b/clang/test/SemaObjC/comptypes-2.m new file mode 100644 index 0000000..74e42c9 --- /dev/null +++ b/clang/test/SemaObjC/comptypes-2.m @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#define nil (void *)0; +#define Nil (void *)0; + +@protocol MyProtocol +- (void) foo; +@end + +@interface MyClass +@end + +int main() +{ + id obj = nil; + id<MyProtocol> obj_p = nil; + MyClass *obj_c = nil; + Class obj_C = Nil; + + /* All these casts should generate no warnings. */ + + obj = (id)obj_p; + obj = (id)obj_c; + obj = (id)obj_C; + obj_c = (MyClass *)obj; + obj_c = (MyClass *)obj_p; + obj_c = (MyClass *)obj_C; + obj_p = (id<MyProtocol>)obj; + obj_p = (id<MyProtocol>)obj_c; + obj_p = (id<MyProtocol>)obj_C; + obj_C = (Class)obj; + obj_C = (Class)obj_p; + obj_C = (Class)obj_c; + + + return 0; +} diff --git a/clang/test/SemaObjC/comptypes-3.m b/clang/test/SemaObjC/comptypes-3.m new file mode 100644 index 0000000..6c1ce41 --- /dev/null +++ b/clang/test/SemaObjC/comptypes-3.m @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#define nil (void *)0; + +extern void foo(); + +@protocol MyProtocolA +- (void) methodA; +@end + +@protocol MyProtocolB +- (void) methodB; +@end + +@protocol MyProtocolAB <MyProtocolA, MyProtocolB> +@end + +@protocol MyProtocolAC <MyProtocolA> +- (void) methodC; +@end + +int main() +{ + id<MyProtocolA> obj_a = nil; + id<MyProtocolB> obj_b = nil; + id<MyProtocolAB> obj_ab = nil; + id<MyProtocolAC> obj_ac = nil; + + obj_a = obj_b; // expected-warning {{assigning to 'id<MyProtocolA>' from incompatible type 'id<MyProtocolB>'}} + obj_a = obj_ab; /* Ok */ + obj_a = obj_ac; /* Ok */ + + obj_b = obj_a; // expected-warning {{assigning to 'id<MyProtocolB>' from incompatible type 'id<MyProtocolA>'}} + obj_b = obj_ab; /* Ok */ + obj_b = obj_ac; // expected-warning {{assigning to 'id<MyProtocolB>' from incompatible type 'id<MyProtocolAC>'}} + + obj_ab = obj_a; // expected-warning {{assigning to 'id<MyProtocolAB>' from incompatible type 'id<MyProtocolA>'}} + obj_ab = obj_b; // expected-warning {{assigning to 'id<MyProtocolAB>' from incompatible type 'id<MyProtocolB>'}} + obj_ab = obj_ac; // expected-warning {{assigning to 'id<MyProtocolAB>' from incompatible type 'id<MyProtocolAC>'}} + + obj_ac = obj_a; // expected-warning {{assigning to 'id<MyProtocolAC>' from incompatible type 'id<MyProtocolA>'}} + obj_ac = obj_b; // expected-warning {{assigning to 'id<MyProtocolAC>' from incompatible type 'id<MyProtocolB>'}} + obj_ac = obj_ab; // expected-warning {{assigning to 'id<MyProtocolAC>' from incompatible type 'id<MyProtocolAB>'}} + + if (obj_a == obj_b) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolA>' and 'id<MyProtocolB>')}} + if (obj_b == obj_a) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolB>' and 'id<MyProtocolA>')}} + + if (obj_a == obj_ab) foo (); /* Ok */ + if (obj_ab == obj_a) foo (); /* Ok */ + + if (obj_a == obj_ac) foo (); /* Ok */ + if (obj_ac == obj_a) foo (); /* Ok */ + + if (obj_b == obj_ab) foo (); /* Ok */ + if (obj_ab == obj_b) foo (); /* Ok */ + + if (obj_b == obj_ac) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolB>' and 'id<MyProtocolAC>')}} + if (obj_ac == obj_b) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolAC>' and 'id<MyProtocolB>')}} + + if (obj_ab == obj_ac) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolAB>' and 'id<MyProtocolAC>')}} + if (obj_ac == obj_ab) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolAC>' and 'id<MyProtocolAB>')}} + + return 0; +} diff --git a/clang/test/SemaObjC/comptypes-4.m b/clang/test/SemaObjC/comptypes-4.m new file mode 100644 index 0000000..adc324c --- /dev/null +++ b/clang/test/SemaObjC/comptypes-4.m @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +extern void foo(); + +@protocol MyProtocol @end + +@interface MyClass @end + +int main() +{ + MyClass <MyProtocol> *obj_p; + MyClass *obj_cp; + + obj_cp = obj_p; + obj_p = obj_cp; // expected-warning {{incompatible pointer types assigning to 'MyClass<MyProtocol> *' from 'MyClass *'}} + + if (obj_cp == obj_p) + foo(); + + if (obj_p == obj_cp) + foo(); + +} + + diff --git a/clang/test/SemaObjC/comptypes-5.m b/clang/test/SemaObjC/comptypes-5.m new file mode 100644 index 0000000..46300e3 --- /dev/null +++ b/clang/test/SemaObjC/comptypes-5.m @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s + +#define nil (void *)0; + +extern void foo(); + +@protocol MyProtocol +- (void) method; +@end + +@interface MyClass +@end + +@interface MyClass (Addition) <MyProtocol> +- (void) method; +@end + +@interface MyOtherClass : MyClass +@end + +int main() +{ + id <MyProtocol> obj_id_p = nil; + MyClass *obj_c_cat_p = nil; + MyOtherClass *obj_c_super_p = nil; + MyOtherClass<MyProtocol> *obj_c_super_p_q = nil; + MyClass<MyProtocol> *obj_c_cat_p_q = nil; + + obj_c_cat_p = obj_id_p; + obj_c_super_p = obj_id_p; + obj_id_p = obj_c_cat_p; /* Ok */ + obj_id_p = obj_c_super_p; /* Ok */ + + if (obj_c_cat_p == obj_id_p) foo(); /* Ok */ + if (obj_c_super_p == obj_id_p) foo() ; /* Ok */ + if (obj_id_p == obj_c_cat_p) foo(); /* Ok */ + if (obj_id_p == obj_c_super_p) foo(); /* Ok */ + + obj_c_cat_p = obj_c_super_p; // ok. + obj_c_cat_p = obj_c_super_p_q; // ok. + obj_c_super_p = obj_c_cat_p_q; // expected-warning {{incompatible pointer types}} + obj_c_cat_p_q = obj_c_super_p; + return 0; +} diff --git a/clang/test/SemaObjC/comptypes-6.m b/clang/test/SemaObjC/comptypes-6.m new file mode 100644 index 0000000..98cf488 --- /dev/null +++ b/clang/test/SemaObjC/comptypes-6.m @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s + +@interface Derived +@end + +@interface Object @end + +extern Object* foo(void); + +static Derived *test(void) +{ + Derived *m = foo(); // expected-warning {{incompatible pointer types initializing 'Derived *' with an expression of type 'Object *'}} + + return m; +} + diff --git a/clang/test/SemaObjC/comptypes-7.m b/clang/test/SemaObjC/comptypes-7.m new file mode 100644 index 0000000..dde504b --- /dev/null +++ b/clang/test/SemaObjC/comptypes-7.m @@ -0,0 +1,75 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s + +#define nil (void *)0; +#define Nil (void *)0; + +extern void foo(); + +@protocol MyProtocol +- (void) method; +@end + +@interface MyClass +@end + +int main() +{ + id obj = nil; + id <MyProtocol> obj_p = nil; + MyClass *obj_c = nil; + Class obj_C = Nil; + + int i = 0; + int *j = nil; + + /* These should all generate warnings. */ + + obj = i; // expected-warning {{incompatible integer to pointer conversion assigning to 'id' from 'int'}} + obj = j; // expected-warning {{incompatible pointer types assigning to 'id' from 'int *'}} + + obj_p = i; // expected-warning {{incompatible integer to pointer conversion assigning to 'id<MyProtocol>' from 'int'}} + obj_p = j; // expected-warning {{incompatible pointer types assigning to 'id<MyProtocol>' from 'int *'}} + + obj_c = i; // expected-warning {{incompatible integer to pointer conversion assigning to 'MyClass *' from 'int'}} + obj_c = j; // expected-warning {{incompatible pointer types assigning to 'MyClass *' from 'int *'}} + + obj_C = i; // expected-warning {{incompatible integer to pointer conversion assigning to 'Class' from 'int'}} + obj_C = j; // expected-warning {{incompatible pointer types assigning to 'Class' from 'int *'}} + + i = obj; // expected-warning {{incompatible pointer to integer conversion assigning to 'int' from 'id'}} + i = obj_p; // expected-warning {{incompatible pointer to integer conversion assigning to 'int' from 'id<MyProtocol>'}} + i = obj_c; // expected-warning {{incompatible pointer to integer conversion assigning to 'int' from 'MyClass *'}} + i = obj_C; // expected-warning {{incompatible pointer to integer conversion assigning to 'int' from 'Class'}} + + j = obj; // expected-warning {{incompatible pointer types assigning to 'int *' from 'id'}} + j = obj_p; // expected-warning {{incompatible pointer types assigning to 'int *' from 'id<MyProtocol>'}} + j = obj_c; // expected-warning {{incompatible pointer types assigning to 'int *' from 'MyClass *'}} + j = obj_C; // expected-warning {{incompatible pointer types assigning to 'int *' from 'Class'}} + + if (obj == i) foo() ; // expected-warning {{comparison between pointer and integer ('id' and 'int')}} + if (i == obj) foo() ; // expected-warning {{comparison between pointer and integer ('int' and 'id')}} + if (obj == j) foo() ; // expected-warning {{comparison of distinct pointer types ('id' and 'int *')}} + if (j == obj) foo() ; // expected-warning {{comparison of distinct pointer types ('int *' and 'id')}} + + if (obj_c == i) foo() ; // expected-warning {{comparison between pointer and integer ('MyClass *' and 'int')}} + if (i == obj_c) foo() ; // expected-warning {{comparison between pointer and integer ('int' and 'MyClass *')}} + if (obj_c == j) foo() ; // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'int *')}} + if (j == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('int *' and 'MyClass *')}} + + if (obj_p == i) foo() ; // expected-warning {{comparison between pointer and integer ('id<MyProtocol>' and 'int')}} + if (i == obj_p) foo() ; // expected-warning {{comparison between pointer and integer ('int' and 'id<MyProtocol>')}} + if (obj_p == j) foo() ; // expected-warning {{comparison of distinct pointer types ('id<MyProtocol>' and 'int *')}} + if (j == obj_p) foo() ; // expected-warning {{comparison of distinct pointer types ('int *' and 'id<MyProtocol>')}} + + if (obj_C == i) foo() ; // expected-warning {{comparison between pointer and integer ('Class' and 'int')}} + if (i == obj_C) foo() ; // expected-warning {{comparison between pointer and integer ('int' and 'Class')}} + if (obj_C == j) foo() ; // expected-warning {{comparison of distinct pointer types ('Class' and 'int *')}} + if (j == obj_C) foo() ; // expected-warning {{comparison of distinct pointer types ('int *' and 'Class')}} + + Class bar1 = Nil; + Class <MyProtocol> bar = Nil; + bar = bar1; + bar1 = bar; + + return 0; +} diff --git a/clang/test/SemaObjC/comptypes-8.m b/clang/test/SemaObjC/comptypes-8.m new file mode 100644 index 0000000..750b0a6 --- /dev/null +++ b/clang/test/SemaObjC/comptypes-8.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@protocol MyProtocol +@end + +id<MyProtocol> obj_p = 0; + +int main() +{ + obj_p = 0; +} + diff --git a/clang/test/SemaObjC/comptypes-9.m b/clang/test/SemaObjC/comptypes-9.m new file mode 100644 index 0000000..cc6932d --- /dev/null +++ b/clang/test/SemaObjC/comptypes-9.m @@ -0,0 +1,86 @@ +// RUN: %clang_cc1 -fsyntax-only %s +// FIXME: This test case tests the patch applied in: http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20080602/006017.html +// Eventually that logic should be treated as an extension. + +typedef signed char BOOL; +typedef int NSInteger; +typedef unsigned int NSUInteger; +typedef struct _NSZone NSZone; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; + +@protocol NSObject +- (BOOL)isEqual:(id)object; +@end + +@protocol NSCopying +- (id)copyWithZone:(NSZone *)zone; +@end + +@protocol NSMutableCopying +- (id)mutableCopyWithZone:(NSZone *)zone; +@end + +@protocol NSCoding +- (void)encodeWithCoder:(NSCoder *)aCoder; +@end + +@interface NSObject <NSObject> {} +@end + +@class NSArray; + +typedef struct {} NSFastEnumerationState; + +@protocol NSFastEnumeration +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; +@end + +@class NSString; + +@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> +- (NSUInteger)count; +- (id)objectAtIndex:(NSUInteger)index; +@end + +typedef unsigned short unichar; + +@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> +- (NSUInteger)length; +@end + +@interface NSSimpleCString : NSString +{} + +@end + +@interface NSConstantString : NSSimpleCString @end + +extern void *_NSConstantStringClassReference; + +@interface NSResponder : NSObject <NSCoding> {} +@end + +@class NSDate, NSDictionary, NSError, NSException, NSNotification; + +@interface NSWindowController : NSResponder <NSCoding> {} +@end + +@class PBXBuildLog, PBXBuildLogItem, PBXBuildLogContainerItem, XCWorkQueueCommand, XCBuildLogContainerItemMutationState; + +@protocol PBXBuildLogContainerItems <NSObject> +- (PBXBuildLog *)buildLog; +@end + +@interface PBXBuildLogItem : NSObject {} +- (id <PBXBuildLogContainerItems>)superitem; +@end +@interface PBXBuildResultsModule +@end + +@implementation PBXBuildResultsModule +- (void) revealItems +{ + PBXBuildLogItem *objItem; + PBXBuildLogItem *superitem = [objItem superitem]; +} +@end diff --git a/clang/test/SemaObjC/comptypes-a.m b/clang/test/SemaObjC/comptypes-a.m new file mode 100644 index 0000000..18d546b --- /dev/null +++ b/clang/test/SemaObjC/comptypes-a.m @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fsyntax-only -Wmethod-signatures -verify -pedantic -Wno-objc-root-class %s +typedef signed char BOOL; +typedef int NSInteger; + +@class NSString; + +@protocol PBXCompletionItem +- (NSString *) name; +- (NSInteger)priority; +@end + +extern NSInteger codeAssistantCaseCompareItems(id a, id b, void *context); + +NSInteger codeAssistantCaseCompareItems(id<PBXCompletionItem> a, id<PBXCompletionItem> b, void *context) +{ + return 0; +} + +@interface TedWantsToVerifyObjCDoesTheRightThing + +- compareThis:(int)a withThat:(id)b; // expected-note {{previous definition is here}} \ + // expected-note {{previous definition is here}} + +@end + +@implementation TedWantsToVerifyObjCDoesTheRightThing + +- compareThis:(id<PBXCompletionItem>) + a // expected-warning {{conflicting parameter types in implementation of 'compareThis:withThat:': 'int' vs 'id<PBXCompletionItem>'}} + withThat:(id<PBXCompletionItem>)b { // expected-warning {{conflicting parameter types in implementation of 'compareThis:withThat:': 'id' vs 'id<PBXCompletionItem>'}} + return self; +} + +@end diff --git a/clang/test/SemaObjC/comptypes-legal.m b/clang/test/SemaObjC/comptypes-legal.m new file mode 100644 index 0000000..d83d559 --- /dev/null +++ b/clang/test/SemaObjC/comptypes-legal.m @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s + +@protocol NSObject +@end +@interface NSObject <NSObject> { +} +@end +@interface NSString : NSObject +@end +void __setRetained(id *ivar, id value, NSObject **o) { + *ivar = value; +} +static NSString *_logProcessPrefix = 0; +void func() { + __setRetained(&_logProcessPrefix, _logProcessPrefix, &_logProcessPrefix); +} +@implementation NSObject (ScopeAdditions) ++ (void)setObjectLogProcessPrefix:(NSString *)processPrefix { + __setRetained(&_logProcessPrefix, processPrefix, &_logProcessPrefix); +} +@end + +@class Derived; + +NSObject *ExternFunc (NSObject *filePath, NSObject *key); +typedef id FuncSignature (NSObject *arg1, Derived *arg2); + +@interface Derived: NSObject ++ (void)registerFunc:(FuncSignature *)function; // expected-note{{passing argument to parameter 'function' here}} +@end + +void foo(void) +{ + // GCC currently allows this (it has some fiarly new support for covariant return types and contravariant argument types). + // Since registerFunc: expects a Derived object as it's second argument, I don't know why this would be legal. + [Derived registerFunc: ExternFunc]; // expected-warning{{incompatible pointer types sending 'NSObject *(NSObject *, NSObject *)' to parameter of type 'FuncSignature *'}} +} diff --git a/clang/test/SemaObjC/conditional-expr-2.m b/clang/test/SemaObjC/conditional-expr-2.m new file mode 100644 index 0000000..fdf3d13 --- /dev/null +++ b/clang/test/SemaObjC/conditional-expr-2.m @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface A +@end +@interface B +@end + +void f0(int cond, A *a, B *b) { + // Ensure that we can still send a message to result of incompatible + // conditional expression. + [ (cond ? a : b) test ]; // expected-warning{{incompatible operand types ('A *' and 'B *')}} expected-warning {{method '-test' not found}} +} + +@interface NSKey @end +@interface KeySub : NSKey @end + +@interface UpdatesList @end + +void foo (int i, NSKey *NSKeyValueCoding_NullValue, UpdatesList *nukedUpdatesList) +{ + id obj; + NSKey *key; + KeySub *keysub; + + obj = i ? NSKeyValueCoding_NullValue : nukedUpdatesList; // expected-warning{{incompatible operand types ('NSKey *' and 'UpdatesList *')}} + key = i ? NSKeyValueCoding_NullValue : nukedUpdatesList; // expected-warning{{incompatible operand types ('NSKey *' and 'UpdatesList *')}} + key = i ? NSKeyValueCoding_NullValue : keysub; + keysub = i ? NSKeyValueCoding_NullValue : keysub; // expected-warning{{incompatible pointer types assigning to 'KeySub *' from 'NSKey *'}} +} diff --git a/clang/test/SemaObjC/conditional-expr-3.m b/clang/test/SemaObjC/conditional-expr-3.m new file mode 100644 index 0000000..166e02b --- /dev/null +++ b/clang/test/SemaObjC/conditional-expr-3.m @@ -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-warning {{initializing 'id<P0>' with an expression of incompatible type 'id<P1>'}} +} + +void f3(A *a) { + id<P1> l = a; // expected-warning {{initializing 'id<P1>' with an expression of incompatible 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/SemaObjC/conditional-expr-4.m b/clang/test/SemaObjC/conditional-expr-4.m new file mode 100644 index 0000000..56bcfc2 --- /dev/null +++ b/clang/test/SemaObjC/conditional-expr-4.m @@ -0,0 +1,80 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// <rdar://problem/6212771> + +#define nil ((void*) 0) + +@interface A +@property int x; +@end + +@interface B : A +@end + +// Basic checks... +id f0(int cond, id a, void *b) { + return cond ? a : b; +} +A *f0_a(int cond, A *a, void *b) { + return cond ? a : b; +} + +id f1(int cond, id a) { + return cond ? a : nil; +} +A *f1_a(int cond, A *a) { + return cond ? a : nil; +} + +void *f1_const_a(int x, void *p, const A * q) { + void *r = x ? p : q; // expected-warning{{initializing 'void *' with an expression of type 'const void *' discards qualifiers}} + return r; +} + +// Check interaction with qualified id + +@protocol P0 @end + +id f2(int cond, id<P0> a, void *b) { + return cond ? a : b; +} + +id f3(int cond, id<P0> a) { + return cond ? a : nil; +} + +// Check that result actually has correct type. + +// Using properties is one way to find the compiler internal type of a +// conditional expression. Simple assignment doesn't work because if +// the type is id then it can be implicitly promoted. +@protocol P1 +@property int x; +@end + +int f5(int cond, id<P1> a, id<P1> b) { + return (cond ? a : b).x; +} +int f5_a(int cond, A *a, A *b) { + return (cond ? a : b).x; +} +int f5_b(int cond, A *a, B *b) { + return (cond ? a : b).x; +} + +int f6(int cond, id<P1> a, void *b) { + // This should result in something with id type, currently. + return (cond ? a : b).x; // expected-error {{member reference base type 'void *' is not a structure or union}} +} + +int f7(int cond, id<P1> a) { + return (cond ? a : nil).x; +} + +int f8(int cond, id<P1> a, A *b) { + return a == b; // expected-warning {{comparison of distinct pointer types ('id<P1>' and 'A *')}} +} + +int f9(int cond, id<P1> a, A *b) { + return (cond ? a : b).x; // expected-warning {{incompatible operand types ('id<P1>' and 'A *')}} \ + expected-error {{property 'x' not found on object of type 'id'}} +} diff --git a/clang/test/SemaObjC/conditional-expr-5.m b/clang/test/SemaObjC/conditional-expr-5.m new file mode 100644 index 0000000..47aed3e --- /dev/null +++ b/clang/test/SemaObjC/conditional-expr-5.m @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface PBXBuildSettingsDictionary +{ + int i; +} +@end + +@interface XCConditionalBuildSettingsDictionary : PBXBuildSettingsDictionary +{ +} +@end + +@implementation PBXBuildSettingsDictionary + +- (XCConditionalBuildSettingsDictionary *)conditionalDictionaryForConditionSet +{ + return i ? self : (id)0; +} + +- (XCConditionalBuildSettingsDictionary *)conditionalDictionaryForConditionSet2 +{ + return i ? (id)0 : self; +} +@end + + diff --git a/clang/test/SemaObjC/conditional-expr-6.m b/clang/test/SemaObjC/conditional-expr-6.m new file mode 100644 index 0000000..098688a --- /dev/null +++ b/clang/test/SemaObjC/conditional-expr-6.m @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@protocol MyProtocol @end + +@interface NSObject @end + +@interface NSInterm : NSObject <MyProtocol> +@end + +@interface NSArray : NSInterm +@end + +@interface NSSet : NSObject <MyProtocol> +@end + + +@interface N1 : NSObject +@end + +@interface N1() <MyProtocol> +@end + +NSObject* test (int argc) { + NSArray *array = ((void*)0); + NSSet *set = ((void*)0); + return (argc) ? set : array ; +} + + +NSObject* test1 (int argc) { + NSArray *array = ((void*)0); + NSSet *set = ((void*)0); + id <MyProtocol> instance = (argc) ? array : set; + id <MyProtocol> instance1 = (argc) ? set : array; + + N1 *n1 = ((void*)0); + id <MyProtocol> instance2 = (argc) ? set : n1; + id <MyProtocol> instance3 = (argc) ? n1 : array; + + NSArray<MyProtocol> *qual_array = ((void*)0); + id <MyProtocol> instance4 = (argc) ? array : qual_array; + id <MyProtocol> instance5 = (argc) ? qual_array : array; + NSSet<MyProtocol> *qual_set = ((void*)0); + id <MyProtocol> instance6 = (argc) ? qual_set : qual_array; + id <MyProtocol> instance7 = (argc) ? qual_set : array; + id <MyProtocol> instance8 = (argc) ? qual_array : set; + id <MyProtocol> instance9 = (argc) ? qual_array : qual_set; + + + return (argc) ? array : set; +} diff --git a/clang/test/SemaObjC/conditional-expr-7.m b/clang/test/SemaObjC/conditional-expr-7.m new file mode 100644 index 0000000..3ddf3d7 --- /dev/null +++ b/clang/test/SemaObjC/conditional-expr-7.m @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// radar 7682116 + +@interface Super @end + +@interface NSArray : Super @end +@interface NSSet : Super @end + +@protocol MyProtocol +- (void)myMethod; +@end + +@protocol MyProtocol2 <MyProtocol> +- (void)myMethod2; +@end + +@interface NSArray() <MyProtocol2> +@end + +@interface NSSet() <MyProtocol> +@end + +int main (int argc, const char * argv[]) { + NSArray *array = (void*)0; + NSSet *set = (void*)0; + id <MyProtocol> instance = (argc) ? array : set; + instance = (void*)0; + return 0; +} + diff --git a/clang/test/SemaObjC/conditional-expr-8.m b/clang/test/SemaObjC/conditional-expr-8.m new file mode 100644 index 0000000..6799983 --- /dev/null +++ b/clang/test/SemaObjC/conditional-expr-8.m @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://9296866 + +@interface NSResponder +@end + + +@interface NSView : NSResponder +@end + +@interface WebView : NSView +@end + +@protocol WebDocumentView +@end + +@implementation NSView + +- (void) FUNC : (id)s { + WebView *m_webView; + NSView <WebDocumentView> *documentView; + NSView *coordinateView = s ? documentView : m_webView; +} +@end + diff --git a/clang/test/SemaObjC/conditional-expr.m b/clang/test/SemaObjC/conditional-expr.m new file mode 100644 index 0000000..e0a3210 --- /dev/null +++ b/clang/test/SemaObjC/conditional-expr.m @@ -0,0 +1,119 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wno-objc-root-class %s +@protocol NSObject +@end + +@protocol DTOutputStreams <NSObject> +@end + +@interface DTFilterOutputStream <DTOutputStreams> +- nextOutputStream; +@end + +@implementation DTFilterOutputStream +- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream { + id <DTOutputStreams> nextOutputStream = [self nextOutputStream]; + self = nextOutputStream; + return nextOutputStream ? nextOutputStream : self; +} +- nextOutputStream { + return self; +} +@end + +@interface DTFilterOutputStream2 +- nextOutputStream; // expected-note {{method definition for 'nextOutputStream' not found}} +@end + +@implementation DTFilterOutputStream2 // expected-warning {{incomplete implementation}} +- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream { + id <DTOutputStreams> nextOutputStream = [self nextOutputStream]; + self = nextOutputStream; // expected-warning {{assigning to 'DTFilterOutputStream2 *' from incompatible type 'id<DTOutputStreams>'}} + return nextOutputStream ? nextOutputStream : self; // expected-warning {{incompatible operand types ('id<DTOutputStreams>' and 'DTFilterOutputStream2 *')}} +} +@end + +// No @interface declaration for DTFilterOutputStream3 +@implementation DTFilterOutputStream3 // expected-warning {{cannot find interface declaration for 'DTFilterOutputStream3'}} +- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream { + id <DTOutputStreams> nextOutputStream = [self nextOutputStream]; // expected-warning {{method '-nextOutputStream' not found (return type defaults to 'id')}} + self = nextOutputStream; // expected-warning {{assigning to 'DTFilterOutputStream3 *' from incompatible type 'id<DTOutputStreams>'}} + return nextOutputStream ? nextOutputStream : self; // expected-warning {{incompatible operand types ('id<DTOutputStreams>' and 'DTFilterOutputStream3 *')}} +} +@end + +// + +@protocol P0 +@property int intProp; +@end +@protocol P1 +@end +@protocol P2 +@end + +@interface A <P0> +@end + +@interface B : A +@end + +@interface C +@end + +@interface D +@end + +void f0(id<P0> x) { + x.intProp = 1; +} + +void f1(int cond, id<P0> x, id<P0> y) { + (cond ? x : y).intProp = 1; +} + +void f2(int cond, id<P0> x, A *y) { + (cond ? x : y).intProp = 1; +} + +void f3(int cond, id<P0> x, B *y) { + (cond ? x : y).intProp = 1; +} + +void f4(int cond, id x, B *y) { + (cond ? x : y).intProp = 1; // expected-error {{property 'intProp' not found on object of type 'id'}} +} + +void f5(int cond, id<P0> x, C *y) { + (cond ? x : y).intProp = 1; // expected-warning {{incompatible operand types ('id<P0>' and 'C *')}} expected-error {{property 'intProp' not found on object of type 'id'}} +} + +void f6(int cond, C *x, D *y) { + (cond ? x : y).intProp = 1; // expected-warning {{incompatible operand types}}, expected-error {{property 'intProp' not found on object of type 'id'}} +} + +id f7(int a, id<P0> x, A* p) { + return a ? x : p; +} + +void f8(int a, A<P0> *x, A *y) { + [ (a ? x : y ) intProp ]; +} + +void f9(int a, A<P0> *x, A<P1> *y) { + id l0 = (a ? x : y ); // expected-warning {{incompatible operand types ('A<P0> *' and 'A<P1> *')}} + A<P0> *l1 = (a ? x : y ); // expected-warning {{incompatible operand types ('A<P0> *' and 'A<P1> *')}} + A<P1> *l2 = (a ? x : y ); // expected-warning {{incompatible operand types ('A<P0> *' and 'A<P1> *')}} + [ (a ? x : y ) intProp ]; // expected-warning {{incompatible operand types ('A<P0> *' and 'A<P1> *')}} +} + +void f10(int a, id<P0> x, id y) { + [ (a ? x : y ) intProp ]; +} + +void f11(int a, id<P0> x, id<P1> y) { + [ (a ? x : y ) intProp ]; // expected-warning {{incompatible operand types ('id<P0>' and 'id<P1>')}} +} + +void f12(int a, A<P0> *x, A<P1> *y) { + A<P1>* l0 = (a ? x : y ); // expected-warning {{incompatible operand types ('A<P0> *' and 'A<P1> *')}} +} diff --git a/clang/test/SemaObjC/conflict-atomic-property.m b/clang/test/SemaObjC/conflict-atomic-property.m new file mode 100644 index 0000000..033980c --- /dev/null +++ b/clang/test/SemaObjC/conflict-atomic-property.m @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://10260017 + +@interface Foo +@property (nonatomic, assign, atomic) float dummy; // expected-error {{property attributes 'atomic' and 'nonatomic' are mutually exclusive}} +@property (nonatomic, assign) float d1; +@property (atomic, assign) float d2; +@property (assign) float d3; +@property (atomic, nonatomic, assign) float d4; // expected-error {{property attributes 'atomic' and 'nonatomic' are mutually exclusive}} +@end diff --git a/clang/test/SemaObjC/conflict-nonfragile-abi2.m b/clang/test/SemaObjC/conflict-nonfragile-abi2.m new file mode 100644 index 0000000..8197327 --- /dev/null +++ b/clang/test/SemaObjC/conflict-nonfragile-abi2.m @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -Wno-objc-root-class %s +// rdar://8225011 + +int glob; + +@interface I +@property int glob; +@property int p; +@property int le; +@property int l; +@property int ls; +@property int r; +@end + +// rdar://9027673 +// Warning on future name lookup rule is removed. +@implementation I +- (int) Meth { return glob; } // no warning +@synthesize glob; +// rdar://8248681 +- (int) Meth1: (int) p { + extern int le; + int l = 1; + static int ls; + register int r; + p = le + ls + r; + return l; +} +@dynamic p; +@dynamic le; +@dynamic l; +@dynamic ls; +@dynamic r; +@end + + diff --git a/clang/test/SemaObjC/conflicting-ivar-test-1.m b/clang/test/SemaObjC/conflicting-ivar-test-1.m new file mode 100644 index 0000000..a7c1d35 --- /dev/null +++ b/clang/test/SemaObjC/conflicting-ivar-test-1.m @@ -0,0 +1,86 @@ +// RUN: %clang_cc1 -fobjc-fragile-abi -fsyntax-only -verify -Wno-objc-root-class %s + +@interface INTF +{ +@public + int IVAR; // expected-note {{previous definition is here}} +} +@end + +@implementation INTF +{ +@private + + int XIVAR; // expected-error {{conflicting instance variable names: 'XIVAR' vs 'IVAR'}} +} +@end + + + +@interface INTF1 +{ +@public + int IVAR; + int IVAR1; // expected-error {{inconsistent number of instance variables specified}} +} +@end + +@implementation INTF1 +{ +@private + + int IVAR; +} +@end + + +@interface INTF2 +{ +@public + int IVAR; +} +@end + +@implementation INTF2 +{ +@private + + int IVAR; + int IVAR1; // expected-error {{inconsistent number of instance variables specified}} +} +@end + + +@interface INTF3 +{ +@public + int IVAR; // expected-note {{previous definition is here}} +} +@end + +@implementation INTF3 +{ +@private + + short IVAR; // expected-error {{instance variable 'IVAR' has conflicting type: 'short' vs 'int'}} +} +@end + +@implementation INTF4 // expected-warning {{cannot find interface declaration for 'INTF4'}} +{ +@private + + short IVAR; +} +@end + +@interface INTF5 +{ + char * ch; +} +@end + +@implementation INTF5 +{ +} +@end diff --git a/clang/test/SemaObjC/continuation-class-err.m b/clang/test/SemaObjC/continuation-class-err.m new file mode 100644 index 0000000..d691f12 --- /dev/null +++ b/clang/test/SemaObjC/continuation-class-err.m @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface ReadOnly +{ + id _object; + id _object1; +} +@property(readonly) id object; // expected-note {{property declared here}} +@property(readwrite, assign) id object1; // expected-note {{property declared here}} +@property (readonly) int indentLevel; +@end + +@interface ReadOnly () +@property(readwrite, copy) id object; // expected-warning {{property attribute in continuation class does not match the primary class}} +@property(readonly) id object1; // expected-error {{illegal redeclaration of property in continuation class 'ReadOnly' (attribute must be 'readwrite', while its primary must be 'readonly')}} +@property (readwrite, assign) int indentLevel; // OK. assign the the default in any case. +@end + +@protocol Proto + @property (copy) id fee; // expected-note {{property declared here}} +@end + +@protocol Foo<Proto> + @property (copy) id foo; // expected-note {{property declared here}} +@end + +@interface Bar <Foo> { + id _foo; + id _fee; +} +@end + +@interface Bar () +@property (copy) id foo; // expected-error {{illegal redeclaration of property in continuation class 'Bar' (attribute must be 'readwrite', while its primary must be 'readonly')}} +@property (copy) id fee; // expected-error {{illegal redeclaration of property in continuation class 'Bar' (attribute must be 'readwrite', while its primary must be 'readonly')}} +@end + +@implementation Bar +@synthesize foo = _foo; +@synthesize fee = _fee; +@end + +// rdar://10752081 +@interface MyOtherClass() // expected-error {{cannot find interface declaration for 'MyOtherClass'}} +{ + id array; +} +@end + +@implementation MyOtherClass // expected-warning {{cannot find interface declaration for 'MyOtherClass'}} +@end diff --git a/clang/test/SemaObjC/continuation-class-property.m b/clang/test/SemaObjC/continuation-class-property.m new file mode 100644 index 0000000..7d95424 --- /dev/null +++ b/clang/test/SemaObjC/continuation-class-property.m @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// radar 7509234 + +@protocol Foo +@property (readonly, copy) id foos; +@end + +@interface Bar <Foo> { +} + +@end + +@interface Baz <Foo> { +} +@end + +@interface Bar () +@property (readwrite, copy) id foos; +@end + +@interface Baz () +@property (readwrite, copy) id foos; +@end + + +// rdar://10142679 +@class NSString; + +typedef struct { + float width; + float length; +} NSRect; + +@interface MyClass { +} +@property (readonly) NSRect foo; // expected-note {{property declared here}} +@property (readonly, strong) NSString *bar; // expected-note {{property declared here}} +@end + +@interface MyClass () +@property (readwrite) NSString *foo; // expected-error {{type of property 'NSString *' in continuation class does not match property type in primary class}} +@property (readwrite, strong) NSRect bar; // expected-error {{type of property 'NSRect' in continuation class does not match property type in primary class}} +@end + +// rdar://10655530 +struct S; +struct S1; +@interface STAdKitContext +@property (nonatomic, readonly, assign) struct evhttp_request *httpRequest; +@property (nonatomic, readonly, assign) struct S *httpRequest2; +@property (nonatomic, readonly, assign) struct S1 *httpRequest3; +@property (nonatomic, readonly, assign) struct S2 *httpRequest4; +@end + +struct evhttp_request; +struct S1; + +@interface STAdKitContext() +@property (nonatomic, readwrite, assign) struct evhttp_request *httpRequest; +@property (nonatomic, readwrite, assign) struct S *httpRequest2; +@property (nonatomic, readwrite, assign) struct S1 *httpRequest3; +@property (nonatomic, readwrite, assign) struct S2 *httpRequest4; +@end diff --git a/clang/test/SemaObjC/crash-label.m b/clang/test/SemaObjC/crash-label.m new file mode 100644 index 0000000..b0ca5b5 --- /dev/null +++ b/clang/test/SemaObjC/crash-label.m @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + + - (NSDictionary*) _executeScript:(NSString *)source { // expected-error 2 {{expected a type}} \ + // expected-error {{missing context for method declaration}} +Exit: [nilArgs release]; +} +- (NSDictionary *) _setupKernelStandardMode:(NSString *)source { // expected-error 2 {{expected a type}} \ + // expected-error {{missing context for method declaration}} + Exit: if(_ciKernel && !success ) { diff --git a/clang/test/SemaObjC/custom-atomic-property.m b/clang/test/SemaObjC/custom-atomic-property.m new file mode 100644 index 0000000..53eaeb0 --- /dev/null +++ b/clang/test/SemaObjC/custom-atomic-property.m @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -Wcustom-atomic-properties -verify -Wno-objc-root-class %s + +@interface Foo +@property (assign) Foo *myProp; // expected-note {{property declared here}} expected-note {{property declared here}} +@end + +@implementation Foo + -(Foo*)myProp {return 0;} // expected-warning {{atomic by default property 'myProp' has a user defined getter (property should be marked 'atomic' if this is intended)}} + -(void)setMyProp:(Foo*)e {} // expected-warning {{atomic by default property 'myProp' has a user defined setter (property should be marked 'atomic' if this is intended)}} +@end + +@interface Foo2 { + Foo *myProp; +} +@property (assign) Foo *myProp; +@end + +@implementation Foo2 +@synthesize myProp; // no warnings. +@end diff --git a/clang/test/SemaObjC/debugger-cast-result-to-id.m b/clang/test/SemaObjC/debugger-cast-result-to-id.m new file mode 100644 index 0000000..00a02be --- /dev/null +++ b/clang/test/SemaObjC/debugger-cast-result-to-id.m @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -funknown-anytype -fsyntax-only -fdebugger-support -fdebugger-cast-result-to-id -verify %s + +extern __unknown_anytype test0; +extern __unknown_anytype test1(); + +void test_unknown_anytype_receiver() { + (void)(int)[[test0 unknownMethod] otherUnknownMethod];; + (void)(id)[[test1() unknownMethod] otherUnknownMethod]; +} + +// rdar://10988847 +@class NSString; // expected-note {{forward declaration of class here}} + +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/SemaObjC/debugger-support.m b/clang/test/SemaObjC/debugger-support.m new file mode 100644 index 0000000..21c096e --- /dev/null +++ b/clang/test/SemaObjC/debugger-support.m @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fdebugger-support %s -emit-llvm -o - | FileCheck %s + +// rdar://problem/9416370 +void test0(id x) { + struct A { int w, x, y, z; }; + struct A result = (struct A) [x makeStruct]; + // CHECK: define void @test0( + // CHECK: [[X:%.*]] = alloca i8*, align 8 + // CHECK-NEXT: [[RESULT:%.*]] = alloca [[A:%.*]], align 4 + // CHECK-NEXT: store i8* {{%.*}}, i8** [[X]], + // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]], + // CHECK-NEXT: [[T1:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_" + // CHECK-NEXT: [[T2:%.*]] = call { i64, i64 } bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to { i64, i64 } (i8*, i8*)*)(i8* [[T0]], i8* [[T1]]) +} diff --git a/clang/test/SemaObjC/default-synthesize-1.m b/clang/test/SemaObjC/default-synthesize-1.m new file mode 100644 index 0000000..c201e74 --- /dev/null +++ b/clang/test/SemaObjC/default-synthesize-1.m @@ -0,0 +1,116 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-default-synthesize-properties -verify -Wno-objc-root-class %s + +@interface NSObject +- (void) release; +- (id) retain; +@end +@class NSString; + +@interface SynthItAll : NSObject +@property int howMany; +@property (retain) NSString* what; +@end + +@implementation SynthItAll +//@synthesize howMany, what; +@end + + +@interface SynthSetter : NSObject +@property (nonatomic) int howMany; // REM: nonatomic to avoid warnings about only implementing one of the pair +@property (nonatomic, retain) NSString* what; +@end + +@implementation SynthSetter +//@synthesize howMany, what; + +- (int) howMany { + return _howMany; +} +// - (void) setHowMany: (int) value + +- (NSString*) what { + return _what; +} +// - (void) setWhat: (NSString*) value +@end + + +@interface SynthGetter : NSObject +@property (nonatomic) int howMany; // REM: nonatomic to avoid warnings about only implementing one of the pair +@property (nonatomic, retain) NSString* what; +@end + +@implementation SynthGetter +//@synthesize howMany, what; + +// - (int) howMany +- (void) setHowMany: (int) value { + _howMany = value; +} + +// - (NSString*) what +- (void) setWhat: (NSString*) value { + if (_what != value) { + [_what release]; + _what = [value retain]; + } +} +@end + + +@interface SynthNone : NSObject +@property int howMany; +@property (retain) NSString* what; +@end + +@implementation SynthNone +//@synthesize howMany, what; // REM: Redundant anyway + +- (int) howMany { + return howMany; // expected-error {{use of undeclared identifier 'howMany'}} +} +- (void) setHowMany: (int) value { + howMany = value; // expected-error {{use of undeclared identifier 'howMany'}} +} + +- (NSString*) what { + return what; // expected-error {{use of undeclared identifier 'what'}} +} +- (void) setWhat: (NSString*) value { + if (what != value) { // expected-error {{use of undeclared identifier 'what'}} + [what release]; // expected-error {{use of undeclared identifier 'what'}} + what = [value retain]; // expected-error {{use of undeclared identifier 'what'}} + } +} +@end + +// rdar://8349319 +// No default synthesis if implementation has getter (readonly) and setter(readwrite) methods. +@interface DSATextSearchResult +@property(assign,readonly) float relevance; +@property(assign,readonly) char isTitleMatch; +@end + +@interface DSANodeSearchResult : DSATextSearchResult {} +@end + + +@implementation DSATextSearchResult +-(char)isTitleMatch { + return (char)0; +} + +-(float)relevance { + return 0.0; +} +@end + +@implementation DSANodeSearchResult +-(id)initWithNode:(id )node relevance:(float)relevance isTitleMatch:(char)isTitleMatch { + relevance = 0.0; + isTitleMatch = 'a'; + return self; +} +@end + diff --git a/clang/test/SemaObjC/default-synthesize-2.m b/clang/test/SemaObjC/default-synthesize-2.m new file mode 100644 index 0000000..b95f263 --- /dev/null +++ b/clang/test/SemaObjC/default-synthesize-2.m @@ -0,0 +1,116 @@ +// RUN: %clang_cc1 -x objective-c -fsyntax-only -fobjc-default-synthesize-properties -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -fobjc-default-synthesize-properties -verify -Wno-objc-root-class %s +// rdar://8843851 + +@interface StopAccessingIvarsDirectlyExample +@property(strong) id name, rank, serialNumber; +@end + +@implementation StopAccessingIvarsDirectlyExample + +- (void)identifyYourSelf { + if (self.name && self.rank && self.serialNumber) + self.name = 0; +} + +// @synthesize name, rank, serialNumber; +// default synthesis allows direct access to property ivars. +- (id)init { + _name = _rank = _serialNumber = 0; + return self; +} + +- (void)dealloc { +} +@end + + +// Test2 +@interface Test2 +@property(strong, nonatomic) id object; +@end + +// object has user declared setter/getter so it won't be +// default synthesized; thus causing user error. +@implementation Test2 +- (id) bar { return object; } // expected-error {{use of undeclared identifier 'object'}} +- (void)setObject:(id)newObject {} +- (id)object { return 0; } +@end + +// Test3 +@interface Test3 +{ + id uid; +} +@property (readwrite, assign) id uid; +@end + +@implementation Test3 +// Oops, forgot to write @synthesize! will be default synthesized +- (void) myMethod { + self.uid = 0; // Use of the “setter” + uid = 0; // Use of the wrong instance variable + _uid = 0; // Use of the property instance variable +} +@end + +@interface Test4 { + id _var; +} +@property (readwrite, assign) id var; +@end + + +// default synthesize property named 'var' +@implementation Test4 +- (id) myMethod { + return self->_var; // compiles because 'var' is synthesized by default +} +@end + +@interface Test5 +{ + id _var; +} +@property (readwrite, assign) id var; +@end + +// default synthesis of property 'var' +@implementation Test5 +- (id) myMethod { + Test5 *foo = 0; + return foo->_var; // OK +} +@end + +@interface Test6 +{ + id _var; // expected-note {{'_var' declared here}} +} +@property (readwrite, assign) id var; +@end + +// no default synthesis. So error is expected. +@implementation Test6 +- (id) myMethod +{ + return var; // expected-error {{use of undeclared identifier 'var'}} +} +@synthesize var = _var; +@end + +int* _object; + +@interface Test7 +@property (readwrite, assign) id object; +@end + +// With default synthesis, '_object' is be the synthesized ivar not the global +// 'int*' object. So no error. +@implementation Test7 +- (id) myMethod { + return _object; +} +@end + diff --git a/clang/test/SemaObjC/default-synthesize-3.m b/clang/test/SemaObjC/default-synthesize-3.m new file mode 100644 index 0000000..606ece3 --- /dev/null +++ b/clang/test/SemaObjC/default-synthesize-3.m @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -x objective-c -fsyntax-only -fobjc-default-synthesize-properties -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -fobjc-default-synthesize-properties -verify -Wno-objc-root-class %s + +#if __has_attribute(objc_requires_property_definitions) +__attribute ((objc_requires_property_definitions)) +#endif +@interface NoAuto // expected-note 2 {{class with specified objc_requires_property_definitions attribute is declared here}} +@property int NoAutoProp; // expected-note 2 {{property declared here}} +@end + +@implementation NoAuto // expected-warning {{property 'NoAutoProp' requires method 'NoAutoProp' to be defined}} \ + // expected-warning {{property 'NoAutoProp' requires method 'setNoAutoProp:'}} +@end + +__attribute ((objc_requires_property_definitions)) // redundant, just for testing +@interface Sub : NoAuto // expected-note 3 {{class with specified objc_requires_property_definitions attribute is declared here}} +@property (copy) id SubProperty; // expected-note 2 {{property declared here}} +@end + +@implementation Sub // expected-warning {{property 'SubProperty' requires method 'SubProperty' to be defined}} \ + // expected-warning {{property 'SubProperty' requires method 'setSubProperty:' to be defined}} +@end + +@interface Deep : Sub +@property (copy) id DeepProperty; +@property (copy) id DeepSynthProperty; +@property (copy) id DeepMustSynthProperty; // expected-note {{property declared here}} +@end + +@implementation Deep // expected-warning {{property 'DeepMustSynthProperty' requires method 'setDeepMustSynthProperty:' to be defined}} +@dynamic DeepProperty; +@synthesize DeepSynthProperty; +- (id) DeepMustSynthProperty { return 0; } +@end + +__attribute ((objc_requires_property_definitions)) +@interface Deep(CAT) // expected-error {{attributes may not be specified on a category}} +@end + +__attribute ((objc_requires_property_definitions)) // expected-error {{objc_requires_property_definitions attribute may only be specified on a class}} +@protocol P @end diff --git a/clang/test/SemaObjC/default-synthesize.m b/clang/test/SemaObjC/default-synthesize.m new file mode 100644 index 0000000..e6ea0a5 --- /dev/null +++ b/clang/test/SemaObjC/default-synthesize.m @@ -0,0 +1,140 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-default-synthesize-properties -verify -Wno-objc-root-class %s + +@interface NSString @end + +@interface NSObject @end + +@interface SynthItAll +@property int howMany; +@property (retain) NSString* what; +@end + +@implementation SynthItAll +#if !__has_feature(objc_default_synthesize_properties) +@synthesize howMany, what; +#endif +@end + + +@interface SynthSetter : NSObject +@property (nonatomic) int howMany; // REM: nonatomic to avoid warnings about only implementing one of the pair +@property (nonatomic, retain) NSString* what; +@end + +@implementation SynthSetter +#if !__has_feature(objc_default_synthesize_properties) +@synthesize howMany, what; +#endif + +- (int) howMany { + return self.howMany; +} +// - (void) setHowMany: (int) value + +- (NSString*) what { + return self.what; +} +// - (void) setWhat: (NSString*) value +@end + + +@interface SynthGetter : NSObject +@property (nonatomic) int howMany; // REM: nonatomic to avoid warnings about only implementing one of the pair +@property (nonatomic, retain) NSString* what; +@end + +@implementation SynthGetter +#if !__has_feature(objc_default_synthesize_properties) +@synthesize howMany, what; +#endif + +// - (int) howMany +- (void) setHowMany: (int) value { + self.howMany = value; +} + +// - (NSString*) what +- (void) setWhat: (NSString*) value { + if (self.what != value) { + } +} +@end + + +@interface SynthNone : NSObject +@property int howMany; +@property (retain) NSString* what; +@end + +@implementation SynthNone +#if !__has_feature(objc_default_synthesize_properties) +@synthesize howMany, what; // REM: Redundant anyway +#endif + +- (int) howMany { + return self.howMany; +} +- (void) setHowMany: (int) value { + self.howMany = value; +} + +- (NSString*) what { + return self.what; +} +- (void) setWhat: (NSString*) value { + if (self.what != value) { + } +} +@end + +@protocol TopProtocol + @property (readonly) id myString; +@end + +@interface TopClass <TopProtocol> +{ + id myString; +} +@end + +@interface SubClass : TopClass <TopProtocol> +@end + +@implementation SubClass @end + +// rdar://7920807 +@interface C @end +@interface C (Category) +@property int p; // expected-note 2 {{property declared here}} +@end +@implementation C (Category) // expected-warning {{property 'p' requires method 'p' to be defined}} \ + // expected-warning {{property 'p' requires method 'setP:' to be defined}} +@end + +// Don't complain if a property is already @synthesized by usr. +@interface D +{ +} +@property int PROP; +@end + +@implementation D +- (int) Meth { return self.PROP; } +#if __has_feature(objc_default_synthesize_properties) +@synthesize PROP=IVAR; +#endif +@end + +// rdar://10567333 +@protocol MyProtocol +@property (nonatomic, strong) NSString *requiredString; // expected-note {{property declared here}} + +@optional +@property (nonatomic, strong) NSString *optionalString; +@end + +@interface MyClass <MyProtocol> +@end + +@implementation MyClass // expected-warning {{auto property synthesis will not synthesize property declared in a protocol}} +@end diff --git a/clang/test/SemaObjC/deref-interface.m b/clang/test/SemaObjC/deref-interface.m new file mode 100644 index 0000000..3201412 --- /dev/null +++ b/clang/test/SemaObjC/deref-interface.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -Wno-objc-root-class %s + +@interface NSView + - (id)initWithView:(id)realView; +@end + +@implementation NSView + - (id)initWithView:(id)realView { + *(NSView *)self = *(NSView *)realView; // expected-error {{cannot assign to class object}} + } +@end + diff --git a/clang/test/SemaObjC/direct-synthesized-ivar-access.m b/clang/test/SemaObjC/direct-synthesized-ivar-access.m new file mode 100644 index 0000000..54b7110 --- /dev/null +++ b/clang/test/SemaObjC/direct-synthesized-ivar-access.m @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -Wnonfragile-abi2 -fsyntax-only -fobjc-default-synthesize-properties -verify -Wno-objc-root-class %s +// rdar://8673791 +// rdar://9943851 + +@interface I { +} + +@property int IVAR; +- (int) OK; +@end + +@implementation I +- (int) Meth { return _IVAR; } +- (int) OK { return self.IVAR; } +@end diff --git a/clang/test/SemaObjC/dist-object-modifiers.m b/clang/test/SemaObjC/dist-object-modifiers.m new file mode 100644 index 0000000..aa7e340 --- /dev/null +++ b/clang/test/SemaObjC/dist-object-modifiers.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://7076235 + +@protocol P +- (bycopy id)serverPID; // expected-note {{previous declaration is here}} +- (void)doStuff:(bycopy id)clientId; // expected-note {{previous declaration is here}} +- (bycopy id)Ok; ++ (oneway id) stillMore : (byref id)Arg : (bycopy oneway id)Arg1; // expected-note 3 {{previous declaration is here}} +@end + +@interface I <P> +- (id)Ok; +@end + +@implementation I +- (id)serverPID { return 0; } // expected-warning {{conflicting distributed object modifiers on return type in implementation of 'serverPID'}} +- (void)doStuff:(id)clientId { } // expected-warning {{conflicting distributed object modifiers on parameter type in implementation of 'doStuff:'}} +- (bycopy id)Ok { return 0; } ++ (id) stillMore : (id)Arg : (bycopy id)Arg1 { return Arg; } // expected-warning {{conflicting distributed object modifiers on return type in implementation of 'stillMore::'}} \ + // expected-warning 2{{conflicting distributed object modifiers on parameter type in implementation of 'stillMore::'}} +@end diff --git a/clang/test/SemaObjC/duplicate-ivar-check.m b/clang/test/SemaObjC/duplicate-ivar-check.m new file mode 100644 index 0000000..260c215 --- /dev/null +++ b/clang/test/SemaObjC/duplicate-ivar-check.m @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface B1 { +@public + double fill_B; // expected-note {{previous declaration is here}} + unsigned : 0; +} +@end + +@interface B : B1 { +@public + int one; // expected-note {{previous declaration is here}} + int one; // expected-error {{duplicate member 'one'}} + unsigned : 0; +} +@end + +@interface A : B { +@public + int fill_B; // expected-error {{duplicate member 'fill_B'}} +} +@end diff --git a/clang/test/SemaObjC/duplicate-ivar-in-class-extension.m b/clang/test/SemaObjC/duplicate-ivar-in-class-extension.m new file mode 100644 index 0000000..9b9d58c --- /dev/null +++ b/clang/test/SemaObjC/duplicate-ivar-in-class-extension.m @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface Root @end + +@interface SuperClass : Root +{ + int iSuper; // expected-note {{previous declaration is here}} +} +@end + +@interface SubClass : SuperClass { + int ivar; // expected-error {{duplicate member 'ivar'}} + int another_ivar; // expected-error {{duplicate member 'another_ivar'}} + int iSuper; // expected-error {{duplicate member 'iSuper'}} +} +@end + +@interface SuperClass () { + int ivar; // expected-note {{previous declaration is here}} +} +@end + +@interface Root () { + int another_ivar; // expected-note {{previous declaration is here}} +} +@end + +@implementation SubClass +-(int) method { + return self->ivar; // would be ambiguous if the duplicate ivar were allowed +} +@end diff --git a/clang/test/SemaObjC/duplicate-property-class-extension.m b/clang/test/SemaObjC/duplicate-property-class-extension.m new file mode 100644 index 0000000..bf48ed6 --- /dev/null +++ b/clang/test/SemaObjC/duplicate-property-class-extension.m @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://7629420 + +@interface Foo +@property (readonly) char foo; +@property (readwrite) char bar; // expected-note {{property declared here}} +@end + +@interface Foo () +@property (readwrite) char foo; // expected-note 2 {{property declared here}} +@property (readwrite) char NewProperty; // expected-note 2 {{property declared here}} +@property (readwrite) char bar; // expected-error{{illegal redeclaration of 'readwrite' property in continuation class 'Foo' (perhaps you intended this to be a 'readwrite' redeclaration of a 'readonly' public property?)}} +@end + +@interface Foo () +@property (readwrite) char foo; // expected-error {{property has a previous declaration}} +@property (readwrite) char NewProperty; // expected-error {{property has a previous declaration}} +@end + +@interface Foo () +@property (readonly) char foo; // expected-error {{property has a previous declaration}} +@property (readwrite) char NewProperty; // expected-error {{property has a previous declaration}} +@end + diff --git a/clang/test/SemaObjC/duplicate-property.m b/clang/test/SemaObjC/duplicate-property.m new file mode 100644 index 0000000..bc1fe71 --- /dev/null +++ b/clang/test/SemaObjC/duplicate-property.m @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface Foo { + id x; +} +@property (nonatomic, retain) id x; // expected-note{{property declared here}} +@property (nonatomic, retain) id x; // expected-error{{property has a previous declaration}} +@end diff --git a/clang/test/SemaObjC/enhanced-proto-2.m b/clang/test/SemaObjC/enhanced-proto-2.m new file mode 100644 index 0000000..28b03d9 --- /dev/null +++ b/clang/test/SemaObjC/enhanced-proto-2.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -verify -Wno-objc-root-class %s + +@protocol MyProto1 +@optional +- (void) FOO; +@optional +- (void) FOO1; +@optional +- (void) REQ; +@optional +@end + +@interface MyProto2 <MyProto1> +- (void) FOO2; +- (void) FOO3; +@end + +@implementation MyProto2 +- (void) FOO2{} +- (void) FOO3{} +@end diff --git a/clang/test/SemaObjC/enum-fixed-type.m b/clang/test/SemaObjC/enum-fixed-type.m new file mode 100644 index 0000000..95153be --- /dev/null +++ b/clang/test/SemaObjC/enum-fixed-type.m @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#if !__has_feature(objc_fixed_enum) +# error Enumerations with a fixed underlying type are not supported +#endif + +typedef long Integer; + +typedef enum : Integer { Enumerator1, Enumerator2 } Enumeration; + +int array[sizeof(Enumeration) == sizeof(long)? 1 : -1]; + + +enum Color { Red, Green, Blue }; + +struct X { + enum Color : 4; + enum Color field1: 4; + enum Other : Integer field2; + enum Other : Integer field3 : 4; + enum : Integer { Blah, Blarg } field4 : 4; +}; + +void test() { + long value = 2; + Enumeration e = value; +} + +// <rdar://10381507> +typedef enum : long { Foo } IntegerEnum; +int arr[(sizeof(typeof(Foo)) == sizeof(typeof(IntegerEnum))) - 1]; +int arr1[(sizeof(typeof(Foo)) == sizeof(typeof(long))) - 1]; +int arr2[(sizeof(typeof(IntegerEnum)) == sizeof(typeof(long))) - 1]; + +// <rdar://problem/10760113> +typedef enum : long long { Bar = -1 } LongLongEnum; +int arr3[(long long)Bar == (long long)-1 ? 1 : -1]; diff --git a/clang/test/SemaObjC/err-ivar-access-in-class-method.m b/clang/test/SemaObjC/err-ivar-access-in-class-method.m new file mode 100644 index 0000000..2a5e0dc --- /dev/null +++ b/clang/test/SemaObjC/err-ivar-access-in-class-method.m @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -x objective-c -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://10593227 + +@class UIWindow; + +@interface CNAppDelegate + +@property (strong, nonatomic) UIWindow *window; + +@end + + +@interface CNAppDelegate () +@property (nonatomic,retain) id foo; +@end + +@implementation CNAppDelegate +@synthesize foo; +@synthesize window = _window; + ++(void)myClassMethod; +{ + foo = 0; // expected-error {{instance variable 'foo' accessed in class method}} +} +@end diff --git a/clang/test/SemaObjC/error-implicit-property.m b/clang/test/SemaObjC/error-implicit-property.m new file mode 100644 index 0000000..ea0587a --- /dev/null +++ b/clang/test/SemaObjC/error-implicit-property.m @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -verify %s +// rdar://11273060 + +@interface I +- (void) setP : (int)arg; +@end + +@interface J + - (int) P; +@end + +@interface K @end + +@interface II @end + +@implementation II +- (void) Meth : (I*) arg { + arg.P++; // expected-error {{no getter method 'P' for increment of property}} + --arg.P; // expected-error {{no getter method 'P' for decrement of property}} +} +- (void) Meth1 : (J*) arg { + arg.P++; // expected-error {{no setter method 'setP:' for increment of property}} + arg.P--; // expected-error {{no setter method 'setP:' for decrement of property}} +} + +- (void) Meth2 : (K*) arg { + arg.P++; // expected-error {{property 'P' not found on object of type 'K *'}} + arg.P--; // expected-error {{property 'P' not found on object of type 'K *'}} +} +@end diff --git a/clang/test/SemaObjC/error-missing-getter.m b/clang/test/SemaObjC/error-missing-getter.m new file mode 100644 index 0000000..3c91ab2 --- /dev/null +++ b/clang/test/SemaObjC/error-missing-getter.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://8155806 + +@interface Subclass +{ + int setterOnly; +} +- (void) setSetterOnly : (int) arg; +@end + +int func (int arg, Subclass *x) { + if (x.setterOnly) { // expected-error {{expected getter method not found on object of type 'Subclass *'}} + x.setterOnly = 1; + } + func(x.setterOnly + 1, x); // expected-error {{expected getter method not found on object of type 'Subclass *'}} + int i = x.setterOnly + 1; // expected-error {{expected getter method not found on object of type 'Subclass *'}} + return x.setterOnly + 1; // expected-error {{expected getter method not found on object of type 'Subclass *'}} +} + diff --git a/clang/test/SemaObjC/error-property-gc-attr.m b/clang/test/SemaObjC/error-property-gc-attr.m new file mode 100644 index 0000000..5680296 --- /dev/null +++ b/clang/test/SemaObjC/error-property-gc-attr.m @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-gc -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -triple i386-apple-darwin9 -fobjc-gc -fsyntax-only -verify -Wno-objc-root-class %s + +@interface INTF +{ + id IVAR; // expected-note {{ivar is declared here}} + __weak id II; + __weak id WID; + id ID; + __weak INTF* AWEAK; + __weak INTF* WI; +} +@property (assign) __weak id pweak; +@property (assign) __weak id WID; +@property (assign) __strong id NOT; +@property (assign) id ID; +@property (assign) INTF* AWEAK; +@property (assign) __weak INTF* WI; +@end + +@implementation INTF +@synthesize pweak=IVAR; // expected-error {{existing ivar 'IVAR' for __weak property 'pweak' must be __weak}} +@synthesize NOT=II; // expected-error {{existing ivar 'II' for strong property 'NOT' may not be __weak}} +@synthesize WID; +@synthesize ID; +@synthesize AWEAK; // expected-error {{existing ivar 'AWEAK' for strong property 'AWEAK' may not be __weak}} +@synthesize WI; +@end diff --git a/clang/test/SemaObjC/exprs.m b/clang/test/SemaObjC/exprs.m new file mode 100644 index 0000000..b198cba --- /dev/null +++ b/clang/test/SemaObjC/exprs.m @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 %s -fsyntax-only -fblocks -verify -Wno-unreachable-code + +// rdar://6597252 +Class test1(Class X) { + return 1 ? X : X; +} + + +// rdar://6079877 +void test2() { + id str = @"foo" + "bar\0" // no-warning + @"baz" " blarg"; + id str2 = @"foo" + "bar" + @"baz" + " b\0larg"; // no-warning + + + if (@encode(int) == "foo") { } // expected-warning {{result of comparison against @encode is unspecified}} +} + +#define MAX(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; }) +void (^foo)(int, int) = ^(int x, int y) { int z = MAX(x, y); }; + + + +// rdar://8445858 +@class Object; +static Object *g; +void test3(Object *o) { + // this is ok. + __sync_bool_compare_and_swap(&g, 0, o); +} + +@class Incomplete_ObjC_class; // expected-note{{forward declaration of class here}} +struct Incomplete_struct; // expected-note {{forward declaration}} + +void test_encode() { + (void)@encode(Incomplete_ObjC_class); // expected-error {{incomplete type}} + (void)@encode(struct Incomplete_struct); // expected-error {{incomplete type}} + (void)@encode(Incomplete_ObjC_class*); + (void)@encode(id); +} diff --git a/clang/test/SemaObjC/foreach.m b/clang/test/SemaObjC/foreach.m new file mode 100644 index 0000000..d0e0f7b --- /dev/null +++ b/clang/test/SemaObjC/foreach.m @@ -0,0 +1,57 @@ +/* RUN: %clang_cc1 -Wall -fsyntax-only -verify -std=c89 -pedantic %s + */ + +@class NSArray; + +void f(NSArray *a) { + id keys; + for (int i in a); /* expected-error{{selector element type 'int' is not a valid object}} */ + for ((id)2 in a); /* expected-error{{selector element is not a valid lvalue}} */ + for (2 in a); /* expected-error{{selector element is not a valid lvalue}} */ + + /* This should be ok, 'thisKey' should be scoped to the loop in question, + * and no diagnostics even in pedantic mode should happen. + * rdar://6814674 + */ + for (id thisKey in keys); + for (id thisKey in keys); +} + +/* // rdar://9072298 */ +@protocol NSObject @end + +@interface NSObject <NSObject> { + Class isa; +} +@end + +typedef struct { + unsigned long state; + id *itemsPtr; + unsigned long *mutationsPtr; + unsigned long extra[5]; +} NSFastEnumerationState; + +@protocol NSFastEnumeration + +- (unsigned long)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(unsigned long)len; + +@end + +int main () +{ + NSObject<NSFastEnumeration>* collection = ((void*)0); + for (id thing in collection) { } + + return 0; +} + +/* rdar://problem/11068137 */ +@interface Test2 +@property (assign) id prop; +@end +void test2(NSObject<NSFastEnumeration> *collection) { + Test2 *obj; + for (obj.prop in collection) { /* expected-error {{selector element is not a valid lvalue}} */ + } +} diff --git a/clang/test/SemaObjC/format-arg-attribute.m b/clang/test/SemaObjC/format-arg-attribute.m new file mode 100644 index 0000000..6edb8fd --- /dev/null +++ b/clang/test/SemaObjC/format-arg-attribute.m @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -verify -fsyntax-only %s + +@class NSString; + +extern NSString *fa2 (const NSString *) __attribute__((format_arg(1))); +extern NSString *fa3 (NSString *) __attribute__((format_arg(1))); + +extern void fc1 (const NSString *) __attribute__((format_arg)); // expected-error {{attribute takes one argument}} +extern void fc2 (const NSString *) __attribute__((format_arg())); // expected-error {{attribute takes one argument}} +extern void fc3 (const NSString *) __attribute__((format_arg(1, 2))); // expected-error {{attribute takes one argument}} + +struct s1 { int i; } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to functions}} +union u1 { int i; } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to functions}} +enum e1 { E1V0 } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to functions}} + +extern NSString *ff3 (const NSString *) __attribute__((format_arg(3-2))); +extern NSString *ff4 (const NSString *) __attribute__((format_arg(foo))); // expected-error {{attribute takes one argument}} + +/* format_arg formats must take and return a string. */ +extern NSString *fi0 (int) __attribute__((format_arg(1))); // expected-error {{format argument not a string type}} +extern NSString *fi1 (NSString *) __attribute__((format_arg(1))); + +extern NSString *fi2 (NSString *) __attribute__((format_arg(1))); + +extern int fi3 (const NSString *) __attribute__((format_arg(1))); // expected-error {{function does not return NSString}} +extern NSString *fi4 (const NSString *) __attribute__((format_arg(1))); +extern NSString *fi5 (const NSString *) __attribute__((format_arg(1))); diff --git a/clang/test/SemaObjC/format-strings-objc.m b/clang/test/SemaObjC/format-strings-objc.m new file mode 100644 index 0000000..987889b --- /dev/null +++ b/clang/test/SemaObjC/format-strings-objc.m @@ -0,0 +1,188 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -Wformat-nonliteral -fsyntax-only -fblocks -verify -Wno-objc-root-class %s + +//===----------------------------------------------------------------------===// +// The following code is reduced using delta-debugging from +// Foundation.h (Mac OS X). +// +// It includes the basic definitions for the test cases below. +// Not including Foundation.h directly makes this test case both svelt and +// portable to non-Mac platforms. +//===----------------------------------------------------------------------===// + +#include <stdarg.h> + +typedef signed char BOOL; +typedef unsigned int NSUInteger; +@class NSString, Protocol; +extern void NSLog(NSString *format, ...); +extern void NSLogv(NSString *format, va_list args); +typedef struct _NSZone NSZone; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; +@protocol NSObject - (BOOL)isEqual:(id)object; @end +@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end +@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end +@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end +@interface NSObject <NSObject> {} @end +typedef float CGFloat; +@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; @end +@interface NSSimpleCString : NSString {} @end +@interface NSConstantString : NSSimpleCString @end +extern void *_NSConstantStringClassReference; + +typedef const struct __CFString * CFStringRef; +extern void CFStringCreateWithFormat(CFStringRef format, ...) __attribute__((format(CFString, 1, 2))); + +int printf(const char * restrict, ...) ; + +//===----------------------------------------------------------------------===// +// Test cases. +//===----------------------------------------------------------------------===// + +void check_nslog(unsigned k) { + NSLog(@"%d%%", k); // no-warning + NSLog(@"%s%lb%d", "unix", 10,20); // expected-warning {{invalid conversion specifier 'b'}} +} + +// Check type validation +extern void NSLog2(int format, ...) __attribute__((format(__NSString__, 1, 2))); // expected-error {{format argument not an NSString}} +extern void CFStringCreateWithFormat2(int *format, ...) __attribute__((format(CFString, 1, 2))); // expected-error {{format argument not a CFString}} + +// <rdar://problem/7068334> - Catch use of long long with int arguments. +void rdar_7068334() { + long long test = 500; + printf("%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}} + NSLog(@"%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}} +} + +// <rdar://problem/7697748> +void rdar_7697748() { + NSLog(@"%@!"); // expected-warning{{more '%' conversions than data arguments}} +} + +@protocol Foo; + +void test_p_conversion_with_objc_pointer(id x, id<Foo> y) { + printf("%p", x); // no-warning + printf("%p", y); // no-warning +} + +// <rdar://problem/10696348>, PR 10274 - CFString and NSString formats are ignored +extern void MyNSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); +extern void MyCFStringCreateWithFormat(CFStringRef format, ...) __attribute__((format(__CFString__, 1, 2))); + +void check_mylog() { + MyNSLog(@"%@"); // expected-warning {{more '%' conversions than data arguments}} + // FIXME: find a way to test CFString too, but I don't know how to create constant CFString. +} + +// PR 10275 - format function attribute isn't checked in Objective-C methods +@interface Foo ++ (id)fooWithFormat:(NSString *)fmt, ... __attribute__((format(__NSString__, 1, 2))); ++ (id)fooWithCStringFormat:(const char *)format, ... __attribute__((format(__printf__, 1, 2))); +@end + +void check_method() { + [Foo fooWithFormat:@"%@"]; // expected-warning {{more '%' conversions than data arguments}} + [Foo fooWithCStringFormat:"%@"]; // expected-warning {{invalid conversion specifier '@'}} +} + +// Warn about using BOOL with %@ +void rdar10743758(id x) { + NSLog(@"%@ %@", x, (BOOL) 1); // expected-warning {{format specifies type 'id' but the argument has type 'BOOL' (aka 'signed char')}} +} + +NSString *test_literal_propagation(void) { + const char * const s1 = "constant string %s"; // expected-note {{format string is defined here}} + printf(s1); // expected-warning {{more '%' conversions than data arguments}} + const char * const s5 = "constant string %s"; // expected-note {{format string is defined here}} + const char * const s2 = s5; + printf(s2); // expected-warning {{more '%' conversions than data arguments}} + + const char * const s3 = (const char *)0; + printf(s3); // no-warning (NULL is a valid format string) + + NSString * const ns1 = @"constant string %s"; // expected-note {{format string is defined here}} + NSLog(ns1); // expected-warning {{more '%' conversions than data arguments}} + NSString * const ns5 = @"constant string %s"; // expected-note {{format string is defined here}} + NSString * const ns2 = ns5; + NSLog(ns2); // expected-warning {{more '%' conversions than data arguments}} + NSString * ns3 = ns1; + NSLog(ns3); // expected-warning {{format string is not a string literal}}} +} + +// Do not emit warnings when using NSLocalizedString +extern NSString *GetLocalizedString(NSString *str); +#define NSLocalizedString(key) GetLocalizedString(key) + +void check_NSLocalizedString() { + [Foo fooWithFormat:NSLocalizedString(@"format"), @"arg"]; // no-warning +} + +typedef __WCHAR_TYPE__ wchar_t; + +// Test that %S, %C, %ls check for 16 bit types in ObjC strings, as described at +// http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html#//apple_ref/doc/uid/TP40004265 + +void test_percent_S() { + const unsigned short data[] = { 'a', 'b', 0 }; + const unsigned short* ptr = data; + NSLog(@"%S", ptr); // no-warning + + const wchar_t* wchar_ptr = L"ab"; + NSLog(@"%S", wchar_ptr); // expected-warning{{format specifies type 'const unsigned short *' but the argument has type 'const wchar_t *'}} +} + +void test_percent_ls() { + const unsigned short data[] = { 'a', 'b', 0 }; + const unsigned short* ptr = data; + NSLog(@"%ls", ptr); // no-warning + + const wchar_t* wchar_ptr = L"ab"; + NSLog(@"%ls", wchar_ptr); // expected-warning{{format specifies type 'const unsigned short *' but the argument has type 'const wchar_t *'}} +} + +void test_percent_C() { + const unsigned short data = 'a'; + NSLog(@"%C", data); // no-warning + + const wchar_t wchar_data = L'a'; + NSLog(@"%C", wchar_data); // expected-warning{{format specifies type 'unsigned short' but the argument has type 'wchar_t'}} +} + +// Test that %@ works with toll-free bridging (<rdar://problem/10814120>). +void test_toll_free_bridging(CFStringRef x) { + NSLog(@"%@", x); // no-warning +} + +@interface Bar ++ (void)log:(NSString *)fmt, ...; ++ (void)log2:(NSString *)fmt, ... __attribute__((format(NSString, 1, 2))); +@end + +@implementation Bar + ++ (void)log:(NSString *)fmt, ... { + va_list ap; + va_start(ap,fmt); + NSLogv(fmt, ap); // expected-warning{{format string is not a string literal}} + va_end(ap); +} + ++ (void)log2:(NSString *)fmt, ... { + va_list ap; + va_start(ap,fmt); + NSLogv(fmt, ap); // no-warning + va_end(ap); +} + +@end + + +// Test that it is okay to use %p with the address of a block. +void rdar11049844_aux(); +int rdar11049844() { + typedef void (^MyBlock)(void); + MyBlock x = ^void() { rdar11049844_aux(); }; + printf("%p", x); // no-warning +} + diff --git a/clang/test/SemaObjC/forward-class-1.m b/clang/test/SemaObjC/forward-class-1.m new file mode 100644 index 0000000..85c6c87 --- /dev/null +++ b/clang/test/SemaObjC/forward-class-1.m @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@class FOO, BAR; // expected-note {{forward declaration of class here}} +@class FOO, BAR; + +@interface INTF : FOO // expected-error {{attempting to use the forward class 'FOO' as superclass of 'INTF'}} +@end + +@interface FOO +- (BAR*) Meth1; +- (FOO*) Meth2; +@end + +@interface INTF1 : FOO +@end + +@interface INTF2 : INTF1 // expected-note {{previous definition is here}} +@end + + +@class INTF1, INTF2; + +@interface INTF2 : INTF1 // expected-error {{duplicate interface definition for class 'INTF2'}} +@end + +// 2nd test of a forward class declaration matching a typedef name +// referring to class object. +// FIXME. This may become a negative test should we decide to make this an error. +// +@interface NSObject @end + +@protocol XCElementP @end + +typedef NSObject <XCElementP> XCElement; // expected-note {{previous definition is here}} + +@interface XCElementMainImp { + XCElement * _editingElement; +} +@end + +@class XCElement; // expected-warning {{redefinition of forward class 'XCElement' of a typedef name of an object type is ignored}} + +@implementation XCElementMainImp +- (XCElement *)editingElement { return _editingElement; } +@end + + +// rdar://9653341 +@class B; // expected-note {{forward declaration of class here}} +@interface A : B {} // expected-error {{attempting to use the forward class 'B' as superclass of 'A'}} +@end + +@interface B : A {} +@end + +@implementation A @end +@implementation B @end + diff --git a/clang/test/SemaObjC/forward-class-receiver.m b/clang/test/SemaObjC/forward-class-receiver.m new file mode 100644 index 0000000..9bcb039 --- /dev/null +++ b/clang/test/SemaObjC/forward-class-receiver.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface I ++ new; // expected-note {{method 'new' is used for the forward class}} +@end +Class isa; + +@class NotKnown; // expected-note{{forward declaration of class here}} + +void foo(NotKnown *n) { + [isa new]; + [NotKnown new]; /* expected-warning {{receiver 'NotKnown' is a forward class and corresponding}} */ +} diff --git a/clang/test/SemaObjC/forward-class-redeclare.m b/clang/test/SemaObjC/forward-class-redeclare.m new file mode 100644 index 0000000..80dc335 --- /dev/null +++ b/clang/test/SemaObjC/forward-class-redeclare.m @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://10733000 + +@interface NSObject @end + +@protocol PLAssetContainer +@property (readonly, nonatomic, retain) id assets; +@end + + +typedef NSObject <PLAssetContainer> PLAlbum; // expected-note {{previous definition is here}} + +@class PLAlbum; // expected-warning {{redefinition of forward class 'PLAlbum' of a typedef name of an object type is ignore}} + +@interface PLPhotoBrowserController +{ + PLAlbum *_album; +} +@end + +@interface WPhotoViewController:PLPhotoBrowserController +@end + +@implementation WPhotoViewController +- (void)_prepareForContracting +{ + (void)_album.assets; +} +@end diff --git a/clang/test/SemaObjC/gc-attributes.m b/clang/test/SemaObjC/gc-attributes.m new file mode 100644 index 0000000..2f54328 --- /dev/null +++ b/clang/test/SemaObjC/gc-attributes.m @@ -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{{passing argument to parameter here}} + +void test_f0() { + A *a; + static __weak A *a2; + f0(&a); + f0(&a2); // expected-warning{{passing 'A *__weak *' to parameter of type 'A *__strong *' discards qualifiers}} +} + +void f1(__weak A**); // expected-note{{passing argument to parameter here}} + +void test_f1() { + A *a; + __strong A *a2; + f1(&a); + f1(&a2); // expected-warning{{passing 'A *__strong *' to parameter of type 'A *__weak *' discards qualifiers}} +} diff --git a/clang/test/SemaObjC/gcc-cast-ext.m b/clang/test/SemaObjC/gcc-cast-ext.m new file mode 100644 index 0000000..30e0dce --- /dev/null +++ b/clang/test/SemaObjC/gcc-cast-ext.m @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -verify -fms-extensions -Wno-objc-root-class %s +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; +typedef struct _NSRange { } NSRange; + +@class PBXFileReference; + +@interface PBXDocBookmark ++ alloc; // expected-note {{method definition for 'alloc' not found}} +- autorelease; // expected-note {{method definition for 'autorelease' not found}} +@end + +// GCC allows pointer expressions in integer constant expressions. +struct { + char control[((int)(char *)2)]; +} xx; + +@implementation PBXDocBookmark // expected-warning {{incomplete implementation}} + ++ (id)bookmarkWithFileReference:(PBXFileReference *)fileRef gylphRange:(NSRange)range anchor:(NSString *)htmlAnchor +{ + NSRange r = (NSRange)range; + return [[[self alloc] initWithFileReference:fileRef gylphRange:(NSRange)range anchor:(NSString *)htmlAnchor] autorelease]; // expected-warning {{method '-initWithFileReference:gylphRange:anchor:' not found (return type defaults to 'id')}} +} +@end diff --git a/clang/test/SemaObjC/ibaction.m b/clang/test/SemaObjC/ibaction.m new file mode 100644 index 0000000..9c59d7a --- /dev/null +++ b/clang/test/SemaObjC/ibaction.m @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -verify -Wno-objc-root-class %s + +@interface Foo +{ + __attribute__((iboutlet)) id myoutlet; +} ++ (void) __attribute__((ibaction)) myClassMethod:(id)msg; // expected-warning{{ibaction attribute can only be applied to Objective-C instance methods}} +- (void) __attribute__((ibaction)) myMessage:(id)msg; +@end + +@implementation Foo ++ (void) __attribute__((ibaction)) myClassMethod:(id)msg {} // expected-warning{{ibaction attribute can only be applied to Objective-C instance methods}} +// Normally attributes should not be attached to method definitions, but +// we allow 'ibaction' to be attached because it can be expanded from +// the IBAction macro. +- (void) __attribute__((ibaction)) myMessage:(id)msg {} // no-warning +@end diff --git a/clang/test/SemaObjC/iboutletcollection-attr.m b/clang/test/SemaObjC/iboutletcollection-attr.m new file mode 100644 index 0000000..22c21a7 --- /dev/null +++ b/clang/test/SemaObjC/iboutletcollection-attr.m @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify %s +// rdar://8308053 + +@class NSObject; + +@interface I { + __attribute__((iboutletcollection(I))) id ivar1; + __attribute__((iboutletcollection(id))) id ivar2; + __attribute__((iboutletcollection())) id ivar3; + __attribute__((iboutletcollection)) id ivar4; +} +@property (nonatomic, retain) __attribute__((iboutletcollection(I))) id prop1; +@property (nonatomic, retain) __attribute__((iboutletcollection(id))) id prop2; +@property (nonatomic, retain) __attribute__((iboutletcollection())) id prop3; +@property (nonatomic, retain) __attribute__((iboutletcollection)) id prop4; +@end + +typedef void *PV; +@interface BAD { + __attribute__((iboutletcollection(I, 1))) id ivar1; // expected-error {{attribute takes one argument}} + __attribute__((iboutletcollection(B))) id ivar2; // expected-error {{invalid type 'B' as argument of iboutletcollection attribute}} + __attribute__((iboutletcollection(PV))) id ivar3; // expected-error {{invalid type 'PV' as argument of iboutletcollection attribute}} + __attribute__((iboutletcollection(PV))) void *ivar4; // expected-warning {{ivar with 'iboutletcollection' attribute must be an object type (invalid 'void *')}} + __attribute__((iboutletcollection(int))) id ivar5; // expected-error {{type argument of iboutletcollection attribute cannot be a builtin type}} + __attribute__((iboutlet)) int ivar6; // expected-warning {{ivar with 'iboutlet' attribute must be an object type}} +} +@property (nonatomic, retain) __attribute__((iboutletcollection(I,2,3))) id prop1; // expected-error {{attribute takes one argument}} +@property (nonatomic, retain) __attribute__((iboutletcollection(B))) id prop2; // expected-error {{invalid type 'B' as argument of iboutletcollection attribute}} + +@property __attribute__((iboutletcollection(BAD))) int prop3; // expected-warning {{property with 'iboutletcollection' attribute must be an object type (invalid 'int')}} +@end + +// rdar://10296078 +@interface ParentRDar10296078 @end +@class NSArray; +@protocol RDar10296078_Protocol; +@class RDar10296078_OtherClass; + +@interface RDar10296078 : ParentRDar10296078 +@property (nonatomic, strong) + __attribute__((iboutletcollection(RDar10296078_OtherClass<RDar10296078_Protocol>))) NSArray *stuff; +@end diff --git a/clang/test/SemaObjC/id-isa-ref.m b/clang/test/SemaObjC/id-isa-ref.m new file mode 100644 index 0000000..c2debb0 --- /dev/null +++ b/clang/test/SemaObjC/id-isa-ref.m @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef struct objc_object { + struct objc_class *isa; +} *id; + +@interface NSObject { + struct objc_class *isa; +} +@end +@interface Whatever : NSObject ++self; +@end + +static void func() { + + id x; + + // rdar://8290002 + [(*x).isa self]; // expected-warning {{direct access to objective-c's isa is deprecated in favor of object_setClass() and object_getClass()}} + [x->isa self]; // expected-warning {{direct access to objective-c's isa is deprecated in favor of object_setClass() and object_getClass()}} + + Whatever *y; + + // GCC allows this, with the following warning: + // instance variable 'isa' is @protected; this will be a hard error in the future + // + // FIXME: see if we can avoid the 2 warnings that follow the error. + [(*y).isa self]; // expected-error {{instance variable 'isa' is protected}} \ + expected-warning{{receiver type 'struct objc_class *' is not 'id' or interface pointer, consider casting it to 'id'}} \ + expected-warning{{method '-self' not found (return type defaults to 'id')}} + [y->isa self]; // expected-error {{instance variable 'isa' is protected}} \ + expected-warning{{receiver type 'struct objc_class *' is not 'id' or interface pointer, consider casting it to 'id'}} \ + expected-warning{{method '-self' not found (return type defaults to 'id')}} +} diff --git a/clang/test/SemaObjC/id.m b/clang/test/SemaObjC/id.m new file mode 100644 index 0000000..27b84de --- /dev/null +++ b/clang/test/SemaObjC/id.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@protocol Foo; + +Class T; +id<Foo> S; +id R; +void foo() { + // Test assignment compatibility of Class and id. No warning should be + // produced. + // rdar://6770142 - Class and id<foo> are compatible. + S = T; // expected-warning {{incompatible pointer types assigning to 'id<Foo>' from 'Class'}} + T = S; // expected-warning {{incompatible pointer types assigning to 'Class' from 'id<Foo>'}} + R = T; T = R; + R = S; S = R; +} + +// Test attempt to redefine 'id' in an incompatible fashion. +typedef int id; // FIXME: Decide how we want to deal with this (now that 'id' is more of a built-in type). +id b; + diff --git a/clang/test/SemaObjC/id_builtin.m b/clang/test/SemaObjC/id_builtin.m new file mode 100644 index 0000000..a1431d6 --- /dev/null +++ b/clang/test/SemaObjC/id_builtin.m @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify + +// id is now builtin. There should be no errors. +id obj; + +@interface Foo + +- defaultToId; + +@end diff --git a/clang/test/SemaObjC/idiomatic-parentheses.m b/clang/test/SemaObjC/idiomatic-parentheses.m new file mode 100644 index 0000000..417b948 --- /dev/null +++ b/clang/test/SemaObjC/idiomatic-parentheses.m @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wparentheses -Wno-objc-root-class %s + +// Don't warn about some common ObjC idioms unless we have -Widiomatic-parentheses on. +// <rdar://problem/7382435> + +@interface Object +- (id) init; +- (id) initWithInt: (int) i; +- (void) iterate: (id) coll; +- (id) nextObject; +@end + +@implementation Object +- (id) init { + if (self = [self init]) { + } + return self; +} + +- (id) initWithInt: (int) i { + if (self = [self initWithInt: i]) { + } + return self; +} + +- (void) iterate: (id) coll { + id cur; + while (cur = [coll nextObject]) { + } +} + +- (id) nextObject { + return self; +} +@end diff --git a/clang/test/SemaObjC/ignore-qualifier-on-qualified-id.m b/clang/test/SemaObjC/ignore-qualifier-on-qualified-id.m new file mode 100644 index 0000000..36a2c1a --- /dev/null +++ b/clang/test/SemaObjC/ignore-qualifier-on-qualified-id.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify %s +// rdar://10667659 + +@protocol NSCopying @end + +@interface NSString <NSCopying> +@end + +void takeId(id test) {} + +void takeCopyableId(id<NSCopying> test) {} + +id<NSCopying> Test () { + NSString const *constantString = @"Test"; + takeId(constantString); + takeCopyableId(constantString); + id ID = constantString; + id<NSCopying> IDQNSCopying = constantString; + return constantString; +} diff --git a/clang/test/SemaObjC/ignore-weakimport-method.m b/clang/test/SemaObjC/ignore-weakimport-method.m new file mode 100644 index 0000000..d71cebf --- /dev/null +++ b/clang/test/SemaObjC/ignore-weakimport-method.m @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +@interface foo ++ (void) cx __attribute__((weak_import)); +- (void) x __attribute__((weak_import)); +@end + diff --git a/clang/test/SemaObjC/illegal-nonarc-bridged-cast.m b/clang/test/SemaObjC/illegal-nonarc-bridged-cast.m new file mode 100644 index 0000000..a5bb01f --- /dev/null +++ b/clang/test/SemaObjC/illegal-nonarc-bridged-cast.m @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fblocks -verify %s +// rdar://10597832 + +typedef const void *CFTypeRef; +typedef const struct __CFString *CFStringRef; + +@interface NSString +@end + +CFTypeRef CFCreateSomething(); +CFStringRef CFCreateString(); +CFTypeRef CFGetSomething(); +CFStringRef CFGetString(); + +id CreateSomething(); +NSString *CreateNSString(); + +void from_cf() { + id obj1 = (__bridge_transfer id)CFCreateSomething(); // expected-warning {{'__bridge_transfer' casts have no effect when not using ARC}} + id obj2 = (__bridge_transfer NSString*)CFCreateString(); // expected-warning {{'__bridge_transfer' casts have no effect when not using ARC}} + (__bridge int*)CFCreateSomething(); // expected-warning {{'__bridge' casts have no effect when not using ARC}} \ + // expected-warning {{expression result unused}} + id obj3 = (__bridge id)CFGetSomething(); // expected-warning {{'__bridge' casts have no effect when not using ARC}} + id obj4 = (__bridge NSString*)CFGetString(); // expected-warning {{'__bridge' casts have no effect when not using ARC}} +} + +void to_cf(id obj) { + CFTypeRef cf1 = (__bridge_retained CFTypeRef)CreateSomething(); // expected-warning {{'__bridge_retained' casts have no effect when not using ARC}} + CFStringRef cf2 = (__bridge_retained CFStringRef)CreateNSString(); // expected-warning {{'__bridge_retained' casts have no effect when not using ARC}} + CFTypeRef cf3 = (__bridge CFTypeRef)CreateSomething(); // expected-warning {{'__bridge' casts have no effect when not using ARC}} + CFStringRef cf4 = (__bridge CFStringRef)CreateNSString(); // expected-warning {{'__bridge' casts have no effect when not using ARC}} +} + +void fixits() { + id obj1 = (id)CFCreateSomething(); + CFTypeRef cf1 = (CFTypeRef)CreateSomething(); +} + +#pragma clang diagnostic ignored "-Warc-bridge-casts-disallowed-in-nonarc" + +void to_cf_ignored(id obj) { + CFTypeRef cf1 = (__bridge_retained CFTypeRef)CreateSomething(); // no-warning + CFTypeRef cf3 = (__bridge CFTypeRef)CreateSomething(); // no-warning +} diff --git a/clang/test/SemaObjC/incompatible-protocol-qualified-types.m b/clang/test/SemaObjC/incompatible-protocol-qualified-types.m new file mode 100644 index 0000000..494d23e --- /dev/null +++ b/clang/test/SemaObjC/incompatible-protocol-qualified-types.m @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -pedantic -fsyntax-only -verify %s + +@protocol MyProto1 +@end + +@protocol MyProto2 +@end + +@interface INTF @end + +INTF <MyProto1> * Func(INTF <MyProto1, MyProto2> *p2) // expected-note{{passing argument to parameter 'p2' here}} +{ + return p2; +} + + +INTF <MyProto1> * Func1(INTF <MyProto1, MyProto2> *p2) +{ + return p2; +} + +INTF <MyProto1, MyProto2> * Func2(INTF <MyProto1> *p2) +{ + Func(p2); // expected-warning {{incompatible pointer types passing 'INTF<MyProto1> *' to parameter of type 'INTF<MyProto1,MyProto2> *'}} + return p2; // expected-warning {{incompatible pointer types returning 'INTF<MyProto1> *' from a function with result type 'INTF<MyProto1,MyProto2> *'}} +} + + + +INTF <MyProto1> * Func3(INTF <MyProto2> *p2) +{ + return p2; // expected-warning {{incompatible pointer types returning 'INTF<MyProto2> *' from a function with result type 'INTF<MyProto1> *'}} +} + + +INTF <MyProto1, MyProto2> * Func4(INTF <MyProto2, MyProto1> *p2) +{ + return p2; +} + diff --git a/clang/test/SemaObjC/incomplete-implementation.m b/clang/test/SemaObjC/incomplete-implementation.m new file mode 100644 index 0000000..54f66ef --- /dev/null +++ b/clang/test/SemaObjC/incomplete-implementation.m @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface I +- Meth; // expected-note{{method definition for 'Meth' not found}} \ + // expected-note{{method 'Meth' declared here}} +@end + +@implementation I // expected-warning{{incomplete implementation}} +@end + +@implementation I(CAT) +- Meth {return 0;} // expected-warning {{category is implementing a method which will also be implemented by its primary class}} +@end + +#pragma GCC diagnostic ignored "-Wincomplete-implementation" +@interface I2 +- Meth; // expected-note{{method 'Meth' declared here}} +@end + +@implementation I2 +@end + +@implementation I2(CAT) +- Meth {return 0;} // expected-warning {{category is implementing a method which will also be implemented by its primary class}} +@end + +@interface Q +@end + +// rdar://10336158 +@implementation Q + +__attribute__((visibility("default"))) +@interface QN // expected-error {{Objective-C declarations may only appear in global scope}} +{ +} +@end + +@end + diff --git a/clang/test/SemaObjC/inst-method-lookup-in-root.m b/clang/test/SemaObjC/inst-method-lookup-in-root.m new file mode 100644 index 0000000..babd2a0 --- /dev/null +++ b/clang/test/SemaObjC/inst-method-lookup-in-root.m @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@protocol P +- (id) inst_in_proto; +@end + +@interface Object <P> +- (id) inst_in_root; +@end + +@interface Base +@end + +@interface Derived: Base +- (id)starboard; +@end + +void foo(void) { + Class receiver; + + [Derived starboard]; // expected-warning {{method '+starboard' not found}} + + [receiver starboard]; // expected-warning {{instance method 'starboard' is being used on 'Class'}} + [receiver inst_in_root]; // Ok! + [receiver inst_in_proto]; // Ok! +} + diff --git a/clang/test/SemaObjC/instancetype.m b/clang/test/SemaObjC/instancetype.m new file mode 100644 index 0000000..40f35d9 --- /dev/null +++ b/clang/test/SemaObjC/instancetype.m @@ -0,0 +1,190 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#if !__has_feature(objc_instancetype) +# error Missing 'instancetype' feature macro. +#endif + +@interface Root ++ (instancetype)alloc; +- (instancetype)init; // expected-note{{overridden method is part of the 'init' method family}} +- (instancetype)self; +- (Class)class; + +@property (assign) Root *selfProp; +- (instancetype)selfProp; +@end + +@protocol Proto1 +@optional +- (instancetype)methodInProto1; +@end + +@protocol Proto2 +@optional +- (instancetype)methodInProto2; // expected-note{{overridden method returns an instance of its class type}} +- (instancetype)otherMethodInProto2; // expected-note{{overridden method returns an instance of its class type}} +@end + +@interface Subclass1 : Root +- (instancetype)initSubclass1; +- (void)methodOnSubclass1; ++ (instancetype)allocSubclass1; +@end + +@interface Subclass2 : Root +- (instancetype)initSubclass2; +- (void)methodOnSubclass2; +@end + +// Sanity check: the basic initialization pattern. +void test_instancetype_alloc_init_simple() { + Root *r1 = [[Root alloc] init]; + Subclass1 *sc1 = [[Subclass1 alloc] init]; +} + +// Test that message sends to instancetype methods have the right type. +void test_instancetype_narrow_method_search() { + // instancetype on class methods + Subclass1 *sc1 = [[Subclass1 alloc] initSubclass2]; // expected-warning{{'Subclass1' may not respond to 'initSubclass2'}} + Subclass2 *sc2 = [[Subclass2 alloc] initSubclass2]; // okay + + // instancetype on instance methods + [[[Subclass1 alloc] init] methodOnSubclass2]; // expected-warning{{'Subclass1' may not respond to 'methodOnSubclass2'}} + [[[Subclass2 alloc] init] methodOnSubclass2]; + + // instancetype on class methods using protocols + typedef Subclass1<Proto1> SC1Proto1; + typedef Subclass1<Proto2> SC1Proto2; + [[SC1Proto1 alloc] methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}} + [[SC1Proto2 alloc] methodInProto2]; + + // instancetype on instance methods + Subclass1<Proto1> *sc1proto1 = 0; + [[sc1proto1 self] methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}} + Subclass1<Proto2> *sc1proto2 = 0; + [[sc1proto2 self] methodInProto2]; + + // Exact type checks + typeof([[Subclass1 alloc] init]) *ptr1 = (Subclass1 **)0; + typeof([[Subclass2 alloc] init]) *ptr2 = (Subclass2 **)0; + + // Message sends to Class. + Subclass1<Proto1> *sc1proto1_2 = [[[sc1proto1 class] alloc] init]; + + // Property access + [sc1proto1.self methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}} + [sc1proto2.self methodInProto2]; + [Subclass1.alloc initSubclass2]; // expected-warning{{'Subclass1' may not respond to 'initSubclass2'}} + [Subclass2.alloc initSubclass2]; + + [sc1proto1.selfProp methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}} + [sc1proto2.selfProp methodInProto2]; +} + +// Test that message sends to super methods have the right type. +@interface Subsubclass1 : Subclass1 +- (instancetype)initSubclass1; ++ (instancetype)allocSubclass1; + +- (void)onlyInSubsubclass1; +@end + +@implementation Subsubclass1 +- (instancetype)initSubclass1 { + // Check based on method search. + [[super initSubclass1] methodOnSubclass2]; // expected-warning{{'Subsubclass1' may not respond to 'methodOnSubclass2'}} + [super.initSubclass1 methodOnSubclass2]; // expected-warning{{'Subsubclass1' may not respond to 'methodOnSubclass2'}} + + self = [super init]; // common pattern + + // Exact type check. + typeof([super initSubclass1]) *ptr1 = (Subsubclass1**)0; + + return self; +} + ++ (instancetype)allocSubclass1 { + // Check based on method search. + [[super allocSubclass1] methodOnSubclass2]; // expected-warning{{'Subsubclass1' may not respond to 'methodOnSubclass2'}} + + // The ASTs don't model super property accesses well enough to get this right + [super.allocSubclass1 methodOnSubclass2]; // expected-warning{{'Subsubclass1' may not respond to 'methodOnSubclass2'}} + + // Exact type check. + typeof([super allocSubclass1]) *ptr1 = (Subsubclass1**)0; + + return [super allocSubclass1]; +} + +- (void)onlyInSubsubclass1 {} +@end + +// Check compatibility rules for inheritance of related return types. +@class Subclass4; + +@interface Subclass3 <Proto1, Proto2> +- (Subclass3 *)methodInProto1; +- (Subclass4 *)methodInProto2; // expected-warning{{method is expected to return an instance of its class type 'Subclass3', but is declared to return 'Subclass4 *'}} +@end + +@interface Subclass4 : Root ++ (Subclass4 *)alloc; // okay +- (Subclass3 *)init; // expected-warning{{method is expected to return an instance of its class type 'Subclass4', but is declared to return 'Subclass3 *'}} +- (id)self; // expected-note{{overridden method is part of the 'self' method family}} +- (instancetype)initOther; +@end + +@protocol Proto3 <Proto1, Proto2> +@optional +- (id)methodInProto1; +- (Subclass1 *)methodInProto2; +- (int)otherMethodInProto2; // expected-warning{{protocol method is expected to return an instance of the implementing class, but is declared to return 'int'}} +@end + +@implementation Subclass4 ++ (id)alloc { + return self; // expected-warning{{incompatible pointer types casting 'Class' to type 'Subclass4 *'}} +} + +- (Subclass3 *)init { return 0; } // don't complain: we lost the related return type + +- (Subclass3 *)self { return 0; } // expected-warning{{method is expected to return an instance of its class type 'Subclass4', but is declared to return 'Subclass3 *'}} + +- (Subclass4 *)initOther { return 0; } + +@end + +// Check that inherited related return types influence the types of +// message sends. +void test_instancetype_inherited() { + [[Subclass4 alloc] initSubclass1]; // expected-warning{{'Subclass4' may not respond to 'initSubclass1'}} + [[Subclass4 alloc] initOther]; +} + +// Check that related return types tighten up the semantics of +// Objective-C method implementations. +@implementation Subclass2 +- (instancetype)initSubclass2 { + Subclass1 *sc1 = [[Subclass1 alloc] init]; + return sc1; // expected-warning{{incompatible pointer types casting 'Subclass1 *' to type 'Subclass2 *'}} +} +- (void)methodOnSubclass2 {} +- (id)self { + Subclass1 *sc1 = [[Subclass1 alloc] init]; + return sc1; // expected-warning{{incompatible pointer types casting 'Subclass1 *' to type 'Subclass2 *'}} +} +@end + +@interface MyClass : Root ++ (int)myClassMethod; +@end + +@implementation MyClass ++ (int)myClassMethod { return 0; } + +- (void)blah { + int i = [[MyClass self] myClassMethod]; +} + +@end + diff --git a/clang/test/SemaObjC/interface-1.m b/clang/test/SemaObjC/interface-1.m new file mode 100644 index 0000000..87c2307 --- /dev/null +++ b/clang/test/SemaObjC/interface-1.m @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-fragile-abi %s -fsyntax-only -verify +// rdar://5957506 + +@interface NSWhatever : +NSObject // expected-error {{cannot find interface declaration for 'NSObject'}} +<NSCopying> // expected-error {{cannot find protocol declaration for 'NSCopying'}} +@end + + +// rdar://6095245 +@interface A +{ + int x +} // expected-error {{expected ';' at end of declaration list}} +@end + + +// rdar://4304469 +@interface INT1 +@end + +void test2() { + // rdar://6827200 + INT1 b[3]; // expected-error {{array of interface 'INT1' is invalid (probably should be an array of pointers)}} + INT1 *c = &b[0]; + ++c; +} + + +// rdar://6611778 +@interface FOO // expected-note {{previous definition is here}} +- (void)method; +@end + +@interface FOO // expected-error {{duplicate interface definition for class 'FOO'}} +- (void)method2; +@end + diff --git a/clang/test/SemaObjC/interface-layout-2.m b/clang/test/SemaObjC/interface-layout-2.m new file mode 100644 index 0000000..02b1403 --- /dev/null +++ b/clang/test/SemaObjC/interface-layout-2.m @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify +@interface A +{ + int ivar; +} +@end + +@interface B : A +- (int)ivar; +@end + +@implementation B +- (int)ivar { + return ivar; +} +@end diff --git a/clang/test/SemaObjC/interface-layout.m b/clang/test/SemaObjC/interface-layout.m new file mode 100644 index 0000000..a8a93f0 --- /dev/null +++ b/clang/test/SemaObjC/interface-layout.m @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -triple i386-apple-darwin9 -fobjc-fragile-abi +typedef struct objc_object {} *id; +typedef signed char BOOL; +typedef unsigned int NSUInteger; +typedef struct _NSZone NSZone; + +@protocol NSObject +- (BOOL) isEqual:(id) object; +@end + +@protocol NSCopying +- (id) copyWithZone:(NSZone *) zone; +@end + +@interface NSObject < NSObject > {} +@end + +extern id NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone * zone); + +@interface MyClassBase : NSObject < NSCopying > {} +@end + +@interface MyClassDirectNode : MyClassBase < NSCopying > +{ + @public NSUInteger attributeRuns[((1024 - 16 - sizeof (MyClassBase)) / (sizeof (NSUInteger) + sizeof (void *)))]; +} +@end diff --git a/clang/test/SemaObjC/interface-scope-2.m b/clang/test/SemaObjC/interface-scope-2.m new file mode 100644 index 0000000..60fd900 --- /dev/null +++ b/clang/test/SemaObjC/interface-scope-2.m @@ -0,0 +1,128 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-apple-darwin9 -Wno-objc-root-class %s +// FIXME: must also compile as Objective-C++ + +// <rdar://problem/6487662> +typedef struct objc_selector *SEL; +typedef signed char BOOL; +typedef unsigned int NSUInteger; +typedef struct _NSZone NSZone; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (BOOL)respondsToSelector:(SEL)aSelector; +@end +@protocol NSCopying +- (id)copyWithZone:(NSZone *)zone; +@end +@protocol NSMutableCopying +- (id)mutableCopyWithZone:(NSZone *)zone; +@end +@protocol NSCoding +- (void)encodeWithCoder:(NSCoder *)aCoder; +@end +@interface NSObject <NSObject> {} +@end +@class NSString, NSData; +typedef struct _NSPoint {} +NSRange; +@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> +- (NSUInteger)length; +@end +@interface NSMutableString : NSString +- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)aString; +@end +@class NSArray, NSDictionary, NSMapTable; +@interface NSResponder : NSObject <NSCoding> {} +@end +@protocol NSAnimatablePropertyContainer +- (id)animator; +@end +extern NSString *NSAnimationTriggerOrderIn ; +@interface NSView : NSResponder <NSAnimatablePropertyContainer> { + struct __VFlags2 {} _vFlags2; +} +@end +@class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView; +@interface FooiagramView : NSView { +id _delegate; +} +@end +@class FooiagramView; +@interface _FooiagramViewReserved : NSObject { +@public + NSMutableString *_typeToSelectString; + struct _FooiagramViewFlags { + unsigned int delegateRespondsToPrintInfoForBarView : 1; + } _dvFlags; +} +@end +extern _FooiagramViewReserved *_FooiagramViewBarViewReserved(FooiagramView *BarView); +@interface FooiagramView (FooiagramViewPrivate) ++ (Class)_defaultBarToolManagerClass; +@end +@implementation FooiagramView +static NSMapTable *_defaultMenuForClass = 0; +- (void)setDelegate:(id)delegate { + if (_delegate != delegate) { + struct _FooiagramViewFlags *dvFlags = + &_FooiagramViewBarViewReserved(self)->_dvFlags; + if (_delegate != ((void *)0)) { + dvFlags->delegateRespondsToPrintInfoForBarView = [_delegate respondsToSelector:@selector(printInfoForBarView:)]; + } + } +} +@end + +// <rdar://problem/6487684> +@interface WizKing_MIKeep { +struct __LoreStuffNode *_historyStuff; +} +@end +typedef struct __LoreStuffNode {} LoreStuffNode; +@implementation WizKing_MIKeep +- init { + LoreStuffNode *node; + node = &(_historyStuff[1]); + return 0; +} +@end + +// <rdar://problem/6487702> +typedef long unsigned int __darwin_size_t; +typedef __darwin_size_t size_t; +void *memset(void *, int, size_t); +@class NSString, NSURL, NSError; +@interface OingoWerdnaPeon : NSObject {} +@end typedef enum { +OingoPT_SmashOK, OingoPT_NoSuchFile, } +OingoWerdnaPeonIOMethod; +@interface OingoWerdnaPeonSmashDrivel : NSObject <NSCopying> {} +@end +@interface OingoBoingoContraptionPeon : OingoWerdnaPeon { +struct _OingoBoingoContraptionPeonFlags {} +_nfttFlags; +} +@end +@implementation OingoBoingoContraptionPeon ++ (void)initialize {} +- (id)initWithSmashDrivel:(OingoWerdnaPeonSmashDrivel *)info { + if (self != ((void *)0)) { + (void)memset(&_nfttFlags, 0, sizeof(struct _OingoBoingoContraptionPeonFlags)); + } + return 0; +} +@end + +@interface Blah { + struct X { + int x; + } value; +} +@end + +@implementation Blah +- (int)getValue { + struct X *xp = &value; + return xp->x; +} +@end diff --git a/clang/test/SemaObjC/interface-scope.m b/clang/test/SemaObjC/interface-scope.m new file mode 100644 index 0000000..0671dae --- /dev/null +++ b/clang/test/SemaObjC/interface-scope.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface I1 { +@private + int x; + struct { + unsigned int x : 3; + unsigned int y : 3; + } flags; + int y; +} +@end diff --git a/clang/test/SemaObjC/interface-tu-variable.m b/clang/test/SemaObjC/interface-tu-variable.m new file mode 100644 index 0000000..b8779cc --- /dev/null +++ b/clang/test/SemaObjC/interface-tu-variable.m @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface XX +int x; // expected-error {{cannot declare variable inside @interface or @protocol}} +int one=1; // expected-error {{cannot declare variable inside @interface or @protocol}} +@end + +@protocol PPP +int ddd; // expected-error {{cannot declare variable inside @interface or @protocol}} +@end + +@interface XX(CAT) + char * III; // expected-error {{cannot declare variable inside @interface or @protocol}} + extern int OK; +@end + +@interface XX() + char * III2; // expected-error {{cannot declare variable inside @interface or @protocol}} + extern int OK2; +@end + + +int main( int argc, const char *argv[] ) { + return x+one; +} + diff --git a/clang/test/SemaObjC/invalid-code.m b/clang/test/SemaObjC/invalid-code.m new file mode 100644 index 0000000..290f9d5 --- /dev/null +++ b/clang/test/SemaObjC/invalid-code.m @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fobjc-exceptions -Wno-objc-root-class %s + +// rdar://6124613 +void test1() { + void *xyzzy = 0; + void *p = @xyzzy; // expected-error {{unexpected '@' in program}} +} + +// <rdar://problem/7495713> +// This previously triggered a crash because the class has not been defined. +@implementation RDar7495713 (rdar_7495713_cat) // expected-error{{cannot find interface declaration for 'RDar7495713'}} +- (id) rdar_7495713 { + __PRETTY_FUNCTION__; // expected-warning{{expression result unused}} +} +@end + +// <rdar://problem/7881045> +// This previously triggered a crash because a ';' was expected after the @throw statement. +void foo() { + @throw (id)0 // expected-error{{expected ';' after @throw}} +} + +// <rdar://problem/10415026> +@class NSView; +@implementation IBFillView(IBFillViewIntegration) // expected-error {{cannot find interface declaration for 'IBFillView'}} +- (NSView *)ibDesignableContentView { + [Cake lie]; // expected-error {{undeclared}} + return self; +} +@end + +@interface I +@end +@interface I2 +@end + +@implementation I // expected-note {{started here}} +-(void) foo {} + +@implementation I2 // expected-error {{missing '@end'}} +-(void) foo2 {} +@end + +@end // expected-error {{'@end' must appear in an Objective-C context}} + +@class ForwardBase; +@implementation SomeI : ForwardBase // expected-error {{cannot find interface declaration for 'ForwardBase', superclass of 'SomeI'}} \ + // expected-warning {{cannot find interface declaration for 'SomeI'}} +-(void)meth {} +@end + +@interface I3 +__attribute__((unavailable)) @interface I4 @end // expected-error {{Objective-C declarations may only appear in global scope}} +@end diff --git a/clang/test/SemaObjC/invalid-objc-decls-1.m b/clang/test/SemaObjC/invalid-objc-decls-1.m new file mode 100644 index 0000000..46338bb --- /dev/null +++ b/clang/test/SemaObjC/invalid-objc-decls-1.m @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface Super @end +Super s1; // expected-error{{interface type cannot be statically allocated}} + +extern Super e1; // expected-error{{interface type cannot be statically allocated}} + +struct S { + Super s1; // expected-error{{interface type cannot be statically allocated}} +}; + +@protocol P1 @end + +@interface INTF +{ + Super ivar1; // expected-error{{interface type cannot be statically allocated}} +} +@end + +struct whatever { + Super objField; // expected-error{{interface type cannot be statically allocated}} +}; + +@interface MyIntf +{ + Super<P1> ivar1; // expected-error{{interface type cannot be statically allocated}} +} +@end + +Super foo( // expected-error{{interface type 'Super' cannot be returned by value; did you forget * in 'Super'}} + Super parm1) { // expected-error{{interface type 'Super' cannot be passed by value; did you forget * in 'Super'}} + Super p1; // expected-error{{interface type cannot be statically allocated}} + return p1; +} + +@interface NSMutableSet @end + +@interface DVTDummyAnnotationProvider + @property(readonly) NSMutableSet annotations; // expected-error{{interface type cannot be statically allocated}} + +@end + diff --git a/clang/test/SemaObjC/invalid-receiver.m b/clang/test/SemaObjC/invalid-receiver.m new file mode 100644 index 0000000..1174dd2 --- /dev/null +++ b/clang/test/SemaObjC/invalid-receiver.m @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef struct NotAClass { + int a, b; +} NotAClass; + +void foo() { + [NotAClass nonexistent_method]; // expected-error {{receiver type 'NotAClass' (aka 'struct NotAClass') is not an Objective-C class}} +} diff --git a/clang/test/SemaObjC/invalid-typename.m b/clang/test/SemaObjC/invalid-typename.m new file mode 100644 index 0000000..50dd188 --- /dev/null +++ b/clang/test/SemaObjC/invalid-typename.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@class NSString, NSArray; + +@protocol ISyncSessionCallback +- (oneway void)clientWithId:(bycopy NSString *)clientId + canBeginSyncingPlanWithId:(bycopy NSString *)planId + syncModes:(bycopy NSArray /* ISDSyncState */ *)syncModes + entities:(bycopy NSArray /* ISDEntity */ *)entities + truthPullers:(bycopy NSDictionary /* NSString -> [NSString] */ *)truthPullers; // expected-error{{expected ')'}} expected-note {{to match this '('}} +@end + diff --git a/clang/test/SemaObjC/ivar-access-package.m b/clang/test/SemaObjC/ivar-access-package.m new file mode 100644 index 0000000..abc3420 --- /dev/null +++ b/clang/test/SemaObjC/ivar-access-package.m @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef unsigned char BOOL; + +@interface NSObject { + id isa; +} ++new; ++alloc; +-init; +-autorelease; +@end + +@interface NSAutoreleasePool : NSObject +- drain; +@end + +@interface A : NSObject { +@package + id object; +} +@end + +@interface B : NSObject +- (BOOL)containsSelf:(A*)a; +@end + +@implementation A +@end + +@implementation B +- (BOOL)containsSelf:(A*)a { + return a->object == self; +} +@end + +void NSLog(id, ...); + +int main (int argc, const char * argv[]) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + A *a = [[A new] autorelease]; + B *b = [[B new] autorelease]; + NSLog(@"%s", [b containsSelf:a] ? "YES" : "NO"); + [pool drain]; + return 0; +} + diff --git a/clang/test/SemaObjC/ivar-access-tests.m b/clang/test/SemaObjC/ivar-access-tests.m new file mode 100644 index 0000000..cd7e09d --- /dev/null +++ b/clang/test/SemaObjC/ivar-access-tests.m @@ -0,0 +1,122 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface MySuperClass +{ +@private + int private; + +@protected + int protected; + +@public + int public; +} +@end + +@implementation MySuperClass +- (void) test { + int access; + MySuperClass *s = 0; + access = s->private; + access = s->protected; +} +@end + + +@interface MyClass : MySuperClass +@end + +@implementation MyClass +- (void) test { + int access; + MySuperClass *s = 0; + access = s->private; // expected-error {{instance variable 'private' is private}} + access = s->protected; + MyClass *m=0; + access = m->private; // expected-error {{instance variable 'private' is private}} + access = m->protected; +} +@end + + +@interface Deeper : MyClass +@end + +@implementation Deeper +- (void) test { + int access; + MySuperClass *s = 0; + access = s->private; // expected-error {{instance variable 'private' is private}} + access = s->protected; + MyClass *m=0; + access = m->private; // expected-error {{instance variable 'private' is private}} + access = m->protected; +} +@end + +@interface Unrelated +@end + +@implementation Unrelated +- (void) test { + int access; + MySuperClass *s = 0; + access = s->private; // expected-error {{instance variable 'private' is private}} + access = s->protected; // expected-error {{instance variable 'protected' is protected}} + MyClass *m=0; + access = m->private; // expected-error {{instance variable 'private' is private}} + access = m->protected; // expected-error {{instance variable 'protected' is protected}} +} +@end + +int main (void) +{ + MySuperClass *s = 0; + int access; + access = s->private; // expected-error {{instance variable 'private' is private}} + access = s->protected; // expected-error {{instance variable 'protected' is protected}} + return 0; +} + +typedef signed char BOOL; +typedef unsigned int NSUInteger; +typedef struct _NSZone NSZone; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; +@protocol NSObject - (BOOL)isEqual:(id)object; +@end +@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; +@end +@interface NSObject <NSObject> {} +@end +extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); +@interface NSResponder : NSObject <NSCoding> {} +@end +@protocol NSAnimatablePropertyContainer +- (id)animator; +@end +extern NSString *NSAnimationTriggerOrderIn ; +@interface NSView : NSResponder <NSAnimatablePropertyContainer> { + struct __VFlags2 { + } + _vFlags2; +} +@end +@class NSFontDescriptor, NSAffineTransform, NSGraphicsContext; +@interface NSScrollView : NSView {} +@end + +@class CasperMixerView; +@interface CasperDiffScrollView : NSScrollView { +@private + CasperMixerView *_comparatorView; + NSView *someField; +} +@end + +@implementation CasperDiffScrollView ++ (void)initialize {} +static void _CasperDiffScrollViewInstallMixerView(CasperDiffScrollView *scrollView) { + if (scrollView->someField != ((void *)0)) { + } +} +@end diff --git a/clang/test/SemaObjC/ivar-in-class-extension-error.m b/clang/test/SemaObjC/ivar-in-class-extension-error.m new file mode 100644 index 0000000..cecaa33 --- /dev/null +++ b/clang/test/SemaObjC/ivar-in-class-extension-error.m @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fobjc-fragile-abi -fsyntax-only -verify %s +// rdar://6812436 + +@interface A @end + +@interface A () { + int _p0; // expected-error {{ivars may not be placed in class extension}} +} +@property int p0; +@end + +@interface A(CAT) { + int _p1; // expected-error {{ivars may not be placed in categories}} +} +@end diff --git a/clang/test/SemaObjC/ivar-in-class-extension.m b/clang/test/SemaObjC/ivar-in-class-extension.m new file mode 100644 index 0000000..cf02d26 --- /dev/null +++ b/clang/test/SemaObjC/ivar-in-class-extension.m @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface SomeClass @end + +int fn1(SomeClass *obj) { + obj->privateIvar = 1; // expected-error {{'SomeClass' does not have a member named 'privateIvar}} + return obj->publicIvar; // expected-error {{'SomeClass' does not have a member named 'publicIvar'}} +} + +@interface SomeClass () { +// @private by default + int privateIvar; +@public + int publicIvar; +} +@end + +int fn2(SomeClass *obj) { + obj->publicIvar = 1; + return obj->publicIvar // ok + + obj->privateIvar; // expected-error {{instance variable 'privateIvar' is private}} +} + +@implementation SomeClass + +int fn3(SomeClass *obj) { + obj->privateIvar = 2; + return obj->publicIvar // ok + + obj->privateIvar; // ok + } +@end + +@interface SomeClass (Category) + { + int categoryIvar; // expected-error {{ivars may not be placed in categories}} + } +@end + +@interface SomeClass (Category1) + { + } +@end diff --git a/clang/test/SemaObjC/ivar-in-implementations.m b/clang/test/SemaObjC/ivar-in-implementations.m new file mode 100644 index 0000000..7281f55 --- /dev/null +++ b/clang/test/SemaObjC/ivar-in-implementations.m @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface Super @end + +@interface INTFSTANDALONE : Super +{ + id IVAR; // expected-note {{previous definition is here}} +} + +@end + +@implementation INTFSTANDALONE : Super // expected-warning {{class implementation may not have super class}} +{ + id PRIV_IVAR; +@protected + id PRTCTD; +@private + id IVAR3; + int IVAR; // expected-error {{instance variable is already declared}} +@public + id IVAR4; +} +@end + +@interface Base @end + +@implementation Base { + int ivar1; +@public + int ivar2; +} +@end + +id fn1(INTFSTANDALONE *b) { return b->PRIV_IVAR; } // expected-error {{instance variable 'PRIV_IVAR' is private}} + +id fn2(INTFSTANDALONE *b) { return b->PRTCTD; } // expected-error {{instance variable 'PRTCTD' is protected}} + +id fn4(INTFSTANDALONE *b) { return b->IVAR4; } + diff --git a/clang/test/SemaObjC/ivar-lookup-resolution-builtin.m b/clang/test/SemaObjC/ivar-lookup-resolution-builtin.m new file mode 100644 index 0000000..dd11b51 --- /dev/null +++ b/clang/test/SemaObjC/ivar-lookup-resolution-builtin.m @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// pr5986 + +@interface Test { + int index; +} +- (int) index; ++ (int) ClassMethod; +@end + +@implementation Test +- (int) index +{ + return index; +} ++ (int) ClassMethod +{ + return index; // expected-error {{instance variable 'index' accessed in class method}} +} +@end + +@interface Test1 { +} +- (int) InstMethod; ++ (int) ClassMethod; +@end + +@implementation Test1 +- (int) InstMethod +{ + return index; // expected-warning {{implicitly declaring library function 'index'}} \ + // expected-note {{please include the header <strings.h> or explicitly provide a declaration for 'index'}} \ + // expected-warning {{incompatible pointer to integer conversion returning}} +} ++ (int) ClassMethod +{ + return index; // expected-warning {{incompatible pointer to integer conversion returning}} +} +@end + diff --git a/clang/test/SemaObjC/ivar-lookup.m b/clang/test/SemaObjC/ivar-lookup.m new file mode 100644 index 0000000..df9d8ba --- /dev/null +++ b/clang/test/SemaObjC/ivar-lookup.m @@ -0,0 +1,82 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface Test { + int x; +} + +-(void) setX: (int) d; +@end + +extern struct foo x; + +@implementation Test + +-(void) setX: (int) n { + x = n; +} + +@end + +@interface Ivar +- (float*)method; +@end + +@interface A { + A *Ivar; +} +- (int*)method; +@end + +@implementation A +- (int*)method { + int *ip = [Ivar method]; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'float *'}} + // Note that there is no warning in Objective-C++ + return 0; +} +@end + +@interface TwoIvars { + int a; + int b; +} +@end + +@implementation TwoIvars ++ (int)classMethod { + return a + b; // expected-error{{instance variable 'a' accessed in class method}} \ + // expected-error{{instance variable 'b' accessed in class method}} +} +@end + +// rdar://10309454 +@interface Radar10309454 +{ + int IVAR; // expected-note 4 {{previous definition is here}} +} +@end + +@interface Radar10309454() +{ + int IVAR; // expected-error {{instance variable is already declared}} + int PIVAR; // expected-note {{previous definition is here}} +} +@end + +@interface Radar10309454() +{ + int IVAR; // expected-error {{instance variable is already declared}} +} +@end + +@interface Radar10309454() +{ + int IVAR; // expected-error {{instance variable is already declared}} + int PIVAR; // expected-error {{instance variable is already declared}} +} +@end + +@implementation Radar10309454 +{ + int IVAR; // expected-error {{instance variable is already declared}} +} +@end diff --git a/clang/test/SemaObjC/ivar-ref-misuse.m b/clang/test/SemaObjC/ivar-ref-misuse.m new file mode 100644 index 0000000..3115f5b --- /dev/null +++ b/clang/test/SemaObjC/ivar-ref-misuse.m @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface Sprite { // expected-note{{'Sprite' declared here}} + int sprite, spree; + int UseGlobalBar; +} ++ (void)setFoo:(int)foo; ++ (void)setSprite:(int)sprite; +- (void)setFoo:(int)foo; +- (void)setSprite:(int)sprite; +@end + +int spree = 23; +int UseGlobalBar; + +@implementation Sprite ++ (void)setFoo:(int)foo { + sprite = foo; // expected-error {{instance variable 'sprite' accessed in class method}} + spree = foo; + Xsprite = foo; // expected-error {{unknown type name 'Xsprite'; did you mean 'Sprite'?}} \ + // expected-error{{expected identifier or '('}} + UseGlobalBar = 10; +} ++ (void)setSprite:(int)sprite { + int spree; + sprite = 15; + spree = 17; + ((Sprite *)self)->sprite = 16; /* NB: This is how one _should_ access */ + ((Sprite *)self)->spree = 18; /* ivars from within class methods! */ +} +- (void)setFoo:(int)foo { + sprite = foo; + spree = foo; +} +- (void)setSprite:(int)sprite { + int spree; + sprite = 15; // expected-warning {{local declaration of 'sprite' hides instance variable}} + self->sprite = 16; + spree = 17; // expected-warning {{local declaration of 'spree' hides instance variable}} + self->spree = 18; +} +@end diff --git a/clang/test/SemaObjC/ivar-sem-check-1.m b/clang/test/SemaObjC/ivar-sem-check-1.m new file mode 100644 index 0000000..de038f5 --- /dev/null +++ b/clang/test/SemaObjC/ivar-sem-check-1.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct S; // expected-note{{forward declaration of 'struct S'}} +typedef int FOO(); + +@interface INTF +{ + struct F {} JJ; + int arr[]; // expected-error {{field has incomplete type}} + struct S IC; // expected-error {{field has incomplete type}} + struct T { // expected-note {{previous definition is here}} + struct T {} X; // expected-error {{nested redefinition of 'T'}} + }YYY; + FOO BADFUNC; // expected-error {{field 'BADFUNC' declared as a function}} + int kaka; // expected-note {{previous declaration is here}} + int kaka; // expected-error {{duplicate member 'kaka'}} + char ch[]; // expected-error {{field has incomplete type}} +} +@end diff --git a/clang/test/SemaObjC/ivar-sem-check-2.m b/clang/test/SemaObjC/ivar-sem-check-2.m new file mode 100644 index 0000000..bf884b3 --- /dev/null +++ b/clang/test/SemaObjC/ivar-sem-check-2.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface Super { + id value2; // expected-note {{previously declared 'value2' here}} +} +@property(retain) id value; +@property(retain) id value1; +@property(retain) id prop; +@end + +@interface Sub : Super +{ + id value; +} +@end + +@implementation Sub +@synthesize value; // expected-note {{previous use is here}} +@synthesize value1=value; // expected-error {{synthesized properties 'value1' and 'value' both claim ivar 'value'}} +@synthesize prop=value2; // expected-error {{property 'prop' attempting to use ivar 'value2' declared in super class 'Super'}} +@end + + diff --git a/clang/test/SemaObjC/legacy-implementation-1.m b/clang/test/SemaObjC/legacy-implementation-1.m new file mode 100644 index 0000000..2e4c5ae --- /dev/null +++ b/clang/test/SemaObjC/legacy-implementation-1.m @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@implementation INTF // expected-warning {{cannot find interface declaration for 'INTF'}} +@end + +INTF* pi; + +INTF* FUNC() +{ + return pi; +} diff --git a/clang/test/SemaObjC/message.m b/clang/test/SemaObjC/message.m new file mode 100644 index 0000000..621a18f --- /dev/null +++ b/clang/test/SemaObjC/message.m @@ -0,0 +1,100 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +typedef struct objc_object { + Class isa; +} *id; + + +@interface foo +- (void)meth; +@end + +@implementation foo +- (void) contents {} // No declaration in @interface! +- (void) meth { [self contents]; } +@end + +typedef struct _NSPoint { + float x; + float y; +} NSPoint; + +typedef struct _NSSize { + float width; + float height; +} NSSize; + +typedef struct _NSRect { + NSPoint origin; + NSSize size; +} NSRect; + +@interface AnyClass +- (NSRect)rect; +@end + +@class Helicopter; + +static void func(Helicopter *obj) { + // Note that the proto for "rect" is found in the global pool even when + // a statically typed object's class interface isn't in scope! This + // behavior isn't very desirable, however wee need it for GCC compatibility. + NSRect r = [obj rect]; +} + +@interface NSObject @end + +extern Class NSClassFromObject(id object); + +@interface XX : NSObject +@end + +@implementation XX + ++ _privateMethod { + return self; +} + +- (void) xx { + [NSClassFromObject(self) _privateMethod]; +} +@end + +@implementation XX (Private) +- (void) yy { + [NSClassFromObject(self) _privateMethod]; +} +@end + +@interface I0 +-(void) nonVararg: (int) x; +@end + +int f0(I0 *ob) { + [ ob nonVararg: 0, 1, 2]; // expected-error {{too many arguments to method call}} +} + +int f2() { + const id foo; + [foo bar]; // expected-warning {{method '-bar' not found (return type defaults to 'id')}} + return 0; +} + + +// PR3766 +struct S { int X; } S; + +int test5(int X) { + int a = [X somemsg]; // expected-warning {{receiver type 'int' is not 'id'}} \ + expected-warning {{method '-somemsg' not found}} \ + expected-warning {{incompatible pointer to integer conversion initializing 'int' with an expression of type 'id'}} + int b = [S somemsg]; // expected-error {{bad receiver type 'struct S'}} +} + +// PR4021 +void foo4() { + struct objc_object X[10]; + + [X rect]; // expected-warning {{receiver type 'struct objc_object *' is not 'id' or interface pointer, consider casting it to 'id'}} expected-warning {{method '-rect' not found (return type defaults to 'id')}} +} + diff --git a/clang/test/SemaObjC/method-arg-qualifier-warning.m b/clang/test/SemaObjC/method-arg-qualifier-warning.m new file mode 100644 index 0000000..690509e --- /dev/null +++ b/clang/test/SemaObjC/method-arg-qualifier-warning.m @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef signed char BOOL; + +@interface NSString +- (BOOL)isEqualToString:(NSString *)aString; // expected-note 2{{passing argument to parameter 'aString' here}} +@end + +static const NSString * Identifier1 = @"Identifier1"; +static NSString const * Identifier2 = @"Identifier2"; +static NSString * const Identifier3 = @"Identifier3"; + +int main () { + + [@"Identifier1" isEqualToString:Identifier1]; // expected-warning {{sending 'const NSString *' to parameter of type 'NSString *' discards qualifiers}} + [@"Identifier2" isEqualToString:Identifier2]; // expected-warning {{sending 'const NSString *' to parameter of type 'NSString *' discards qualifiers}} + [@"Identifier3" isEqualToString:Identifier3]; + return 0; +} + diff --git a/clang/test/SemaObjC/method-attributes.m b/clang/test/SemaObjC/method-attributes.m new file mode 100644 index 0000000..f7252af --- /dev/null +++ b/clang/test/SemaObjC/method-attributes.m @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -Wno-objc-root-class %s + +@class NSString; + +@interface A +-t1 __attribute__((noreturn)); +- (NSString *)stringByAppendingFormat:(NSString *)format, ... __attribute__((format(__NSString__, 1, 2))); +-(void) m0 __attribute__((noreturn)); +-(void) m1 __attribute__((unused)); +@end + + +@interface INTF +- (int) foo1: (int)arg1 __attribute__((deprecated)); + +- (int) foo: (int)arg1; // expected-note {{method 'foo:' declared here}} + +- (int) foo2: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)); // expected-note {{method 'foo2:' declared here}} +- (int) foo3: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)) __attribute__((ns_consumes_self)); +@end + +@implementation INTF +- (int) foo: (int)arg1 __attribute__((deprecated)){ // expected-warning {{attributes on method implementation and its declaration must match}} + return 10; +} +- (int) foo1: (int)arg1 { + return 10; +} +- (int) foo2: (int)arg1 __attribute__((deprecated)) { // expected-warning {{attributes on method implementation and its declaration must match}} + return 10; +} +- (int) foo3: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)) __attribute__((ns_consumes_self)) {return 0; } +- (void) dep __attribute__((deprecated)) { } // OK private methodn +@end + + +// rdar://10529259 +#define IBAction void)__attribute__((ibaction) + +@interface Foo +- (void)doSomething1:(id)sender; +- (void)doSomething2:(id)sender; // expected-note {{method 'doSomething2:' declared here}} +@end + +@implementation Foo +- (void)doSomething1:(id)sender{} +- (void)doSomething2:(id)sender{} +@end + +@interface Bar : Foo +- (IBAction)doSomething1:(id)sender; +@end +@implementation Bar +- (IBAction)doSomething1:(id)sender {} +- (IBAction)doSomething2:(id)sender {} // expected-warning {{attributes on method implementation and its declaration must match}} +- (IBAction)doSomething3:(id)sender {} +@end diff --git a/clang/test/SemaObjC/method-bad-param.m b/clang/test/SemaObjC/method-bad-param.m new file mode 100644 index 0000000..9505cb4 --- /dev/null +++ b/clang/test/SemaObjC/method-bad-param.m @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface foo +@end + +@implementation foo +@end + +@interface bar +-(void) my_method:(foo) my_param; // expected-error {{interface type 'foo' cannot be passed by value; did you forget * in 'foo'}} +- (foo)cccccc:(long)ddddd; // expected-error {{interface type 'foo' cannot be returned by value; did you forget * in 'foo'}} +@end + +@implementation bar +-(void) my_method:(foo) my_param // expected-error {{interface type 'foo' cannot be passed by value; did you forget * in 'foo'}} +{ +} +- (foo)cccccc:(long)ddddd // expected-error {{interface type 'foo' cannot be returned by value; did you forget * in 'foo'}} +{ +} +@end + +void somefunc(foo x) {} // expected-error {{interface type 'foo' cannot be passed by value; did you forget * in 'foo'}} +foo somefunc2() {} // expected-error {{interface type 'foo' cannot be returned by value; did you forget * in 'foo'}} + +// rdar://6780761 +void f0(foo *a0) { + extern void g0(int x, ...); + g0(1, *(foo*)a0); // expected-error {{cannot pass object with interface type 'foo' by-value through variadic function}} +} + +// rdar://8421082 +enum bogus; // expected-note {{forward declaration of 'enum bogus'}} + +@interface fee { +} +- (void)crashMe:(enum bogus)p; +@end + +@implementation fee +- (void)crashMe:(enum bogus)p { // expected-error {{variable has incomplete type 'enum bogus'}} +} +@end + diff --git a/clang/test/SemaObjC/method-conflict-1.m b/clang/test/SemaObjC/method-conflict-1.m new file mode 100644 index 0000000..ca91ebd --- /dev/null +++ b/clang/test/SemaObjC/method-conflict-1.m @@ -0,0 +1,83 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +// This test case tests the default behavior. + +// rdar://7933061 + +@interface NSObject @end + +@interface NSArray : NSObject @end + +@interface MyClass : NSObject { +} +- (void)myMethod:(NSArray *)object; +- (void)myMethod1:(NSObject *)object; // broken-note {{previous definition is here}} +@end + +@implementation MyClass +- (void)myMethod:(NSObject *)object { +} +- (void)myMethod1:(NSArray *)object { // broken-warning {{conflicting parameter types in implementation of 'myMethod1:': 'NSObject *' vs 'NSArray *'}} +} +@end + + +@protocol MyProtocol @end + +@interface MyOtherClass : NSObject <MyProtocol> { +} +- (void)myMethod:(id <MyProtocol>)object; // broken-note {{previous definition is here}} +- (void)myMethod1:(id <MyProtocol>)object; // broken-note {{previous definition is here}} +@end + +@implementation MyOtherClass +- (void)myMethod:(MyClass *)object { // broken-warning {{conflicting parameter types in implementation of 'myMethod:': 'id<MyProtocol>' vs 'MyClass *'}} +} +- (void)myMethod1:(MyClass<MyProtocol> *)object { // broken-warning {{conflicting parameter types in implementation of 'myMethod1:': 'id<MyProtocol>' vs 'MyClass<MyProtocol> *'}} +} +@end + + + +@interface A @end +@interface B : A @end + +@interface Test1 {} +- (void) test1:(A*) object; // broken-note {{previous definition is here}} +- (void) test2:(B*) object; +@end + +@implementation Test1 +- (void) test1:(B*) object {} // broken-warning {{conflicting parameter types in implementation of 'test1:': 'A *' vs 'B *'}} +- (void) test2:(A*) object {} +@end + +// rdar://problem/8597621 wants id -> A* to be an exception +@interface Test2 {} +- (void) test1:(id) object; // broken-note {{previous definition is here}} +- (void) test2:(A*) object; +@end +@implementation Test2 +- (void) test1:(A*) object {} // broken-warning {{conflicting parameter types in implementation of 'test1:': 'id' vs 'A *'}} +- (void) test2:(id) object {} +@end + +@interface Test3 {} +- (A*) test1; +- (B*) test2; // broken-note {{previous definition is here}} +@end + +@implementation Test3 +- (B*) test1 { return 0; } +- (A*) test2 { return 0; } // broken-warning {{conflicting return type in implementation of 'test2': 'B *' vs 'A *'}} +@end + +// The particular case of overriding with an id return is white-listed. +@interface Test4 {} +- (id) test1; +- (A*) test2; +@end +@implementation Test4 +- (A*) test1 { return 0; } // id -> A* is rdar://problem/8596987 +- (id) test2 { return 0; } +@end diff --git a/clang/test/SemaObjC/method-conflict-2.m b/clang/test/SemaObjC/method-conflict-2.m new file mode 100644 index 0000000..df59f24 --- /dev/null +++ b/clang/test/SemaObjC/method-conflict-2.m @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -Wmethod-signatures -fsyntax-only -verify -Wno-objc-root-class %s + +@interface A @end +@interface B : A @end + +@interface Test1 {} +- (void) test1:(A*) object; // expected-note {{previous definition is here}} +- (void) test2:(B*) object; +@end + +@implementation Test1 +- (void) test1:(B*) object {} // expected-warning {{conflicting parameter types in implementation of 'test1:': 'A *' vs 'B *'}} +- (void) test2:(A*) object {} +@end + +@interface Test2 {} +- (void) test1:(id) object; // expected-note {{previous definition is here}} +- (void) test2:(A*) object; +@end + +@implementation Test2 +- (void) test1:(A*) object {} // expected-warning {{conflicting parameter types in implementation of 'test1:': 'id' vs 'A *'}} +- (void) test2:(id) object {} +@end + +@interface Test3 {} +- (A*) test1; +- (B*) test2; // expected-note {{previous definition is here}} +@end + +@implementation Test3 +- (B*) test1 { return 0; } +- (A*) test2 { return 0; } // expected-warning {{conflicting return type in implementation of 'test2': 'B *' vs 'A *'}} +@end + +// The particular case of overriding with an id return is white-listed. +@interface Test4 {} +- (id) test1; +- (A*) test2; +@end +@implementation Test4 +- (A*) test1 { return 0; } // id -> A* is rdar://problem/8596987 +- (id) test2 { return 0; } +@end diff --git a/clang/test/SemaObjC/method-conflict.m b/clang/test/SemaObjC/method-conflict.m new file mode 100644 index 0000000..2da629e --- /dev/null +++ b/clang/test/SemaObjC/method-conflict.m @@ -0,0 +1,66 @@ +// RUN: %clang_cc1 -Wmethod-signatures -fsyntax-only -verify -Wno-objc-root-class %s + +typedef signed char BOOL; +typedef unsigned int NSUInteger; +typedef struct _NSZone NSZone; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; +@protocol NSObject - (BOOL)isEqual:(id)object; +@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; +@end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; +@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; +@end @interface NSObject <NSObject> { +} +@end extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); +@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value; +@end @class NSString; +typedef struct _NSRange { +} + NSRange; +@interface NSValue (NSValueRangeExtensions) + (NSValue *)valueWithRange:(NSRange)range; +@end @interface NSAttributedString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSString *)string; +@end @interface NSMutableAttributedString : NSAttributedString - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str; +@end @class NSArray, NSDictionary, NSString, NSError; +@interface NSScanner : NSObject <NSCopying> - (NSString *)string; +@end typedef struct { +} + CSSM_FIELDGROUP, *CSSM_FIELDGROUP_PTR; +@protocol XDUMLClassifier; +@protocol XDUMLClassInterfaceCommons <XDUMLClassifier> +@end @protocol XDUMLImplementation; +@protocol XDUMLElement <NSObject> - (NSArray *) ownedElements; +@end @protocol XDUMLDataType; +@protocol XDUMLNamedElement <XDUMLElement> - (NSString *) name; +@end enum _XDSourceLanguage { +XDSourceUnknown=0, XDSourceJava, XDSourceC, XDSourceCPP, XDSourceObjectiveC }; +typedef NSUInteger XDSourceLanguage; +@protocol XDSCClassifier <XDUMLClassInterfaceCommons> - (XDSourceLanguage)language; +@end @class XDSCDocController; +@interface XDSCDisplaySpecification : NSObject <NSCoding>{ +} +@end @class XDSCOperation; +@interface XDSCClassFormatter : NSObject { +} ++ (NSUInteger) compartmentsForClassifier: (id <XDUMLClassifier>) classifier withSpecification: (XDSCDisplaySpecification *) displaySpec; // expected-note {{previous definition is here}} +@end +@class NSString; +@implementation XDSCClassFormatter + ++ appendVisibility: (id <XDUMLNamedElement>) element withSpecification: (XDSCDisplaySpecification *) displaySpec to: (NSMutableAttributedString *) attributedString +{ + return 0; +} ++ (NSUInteger) compartmentsForClassifier: (id <XDSCClassifier>) classifier withSpecification: (XDSCDisplaySpecification *) displaySpec { // expected-warning {{conflicting parameter types in implementation of 'compartmentsForClassifier:withSpecification:'}} + return 0; +} +@end + +// rdar: // 8006060 +@interface Bar +- (void)foo:(id)format, ...; // expected-note {{previous declaration is here}} +- (void)foo1:(id)format; // expected-note {{previous declaration is here}} +@end +@implementation Bar +- (void)foo:(id)format {}; // expected-warning {{conflicting variadic declaration of method and its implementation}} +- (void)foo1:(id)format, ... {}; // expected-warning {{conflicting variadic declaration of method and its implementation}} +@end + diff --git a/clang/test/SemaObjC/method-def-1.m b/clang/test/SemaObjC/method-def-1.m new file mode 100644 index 0000000..7b292fb --- /dev/null +++ b/clang/test/SemaObjC/method-def-1.m @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -Wmethod-signatures -fsyntax-only -verify -Wno-objc-root-class %s + +@interface foo +- (int)meth; +@end + +@implementation foo +- (int) meth { return [self meth]; } +@end + +// PR2708 +@interface MyClass ++- (void)myMethod; // expected-error {{expected selector for Objective-C method}} +- (vid)myMethod2; // expected-error {{expected a type}} +@end + +@implementation MyClass +- (void)myMethod { } +- (vid)myMethod2 { } // expected-error {{expected a type}} + +@end + + +@protocol proto; +@protocol NSObject; + +//@protocol GrowlPluginHandler <NSObject> @end + + +@interface SomeClass2 +- (int)myMethod1: (id<proto>) +arg; // expected-note {{previous definition is here}} +@end + +@implementation SomeClass2 +- (int)myMethod1: (id<NSObject>) + arg { // expected-warning {{conflicting parameter types in implementation of 'myMethod1:': 'id<proto>' vs 'id<NSObject>'}} + +} +@end diff --git a/clang/test/SemaObjC/method-def-2.m b/clang/test/SemaObjC/method-def-2.m new file mode 100644 index 0000000..915f231 --- /dev/null +++ b/clang/test/SemaObjC/method-def-2.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -ast-print %s +extern void abort(void); +#define CHECK_IF(expr) if(!(expr)) abort() + +static double d = 4.5920234e2; + +@interface Foo +-(void) brokenType: (int)x floatingPoint: (double)y; +@end + + +@implementation Foo +-(void) brokenType: (int)x floatingPoint: (double)y +{ + CHECK_IF(x == 459); + CHECK_IF(y == d); +} +@end + diff --git a/clang/test/SemaObjC/method-encoding-2.m b/clang/test/SemaObjC/method-encoding-2.m new file mode 100644 index 0000000..619a886 --- /dev/null +++ b/clang/test/SemaObjC/method-encoding-2.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s +// TODO: We don't support rewrite of method definitions + +@interface Intf +- (in out bycopy id) address:(byref inout void *)location with:(out oneway unsigned **)arg2; +- (id) another:(void *)location with:(unsigned **)arg2; +@end + +@implementation Intf +- (in out bycopy id) address:(byref inout void *)location with:(out oneway unsigned **)arg2{ return 0; } +- (id) another:(void *)location with:(unsigned **)arg2 { return 0; } +@end diff --git a/clang/test/SemaObjC/method-in-class-extension-impl.m b/clang/test/SemaObjC/method-in-class-extension-impl.m new file mode 100644 index 0000000..c205322 --- /dev/null +++ b/clang/test/SemaObjC/method-in-class-extension-impl.m @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://8530080 + +@protocol ViewDelegate @end + +@interface NSTextView +- (id <ViewDelegate>)delegate; +@end + +@interface FooTextView : NSTextView +@end + +@interface FooTextView() +- (id)delegate; +@end + +@implementation FooTextView +- (id)delegate {return 0; } +@end + diff --git a/clang/test/SemaObjC/method-lookup-2.m b/clang/test/SemaObjC/method-lookup-2.m new file mode 100644 index 0000000..53cae83 --- /dev/null +++ b/clang/test/SemaObjC/method-lookup-2.m @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +typedef signed char BOOL; + +@protocol NSObject ++ alloc; +- init; +- (BOOL) isEqual:(id) object; +- (Class)class; +@end + +@interface NSObject < NSObject > {} @end + +@class NSString, NSPort; + +@interface NSPortNameServer:NSObject ++ (NSPortNameServer *) systemDefaultPortNameServer; +@end + +@interface NSMachBootstrapServer:NSPortNameServer + (id) sharedInstance; @end + +enum { + NSWindowsNTOperatingSystem = 1, NSWindows95OperatingSystem, NSSolarisOperatingSystem, NSHPUXOperatingSystem, NSMACHOperatingSystem, NSSunOSOperatingSystem, NSOSF1OperatingSystem +}; + +@interface NSRunLoop:NSObject {} @end + +@interface NSRunLoop(NSRunLoopConveniences) +- (void) run; +@end + +extern NSString *const NSWillBecomeMultiThreadedNotification; + +@interface SenTestTool:NSObject {} +@end + +@implementation SenTestTool ++ (void) initialize {} ++(SenTestTool *) sharedInstance { return 0; } +-(int) run { return 0; } ++(int) run { + return[[self sharedInstance] run]; +} +@end + +@interface XX : NSObject + ++ classMethod; + +@end + +@interface YY : NSObject +- whatever; +@end + +@implementation YY + +- whatever { + id obj = [[XX alloc] init]; + [[obj class] classMethod]; + return 0; +} + +@end diff --git a/clang/test/SemaObjC/method-lookup-3.m b/clang/test/SemaObjC/method-lookup-3.m new file mode 100644 index 0000000..b3d9c46 --- /dev/null +++ b/clang/test/SemaObjC/method-lookup-3.m @@ -0,0 +1,73 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef struct { int y; } Abstract; + +typedef struct { int x; } Alternate; + +#define INTERFERE_TYPE Alternate* + +@protocol A +@property Abstract *x; // expected-note {{using}} +@end + +@interface B +@property Abstract *y; // expected-note {{using}} +@end + +@interface B (Category) +@property Abstract *z; // expected-note {{using}} +@end + +@interface InterferencePre +-(void) x; // expected-note {{also found}} +-(void) y; // expected-note {{also found}} +-(void) z; // expected-note {{also found}} +-(void) setX: (INTERFERE_TYPE) arg; +-(void) setY: (INTERFERE_TYPE) arg; +-(void) setZ: (INTERFERE_TYPE) arg; +@end + +void f0(id a0) { + Abstract *l = [a0 x]; // expected-warning {{multiple methods named 'x' found}} +} + +void f1(id a0) { + Abstract *l = [a0 y]; // expected-warning {{multiple methods named 'y' found}} +} + +void f2(id a0) { + Abstract *l = [a0 z]; // expected-warning {{multiple methods named 'z' found}} +} + +void f3(id a0, Abstract *a1) { + [ a0 setX: a1]; +} + +void f4(id a0, Abstract *a1) { + [ a0 setY: a1]; +} + +void f5(id a0, Abstract *a1) { + [ a0 setZ: a1]; +} + +// pr7861 +void f6(id<A> a0) { + Abstract *l = [a0 x]; +} + +struct test3a { int x, y; }; +struct test3b { unsigned x, y; }; +@interface Test3A - (struct test3a) test3; @end +@interface Test3B - (struct test3b) test3; @end +void test3(id x) { + (void) [x test3]; +} + +struct test4a { int x, y; }; +struct test4b { float x, y; }; +@interface Test4A - (struct test4a) test4; @end //expected-note{{using}} +@interface Test4B - (struct test4b) test4; @end //expected-note{{also found}} +void test4(id x) { + (void) [x test4]; //expected-warning {{multiple methods named 'test4' found}} +} diff --git a/clang/test/SemaObjC/method-lookup-4.m b/clang/test/SemaObjC/method-lookup-4.m new file mode 100644 index 0000000..700565e --- /dev/null +++ b/clang/test/SemaObjC/method-lookup-4.m @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface NSObject {} + +@end + +@interface MyClass : NSObject {} + +@end + +@interface MyClass (MyCategorie) + +@end + +@interface MySubClass : MyClass {} + +@end + +@interface MySubSubClass : MySubClass {} + +@end + +@implementation NSObject (NSObjectCategory) +- (void)rootMethod {} +@end + +@implementation MyClass + ++ (void)myClassMethod { } +- (void)myMethod { } + +@end + +@implementation MyClass (MyCategorie) ++ (void)myClassCategoryMethod { } +- (void)categoryMethod {} +@end + +@implementation MySubClass + +- (void)mySubMethod {} + +- (void)myTest { + [self mySubMethod]; + // should lookup method in superclass implementation if available + [self myMethod]; + [super myMethod]; + + [self categoryMethod]; + [super categoryMethod]; + + // instance method of root class + [MyClass rootMethod]; + + [MyClass myClassMethod]; + [MySubClass myClassMethod]; + + [MyClass myClassCategoryMethod]; + [MySubClass myClassCategoryMethod]; +} + +@end diff --git a/clang/test/SemaObjC/method-lookup-5.m b/clang/test/SemaObjC/method-lookup-5.m new file mode 100644 index 0000000..13df218 --- /dev/null +++ b/clang/test/SemaObjC/method-lookup-5.m @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://8592156 + +typedef struct objc_class *Class; +@interface A +-(Class) foo; +@end + +void f0(A *a) { int x = [[a foo] baz]; } // expected-warning {{method '+baz' not found (return type defaults to 'id')}} \ + // expected-warning {{ncompatible pointer to integer conversion initializing 'int' with an expression of type 'id'}} diff --git a/clang/test/SemaObjC/method-lookup.m b/clang/test/SemaObjC/method-lookup.m new file mode 100644 index 0000000..13e2d7f --- /dev/null +++ b/clang/test/SemaObjC/method-lookup.m @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +typedef signed char BOOL; +typedef int NSInteger; + +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (BOOL)respondsToSelector:(SEL)s; +@end + +@interface NSObject <NSObject> {} +@end + +@class NSString, NSData, NSMutableData, NSMutableDictionary, NSMutableArray; + +@protocol PBXCompletionItem +- (NSString *) name; +- (NSInteger)priority; +- setPriority:(NSInteger)p; +@end + +@implementation PBXCodeAssistant // expected-warning{{cannot find interface declaration for 'PBXCodeAssistant'}} +static NSMutableArray * recentCompletions = ((void *)0); ++ (float) factorForRecentCompletion:(NSString *) completion +{ + for (NSObject<PBXCompletionItem> * item in [self completionItems]) // expected-warning{{method '+completionItems' not found (return type defaults to 'id')}} + { + if ([item respondsToSelector:@selector(setPriority:)]) + { + [(id)item setPriority:[item priority] / [PBXCodeAssistant factorForRecentCompletion:[item name]]]; + } + } + return 0; +} +@end + diff --git a/clang/test/SemaObjC/method-no-context.m b/clang/test/SemaObjC/method-no-context.m new file mode 100644 index 0000000..c087549 --- /dev/null +++ b/clang/test/SemaObjC/method-no-context.m @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +- im0 { // expected-error{{missing context for method declaration}} + int a; return 0; diff --git a/clang/test/SemaObjC/method-not-defined.m b/clang/test/SemaObjC/method-not-defined.m new file mode 100644 index 0000000..22466f7 --- /dev/null +++ b/clang/test/SemaObjC/method-not-defined.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface Foo +@end + +void test() { + Foo *fooObj; + id obj; + + [[Foo alloc] init]; // expected-warning {{class method '+alloc' not found (return type defaults to 'id')}} expected-warning {{instance method '-init' not found (return type defaults to 'id')}} + [fooObj notdefined]; // expected-warning {{instance method '-notdefined' not found (return type defaults to 'id')}} + [obj whatever:1 :2 :3]; // expected-warning {{instance method '-whatever:::' not found (return type defaults to 'id')}} +} diff --git a/clang/test/SemaObjC/method-prototype-scope.m b/clang/test/SemaObjC/method-prototype-scope.m new file mode 100644 index 0000000..0bebd9b --- /dev/null +++ b/clang/test/SemaObjC/method-prototype-scope.m @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -fsyntax-only -Wduplicate-method-arg -verify -Wno-objc-root-class %s + +// rdar://8877730 + +int object; + +@class NSString, NSArray; + +@interface Test +- Func:(int)XXXX, id object; + +- doSomethingElseWith:(id)object; + +- (NSString *)doSomethingWith:(NSString *)object and:(NSArray *)object; // expected-warning {{redeclaration of method parameter 'object'}} \ + // expected-note {{previous declaration is here}} +@end + +@implementation Test + +- (NSString *)doSomethingWith:(NSString *)object and:(NSArray *)object // expected-warning {{redefinition of method parameter 'object'}} \ + // expected-note {{previous declaration is here}} +{ + return object; // expected-warning {{incompatible pointer types returning 'NSArray *' from a function with result type 'NSString *'}} +} + +- Func:(int)XXXX, id object { return object; } + +- doSomethingElseWith:(id)object { return object; } + +@end + +struct P; + +@interface Test1 +- doSomethingWith:(struct S *)object and:(struct P *)obj; // expected-warning {{declaration of 'struct S' will not be visible outside of this function}} +@end + +int obj; diff --git a/clang/test/SemaObjC/method-sentinel-attr.m b/clang/test/SemaObjC/method-sentinel-attr.m new file mode 100644 index 0000000..274e936 --- /dev/null +++ b/clang/test/SemaObjC/method-sentinel-attr.m @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#define NULL (void*)0 + +#define ATTR __attribute__ ((__sentinel__)) + +@interface INTF +- (void) foo1 : (int)x, ... ATTR; // expected-note {{method has been explicitly marked sentinel here}} +- (void) foo3 : (int)x __attribute__ ((__sentinel__)) ; // expected-warning {{'sentinel' attribute only supported for variadic functions}} +- (void) foo5 : (int)x, ... __attribute__ ((__sentinel__(1))); // expected-note {{method has been explicitly marked sentinel here}} +- (void) foo6 : (int)x, ... __attribute__ ((__sentinel__(5))); // expected-note {{method has been explicitly marked sentinel here}} +- (void) foo7 : (int)x, ... __attribute__ ((__sentinel__(0))); // expected-note {{method has been explicitly marked sentinel here}} +- (void) foo8 : (int)x, ... __attribute__ ((__sentinel__("a"))); // expected-error {{'sentinel' attribute requires parameter 1 to be an integer constant}} +- (void) foo9 : (int)x, ... __attribute__ ((__sentinel__(-1))); // expected-error {{'sentinel' parameter 1 less than zero}} +- (void) foo10 : (int)x, ... __attribute__ ((__sentinel__(1,1))); +- (void) foo11 : (int)x, ... __attribute__ ((__sentinel__(1,1,3))); // expected-error {{attribute takes no more than 2 arguments}} +- (void) foo12 : (int)x, ... ATTR; // expected-note {{method has been explicitly marked sentinel here}} + +// rdar://7975788 +- (id) foo13 : (id)firstObj, ... __attribute__((sentinel(0,1))); +- (id) foo14 : (id)firstObj : (Class)secondObj, ... __attribute__((sentinel(0,1))); +- (id) foo15 : (id*)firstObj, ... __attribute__((sentinel(0,1))); +- (id) foo16 : (id**)firstObj, ... __attribute__((sentinel(0,1))); +@end + +int main () +{ + INTF *p; + + [p foo1:1, NULL]; // OK + [p foo1:1, 0]; // expected-warning {{missing sentinel in method dispatch}} + [p foo5:1, NULL, 2]; // OK + [p foo5:1, 2, NULL, 1]; // OK + [p foo5:1, NULL, 2, 1]; // expected-warning {{missing sentinel in method dispatch}} + + [p foo6:1,2,3,4,5,6,7]; // expected-warning {{missing sentinel in method dispatch}} + [p foo6:1,NULL,3,4,5,6,7]; // OK + [p foo7:1]; // expected-warning {{not enough variable arguments in 'foo7:' declaration to fit a sentinel}} + [p foo7:1, NULL]; // ok + + [p foo12:1]; // expected-warning {{not enough variable arguments in 'foo12:' declaration to fit a sentinel}} + + // rdar://7975788 + [ p foo13 : NULL]; + [ p foo14 : 0 : NULL]; + [ p foo16 : NULL]; + [ p foo15 : NULL]; +} + diff --git a/clang/test/SemaObjC/method-typecheck-1.m b/clang/test/SemaObjC/method-typecheck-1.m new file mode 100644 index 0000000..ee068d0 --- /dev/null +++ b/clang/test/SemaObjC/method-typecheck-1.m @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface A +- (void) setMoo: (int) x; // expected-note {{previous definition is here}} +- (int) setMoo1: (int) x; // expected-note {{previous definition is here}} +- (int) setOk : (int) x : (double) d; +@end + +@implementation A +-(void) setMoo: (float) x {} // expected-warning {{conflicting parameter types in implementation of 'setMoo:': 'int' vs 'float'}} +- (char) setMoo1: (int) x { return 0; } // expected-warning {{conflicting return type in implementation of 'setMoo1:': 'int' vs 'char'}} +- (int) setOk : (int) x : (double) d { return 0; } +@end + + + +@interface C ++ (void) cMoo: (int) x; // expected-note 2 {{previous definition is here}} +@end + +@implementation C ++(float) cMoo: // expected-warning {{conflicting return type in implementation of 'cMoo:': 'void' vs 'float'}} + (float) x { return 0; } // expected-warning {{conflicting parameter types in implementation of 'cMoo:': 'int' vs 'float'}} +@end + + +@interface A(CAT) +- (void) setCat: (int) x; // expected-note 2 {{previous definition is here}} ++ (void) cCat: (int) x; // expected-note {{previous definition is here}} +@end + +@implementation A(CAT) +-(float) setCat: // expected-warning {{conflicting return type in implementation of 'setCat:': 'void' vs 'float'}} +(float) x { return 0; } // expected-warning {{conflicting parameter types in implementation of 'setCat:': 'int' vs 'float'}} ++ (int) cCat: (int) x { return 0; } // expected-warning {{conflicting return type in implementation of 'cCat:': 'void' vs 'int'}} +@end diff --git a/clang/test/SemaObjC/method-typecheck-2.m b/clang/test/SemaObjC/method-typecheck-2.m new file mode 100644 index 0000000..84efa0b --- /dev/null +++ b/clang/test/SemaObjC/method-typecheck-2.m @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@protocol P +- (void) doSomethingInProtocol: (float) x; // expected-note {{previous definition is here}} ++ (void) doSomethingClassyInProtocol: (float) x; // expected-note {{previous definition is here}} +- (void) doNothingInProtocol : (float) x; ++ (void) doNothingClassyInProtocol : (float) x; +@end + +@interface I <P> +- (void) doSomething: (float) x; // expected-note {{previous definition is here}} ++ (void) doSomethingClassy: (int) x; // expected-note {{previous definition is here}} +@end + +@interface Bar : I +@end + +@implementation Bar +- (void) doSomething: (int) x {} // expected-warning {{conflicting parameter types}} ++ (void) doSomethingClassy: (float) x{} // expected-warning {{conflicting parameter types}} +- (void) doSomethingInProtocol: (id) x {} // expected-warning {{conflicting parameter types}} ++ (void) doSomethingClassyInProtocol: (id) x {} // expected-warning {{conflicting parameter types}} +@end + + diff --git a/clang/test/SemaObjC/method-typecheck-3.m b/clang/test/SemaObjC/method-typecheck-3.m new file mode 100644 index 0000000..1999b7d --- /dev/null +++ b/clang/test/SemaObjC/method-typecheck-3.m @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -Wmethod-signatures -fsyntax-only -verify %s + +@class B; +@interface A +- (B*)obj; +- (B*)a; // expected-note {{previous definition is here}} +- (void)takesA: (A*)a; // expected-note {{previous definition is here}} +- (void)takesId: (id)a; // expected-note {{previous definition is here}} +@end + + +@interface B : A +@end + +@implementation B +- (id)obj {return self;} // 'id' overrides are white-listed? +- (A*)a { return self;} // expected-warning {{conflicting return type in implementation of 'a'}} +- (void)takesA: (B*)a // expected-warning {{conflicting parameter types in implementation of 'takesA:'}} +{} +- (void)takesId: (B*)a // expected-warning {{conflicting parameter types in implementation of 'takesId:'}} +{} +@end diff --git a/clang/test/SemaObjC/method-undef-category-warn-1.m b/clang/test/SemaObjC/method-undef-category-warn-1.m new file mode 100644 index 0000000..2548cbd --- /dev/null +++ b/clang/test/SemaObjC/method-undef-category-warn-1.m @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface MyClass1 +@end + +@protocol P +- (void) Pmeth; // expected-note {{method 'Pmeth' declared here}} +- (void) Pmeth1; // expected-note {{method 'Pmeth1' declared here}} +@end + +@interface MyClass1(CAT) <P> // expected-note {{required for direct or indirect protocol 'P'}} +- (void) meth2; // expected-note {{method definition for 'meth2' not found}} +@end + +@implementation MyClass1(CAT) // expected-warning {{incomplete implementation}} \ + // expected-warning {{method 'Pmeth' in protocol not implemented}} +- (void) Pmeth1{} +@end + +@interface MyClass1(DOG) <P> // expected-note {{required for direct or indirect protocol 'P'}} +- (void)ppp; // expected-note {{method definition for 'ppp' not found}} +@end + +@implementation MyClass1(DOG) // expected-warning {{incomplete implementation}} \ + // expected-warning {{method 'Pmeth1' in protocol not implemented}} +- (void) Pmeth {} +@end + +@implementation MyClass1(CAT1) +@end + +// rdar://10823023 +@class NSString; + +@protocol NSObject +- (NSString *)meth_inprotocol; +@end + +@interface NSObject <NSObject> +- (NSString *)description; ++ (NSString *) cls_description; +@end + +@protocol Foo +- (NSString *)description; ++ (NSString *) cls_description; +@end + +@interface NSObject (FooConformance) <Foo> +@end + +@implementation NSObject (FooConformance) +@end + +// rdar://11186449 +// Don't warn when a category does not implemented a method imported +// by its protocol because another category has its declaration and +// that category will implement it. +@interface NSOrderedSet @end + +@interface NSOrderedSet(CoolectionImplements) +- (unsigned char)containsObject:(id)object; +@end + +@protocol Collection +- (unsigned char)containsObject:(id)object; +@end + +@interface NSOrderedSet (CollectionConformance) <Collection> +@end + +@implementation NSOrderedSet (CollectionConformance) +@end + diff --git a/clang/test/SemaObjC/method-undef-extension-warn-1.m b/clang/test/SemaObjC/method-undef-extension-warn-1.m new file mode 100644 index 0000000..c092f24 --- /dev/null +++ b/clang/test/SemaObjC/method-undef-extension-warn-1.m @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface MyClass // expected-note {{required for direct or indirect protocol 'P'}} +@end + +@protocol P +- (void)Pmeth; +- (void)Pmeth1; // expected-note {{method 'Pmeth1' declared here}} +@end + +// Class extension +@interface MyClass () <P> +- (void)meth2; // expected-note {{method definition for 'meth2' not found}} +@end + +// Add a category to test that clang does not emit warning for this method. +@interface MyClass (Category) +- (void)categoryMethod; +@end + +@implementation MyClass // expected-warning {{incomplete implementation}} \ + // expected-warning {{method 'Pmeth1' in protocol not implemented}} +- (void)Pmeth {} +@end diff --git a/clang/test/SemaObjC/method-undefined-warn-1.m b/clang/test/SemaObjC/method-undefined-warn-1.m new file mode 100644 index 0000000..27d645e --- /dev/null +++ b/clang/test/SemaObjC/method-undefined-warn-1.m @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface INTF +- (void) meth; +- (void) meth : (int) arg1; +- (int) int_meth; // expected-note {{method definition for 'int_meth' not found}} ++ (int) cls_meth; // expected-note {{method definition for 'cls_meth' not found}} ++ (void) cls_meth1 : (int) arg1; // expected-note {{method definition for 'cls_meth1:' not found}} +@end + +@implementation INTF // expected-warning {{incomplete implementation}} +- (void) meth {} +- (void) meth : (int) arg2{} +- (void) cls_meth1 : (int) arg2{} +@end + +@interface INTF1 +- (void) meth; +- (void) meth : (int) arg1; +- (int) int_meth; // expected-note {{method definition for 'int_meth' not found}} ++ (int) cls_meth; // expected-note {{method definition for 'cls_meth' not found}} ++ (void) cls_meth1 : (int) arg1; // expected-note {{method definition for 'cls_meth1:' not found}} +@end + +@implementation INTF1 // expected-warning {{incomplete implementation}} +- (void) meth {} +- (void) meth : (int) arg2{} +- (void) cls_meth1 : (int) arg2{} +@end + +@interface INTF2 +- (void) meth; +- (void) meth : (int) arg1; +- (void) cls_meth1 : (int) arg1; +@end + +@implementation INTF2 +- (void) meth {} +- (void) meth : (int) arg2{} +- (void) cls_meth1 : (int) arg2{} +@end + + +// rdar://8850818 +@interface Root @end + +@interface Foo : Root @end + +@implementation Foo + +- (void)someFunction { return; } + ++ (void)anotherFunction { + [self someFunction]; // expected-warning {{method '+someFunction' not found (return type defaults to 'id')}} +} +@end diff --git a/clang/test/SemaObjC/method-unused-attribute.m b/clang/test/SemaObjC/method-unused-attribute.m new file mode 100644 index 0000000..d604c39 --- /dev/null +++ b/clang/test/SemaObjC/method-unused-attribute.m @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -Wunused-parameter -verify -Wno-objc-root-class %s + +@interface INTF +- (void) correct_use_of_unused: (void *) notice : (id)another_arg; +- (void) will_warn_unused_arg: (void *) notice : (id)warn_unused; +- (void) unused_attr_on_decl_ignored: (void *) __attribute__((unused)) will_warn; +@end + +@implementation INTF +- (void) correct_use_of_unused: (void *) __attribute__((unused)) notice : (id) __attribute__((unused)) newarg{ +} +- (void) will_warn_unused_arg: (void *) __attribute__((unused)) notice : (id)warn_unused {} // expected-warning {{unused parameter 'warn_unused'}} +- (void) unused_attr_on_decl_ignored: (void *) will_warn{} // expected-warning {{unused parameter 'will_warn'}} +@end + diff --git a/clang/test/SemaObjC/method-warn-unused-attribute.m b/clang/test/SemaObjC/method-warn-unused-attribute.m new file mode 100644 index 0000000..042f442 --- /dev/null +++ b/clang/test/SemaObjC/method-warn-unused-attribute.m @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -Wunused-value -verify %s + +@interface INTF +- (id) foo __attribute__((warn_unused_result)); +- (void) garf __attribute__((warn_unused_result)); // expected-warning {{attribute 'warn_unused_result' cannot be applied to Objective-C method without return value}} +- (int) fee __attribute__((warn_unused_result)); ++ (int) c __attribute__((warn_unused_result)); +@end + +void foo(INTF *a) { + [a garf]; + [a fee]; // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}} + [INTF c]; // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}} +} + + diff --git a/clang/test/SemaObjC/missing-atend-metadata.m b/clang/test/SemaObjC/missing-atend-metadata.m new file mode 100644 index 0000000..f072981 --- /dev/null +++ b/clang/test/SemaObjC/missing-atend-metadata.m @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface I0 +@end + +@implementation I0 // expected-note {{implementation started here}} +- meth { return 0; } + +@interface I1 : I0 // expected-error {{missing '@end'}} +@end + +@implementation I1 // expected-note {{implementation started here}} +-(void) im0 { self = [super init]; } // expected-warning {{not found}} + +@interface I2 : I0 // expected-error {{missing '@end'}} +- I2meth; +@end + +@implementation I2 // expected-note {{implementation started here}} +- I2meth { return 0; } + +@implementation I2(CAT) // expected-error 2 {{missing '@end'}} expected-note {{implementation started here}} diff --git a/clang/test/SemaObjC/missing-method-context.m b/clang/test/SemaObjC/missing-method-context.m new file mode 100644 index 0000000..1378b36 --- /dev/null +++ b/clang/test/SemaObjC/missing-method-context.m @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only +- (void)compilerTestAgainst; // expected-error {{missing context for method declaration}} + +void xx(); // expected-error {{expected method body}} diff --git a/clang/test/SemaObjC/missing-method-return-type.m b/clang/test/SemaObjC/missing-method-return-type.m new file mode 100644 index 0000000..fc6ff7b --- /dev/null +++ b/clang/test/SemaObjC/missing-method-return-type.m @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -Wmissing-method-return-type -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://9615045 + +@interface I +- initWithFoo:(id)foo; // expected-warning {{method has no return type specified; defaults to 'id'}} +@end + +@implementation I +- initWithFoo:(id)foo { return 0; } // expected-warning {{method has no return type specified; defaults to 'id'}} +@end + diff --git a/clang/test/SemaObjC/narrow-property-type-in-cont-class.m b/clang/test/SemaObjC/narrow-property-type-in-cont-class.m new file mode 100644 index 0000000..3ba848f --- /dev/null +++ b/clang/test/SemaObjC/narrow-property-type-in-cont-class.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -x objective-c -fsyntax-only -verify %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify %s +// rdar://10790488 + +@interface NSArray @end + +@interface NSMutableArray : NSArray +@end + +@interface GKTurnBasedMatchMakerKVO +@property(nonatomic,readonly,retain) NSArray* outline; +@property(nonatomic,readonly,retain) NSMutableArray* err_outline; // expected-note {{property declared here}} +@end + +@interface GKTurnBasedMatchMakerKVO () +@property(nonatomic,readwrite,retain) NSMutableArray* outline; +@property(nonatomic,readwrite,retain) NSArray* err_outline; // expected-error {{type of property 'NSArray *' in continuation class does not match property type in primary class}} +@end + diff --git a/clang/test/SemaObjC/nested-typedef-decl.m b/clang/test/SemaObjC/nested-typedef-decl.m new file mode 100644 index 0000000..bb01ead --- /dev/null +++ b/clang/test/SemaObjC/nested-typedef-decl.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -x objective-c -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://10041908 + +@interface Bar { + struct _A *_hardlinkList; +} +@end +@implementation Bar +typedef struct _A { + int dev; + int inode; +} A; + +- (void) idx:(int)idx ino:(int)ino dev:(int)dev +{ + _hardlinkList[idx].inode = ino; + _hardlinkList[idx].dev = dev; +} +@end + diff --git a/clang/test/SemaObjC/newproperty-class-method-1.m b/clang/test/SemaObjC/newproperty-class-method-1.m new file mode 100644 index 0000000..0f32998 --- /dev/null +++ b/clang/test/SemaObjC/newproperty-class-method-1.m @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -Wno-objc-root-class %s + +void abort(void); + +@interface Subclass ++ (int)magicNumber; ++ (void)setMagicNumber:(int)value; ++ (void)setFakeSetterNumber:(int)value; +@end + +@implementation Subclass +int _magicNumber = 0; ++ (int)magicNumber { + return _magicNumber; +} + ++ (void)setMagicNumber:(int)value { + _magicNumber = value; +} + ++ (void)setFakeSetterNumber:(int)value { + _magicNumber = value; +} + ++ (void) classMeth +{ + self.magicNumber = 10; + if (self.magicNumber != 10) + abort (); +} +@end + +int main (void) { + + int a; + Subclass.magicNumber = 2 /*[Subclass setMagicNumber:2]*/; + if (Subclass.magicNumber != 0) + abort (); + if (Subclass.magicNumber != 2) + abort (); + Subclass.magicNumber += 3; + if (Subclass.magicNumber != 5) + abort (); + Subclass.magicNumber -= 5; + if (Subclass.magicNumber != 0) + abort (); + /* We only have a setter in the following case. */ + Subclass.fakeSetterNumber = 123; + + /* We read it using the other getter. */ + if (Subclass.magicNumber != 123) + abort (); + Subclass.fakeSetterNumber = Subclass.magicNumber; + if (Subclass.magicNumber != 123) + abort (); + + Subclass.fakeSetterNumberX = 123; // expected-error{{property 'fakeSetterNumberX' not found on object of type 'Subclass'}} + + /* Test class methods using the new syntax. */ + [Subclass classMeth]; + return 0; +} diff --git a/clang/test/SemaObjC/no-gc-weak-test.m b/clang/test/SemaObjC/no-gc-weak-test.m new file mode 100644 index 0000000..dd9b73c --- /dev/null +++ b/clang/test/SemaObjC/no-gc-weak-test.m @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface Subtask +{ + id _delegate; +} +@property(nonatomic,readwrite,assign) id __weak delegate; +@end + +@implementation Subtask +@synthesize delegate = _delegate; +@end + + +@interface PVSelectionOverlayView2 +{ + id __weak _selectionRect; +} + +@property(assign) id selectionRect; + +@end + +@implementation PVSelectionOverlayView2 + +@synthesize selectionRect = _selectionRect; +@end + diff --git a/clang/test/SemaObjC/no-ivar-access-control.m b/clang/test/SemaObjC/no-ivar-access-control.m new file mode 100644 index 0000000..6f00b1a --- /dev/null +++ b/clang/test/SemaObjC/no-ivar-access-control.m @@ -0,0 +1,70 @@ +// RUN: %clang_cc1 -fsyntax-only -fdebugger-support -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -fdebugger-support -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://10997647 + +@interface I +{ +@private +int ivar; +} +@end + +@implementation I +- (int) meth { + return self->ivar; +} +int foo1(I* p) { + return p->ivar; +} +@end + +int foo(I* p) { + return p->ivar; +} + +@interface B +@end + +@implementation B +- (int) meth : (I*) arg { + return arg->ivar; +} +@end + + +@interface I1 { + int protected_ivar; +} +@property int PROP_INMAIN; +@end + +@interface I1() { + int private_ivar; +} +@property int PROP_INCLASSEXT; +@end + +@implementation I1 +@synthesize PROP_INMAIN, PROP_INCLASSEXT; + +- (int) Meth { + PROP_INMAIN = 1; + PROP_INCLASSEXT = 2; + protected_ivar = 1; // OK + return private_ivar; // OK +} +@end + + +@interface DER : I1 +@end + +@implementation DER +- (int) Meth { + protected_ivar = 1; // OK + PROP_INMAIN = 1; + PROP_INCLASSEXT = 2; + return private_ivar; +} +@end + diff --git a/clang/test/SemaObjC/no-objc-exceptions.m b/clang/test/SemaObjC/no-objc-exceptions.m new file mode 100644 index 0000000..d47f51a --- /dev/null +++ b/clang/test/SemaObjC/no-objc-exceptions.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void f() { + @throw @"Hello"; // expected-error {{cannot use '@throw' with Objective-C exceptions disabled}} +} + +void g() { + @try { // expected-error {{cannot use '@try' with Objective-C exceptions disabled}} + f(); + } @finally { + + } +} diff --git a/clang/test/SemaObjC/no-protocol-option-tests.m b/clang/test/SemaObjC/no-protocol-option-tests.m new file mode 100644 index 0000000..dbd2a14 --- /dev/null +++ b/clang/test/SemaObjC/no-protocol-option-tests.m @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -fsyntax-only -Wno-protocol -verify -Wno-objc-root-class %s +// rdar: // 7056600 + +@protocol P +- PMeth; +@end + +// Test1 +@interface I <P> @end +@implementation I @end // no warning with -Wno-protocol + +// Test2 +@interface C -PMeth; @end +@interface C (Category) <P> @end +@implementation C (Category) @end // no warning with -Wno-protocol + +// Test2 +@interface super - PMeth; @end +@interface J : super <P> +- PMeth; // expected-note {{method definition for 'PMeth' not found}} +@end +@implementation J @end // expected-warning {{incomplete implementation}} + +// Test3 +@interface K : super <P> +@end +@implementation K @end // no warning with -Wno-protocol + +// Test4 +@interface Root @end +@interface L : Root<P> @end +@implementation L @end // no warning with -Wno-protocol diff --git a/clang/test/SemaObjC/no-warn-qual-mismatch.m b/clang/test/SemaObjC/no-warn-qual-mismatch.m new file mode 100644 index 0000000..1e3c186 --- /dev/null +++ b/clang/test/SemaObjC/no-warn-qual-mismatch.m @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// radar 7211563 + +@interface X + ++ (void)prototypeWithScalar:(int)aParameter; ++ (void)prototypeWithPointer:(void *)aParameter; + +@end + +@implementation X + ++ (void)prototypeWithScalar:(const int)aParameter {} ++ (void)prototypeWithPointer:(void * const)aParameter {} + +@end diff --git a/clang/test/SemaObjC/no-warn-synth-protocol-meth.m b/clang/test/SemaObjC/no-warn-synth-protocol-meth.m new file mode 100644 index 0000000..103f6bb --- /dev/null +++ b/clang/test/SemaObjC/no-warn-synth-protocol-meth.m @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@protocol CYCdef +- (int)name; +@end + +@interface JSCdef <CYCdef> { + int name; +} + +@property (assign) int name; +@end + +@implementation JSCdef +@synthesize name; +@end + diff --git a/clang/test/SemaObjC/no-warn-unimpl-method.m b/clang/test/SemaObjC/no-warn-unimpl-method.m new file mode 100644 index 0000000..dd6e3ad --- /dev/null +++ b/clang/test/SemaObjC/no-warn-unimpl-method.m @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify %s +// This program tests that if class implements the forwardInvocation method, then +// every method possible is implemented in the class and should not issue +// warning of the "Method definition not found" kind. */ + +@interface NSObject +@end + +@interface NSInvocation +@end + +@interface NSProxy +@end + +@protocol MyProtocol + -(void) doSomething; +@end + +@interface DestinationClass : NSObject<MyProtocol> + -(void) doSomething; +@end + +@implementation DestinationClass + -(void) doSomething + { + } +@end + +@interface MyProxy : NSProxy<MyProtocol> +{ + DestinationClass *mTarget; +} + - (id) init; + - (void)forwardInvocation:(NSInvocation *)anInvocation; +@end + +@implementation MyProxy + - (void)forwardInvocation:(NSInvocation *)anInvocation + { + } + - (id) init { return 0; } +@end diff --git a/clang/test/SemaObjC/no-warning-unavail-unimp.m b/clang/test/SemaObjC/no-warning-unavail-unimp.m new file mode 100644 index 0000000..88d519d --- /dev/null +++ b/clang/test/SemaObjC/no-warning-unavail-unimp.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://9651605 + +@interface Foo +@property (getter=getVal) int val __attribute__((unavailable)); +- Method __attribute__((unavailable)); ++ CMethod __attribute__((unavailable)); +@end + +@implementation Foo +@end + diff --git a/clang/test/SemaObjC/nonnull.h b/clang/test/SemaObjC/nonnull.h new file mode 100644 index 0000000..f5a038f --- /dev/null +++ b/clang/test/SemaObjC/nonnull.h @@ -0,0 +1,2 @@ +// rdar: //6857843 +#define NONNULL_ATTR __attribute__((nonnull)) diff --git a/clang/test/SemaObjC/nonnull.m b/clang/test/SemaObjC/nonnull.m new file mode 100644 index 0000000..a38c0ac --- /dev/null +++ b/clang/test/SemaObjC/nonnull.m @@ -0,0 +1,96 @@ +#include "nonnull.h" + +// RUN: %clang_cc1 -fblocks -fsyntax-only -verify -Wno-objc-root-class %s + +@class NSObject; + +NONNULL_ATTR +int f1(int x); // no warning +int f2(int *x) __attribute__ ((nonnull (1))); +int f3(int *x) __attribute__ ((nonnull (0))); // expected-error {{'nonnull' attribute parameter 1 is out of bounds}} +int f4(int *x, int *y) __attribute__ ((nonnull (1,2))); +int f5(int *x, int *y) __attribute__ ((nonnull (2,1))); +int f6(NSObject *x) __attribute__ ((nonnull (1))); // no-warning +int f7(NSObject *x) __attribute__ ((nonnull)); // no-warning + + +extern void func1 (void (^block1)(), void (^block2)(), int) __attribute__((nonnull)); + +extern void func3 (void (^block1)(), int, void (^block2)(), int) +__attribute__((nonnull(1,3))); + +extern void func4 (void (^block1)(), void (^block2)()) __attribute__((nonnull(1))) +__attribute__((nonnull(2))); + +void func6(); +void func7(); + +void +foo (int i1, int i2, int i3, void (^cp1)(), void (^cp2)(), void (^cp3)()) +{ + func1(cp1, cp2, i1); + + func1(0, cp2, i1); // expected-warning {{null passed to a callee which requires a non-null argument}} + func1(cp1, 0, i1); // expected-warning {{null passed to a callee which requires a non-null argument}} + func1(cp1, cp2, 0); + + + func3(0, i2, cp3, i3); // expected-warning {{null passed to a callee which requires a non-null argument}} + func3(cp3, i2, 0, i3); // expected-warning {{null passed to a callee which requires a non-null argument}} + + func4(0, cp1); // expected-warning {{null passed to a callee which requires a non-null argument}} + func4(cp1, 0); // expected-warning {{null passed to a callee which requires a non-null argument}} + + // Shouldn't these emit warnings? Clang doesn't, and neither does GCC. It + // seems that the checking should handle Objective-C pointers. + func6((NSObject*) 0); // no-warning + func7((NSObject*) 0); // no-warning +} + +void func5(int) NONNULL_ATTR; // no warning + +// rdar://6857843 +struct dispatch_object_s { + int x; +}; + +typedef union { + long first; + struct dispatch_object_s *_do; +} dispatch_object_t __attribute__((transparent_union)); + +__attribute__((nonnull)) +void _dispatch_queue_push_list(dispatch_object_t _head); // no warning + +void func6(dispatch_object_t _head) { + _dispatch_queue_push_list(0); // expected-warning {{null passed to a callee which requires a non-null argument}} + _dispatch_queue_push_list(_head._do); // no warning +} + +// rdar://9287695 +#define NULL (void*)0 + +@interface NSObject +- (void)doSomethingWithNonNullPointer:(void *)ptr :(int)iarg : (void*)ptr1 __attribute__((nonnull(1, 3))); ++ (void)doSomethingClassyWithNonNullPointer:(void *)ptr __attribute__((nonnull(1))); +@end + +extern void DoSomethingNotNull(void *db) __attribute__((nonnull(1))); + +@interface IMP +{ + void * vp; +} +@end + +@implementation IMP +- (void) Meth { + NSObject *object; + [object doSomethingWithNonNullPointer:NULL:1:NULL]; // expected-warning 2 {{null passed to a callee which requires a non-null argument}} + [object doSomethingWithNonNullPointer:vp:1:NULL]; // expected-warning {{null passed to a callee which requires a non-null argument}} + [NSObject doSomethingClassyWithNonNullPointer:NULL]; // expected-warning {{null passed to a callee which requires a non-null argument}} + DoSomethingNotNull(NULL); // expected-warning {{null passed to a callee which requires a non-null argument}} + [object doSomethingWithNonNullPointer:vp:1:vp]; +} +@end + diff --git a/clang/test/SemaObjC/nsobject-attribute-1.m b/clang/test/SemaObjC/nsobject-attribute-1.m new file mode 100644 index 0000000..72d8fa6 --- /dev/null +++ b/clang/test/SemaObjC/nsobject-attribute-1.m @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -fblocks -fsyntax-only -verify -Wno-objc-root-class %s + +@interface NSObject +- (id)self; +- (id)copy; +@end + +typedef struct _foo *__attribute__((NSObject)) Foo_ref; + +@interface TestObject { + Foo_ref dict; +} +@property(retain) Foo_ref dict; +@end + +@implementation TestObject +@synthesize dict; +@end + +@interface NSDictionary +- (int)retainCount; +@end + +int main(int argc, char *argv[]) { + NSDictionary *dictRef; + Foo_ref foo = (Foo_ref)dictRef; + + // do Properties retain? + int before = [dictRef retainCount]; + int after = [dictRef retainCount]; + + if ([foo retainCount] != [dictRef retainCount]) { + } + + // do Blocks retain? + { + void (^block)(void) = ^{ + [foo self]; + }; + before = [foo retainCount]; + id save = [block copy]; + after = [foo retainCount]; + if (after <= before) { + ; + } + } + return 0; +} diff --git a/clang/test/SemaObjC/nsobject-attribute.m b/clang/test/SemaObjC/nsobject-attribute.m new file mode 100644 index 0000000..f41df89 --- /dev/null +++ b/clang/test/SemaObjC/nsobject-attribute.m @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +typedef struct CGColor * __attribute__ ((NSObject)) CGColorRef; +static int count; +static CGColorRef tmp = 0; + +typedef struct S1 __attribute__ ((NSObject)) CGColorRef1; // expected-error {{__attribute ((NSObject)) is for pointer types only}} +typedef void * __attribute__ ((NSObject)) CGColorRef2; // expected-error {{__attribute ((NSObject)) is for pointer types only}} + + +@interface HandTested { +@public + CGColorRef x; +} + +@property(copy) CGColorRef x; +// rdar: // 7809460 +typedef struct CGColor * __attribute__((NSObject)) CGColorRefNoNSObject; +@property (nonatomic, retain) CGColorRefNoNSObject color; +@end + +void setProperty(id self, id value) { + ((HandTested *)self)->x = value; +} + +id getProperty(id self) { + return (id)((HandTested *)self)->x; +} + +@implementation HandTested +@synthesize x=x; +@dynamic color; +@end + +int main(int argc, char *argv[]) { + HandTested *to; + to.x = tmp; // setter + if (tmp != to.x) + to.x = tmp; + return 0; +} + +// rdar://10453342 +@interface I +{ + __attribute__((NSObject)) void * color; // expected-warning {{__attribute ((NSObject)) may be put on a typedef only, attribute is ignored}} +} + // <rdar://problem/10930507> +@property (nonatomic, retain) __attribute__((NSObject)) void * color; // // no-warning +@end +void test_10453342() { + char* __attribute__((NSObject)) string2 = 0; // expected-warning {{__attribute ((NSObject)) may be put on a typedef only, attribute is ignored}} +} + diff --git a/clang/test/SemaObjC/objc-array-literal.m b/clang/test/SemaObjC/objc-array-literal.m new file mode 100644 index 0000000..9f59316 --- /dev/null +++ b/clang/test/SemaObjC/objc-array-literal.m @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://10111397 + +#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 +typedef unsigned long NSUInteger; +#else +typedef unsigned int NSUInteger; +#endif + +@class NSString; + +extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); + +@class NSFastEnumerationState; + +@protocol NSFastEnumeration + +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id [])buffer count:(NSUInteger)len; + +@end + +@interface NSNumber ++ (NSNumber *)numberWithInt:(int)value; +@end + +@interface NSArray <NSFastEnumeration> ++ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt; +@end + + +int main() { + NSArray *array = @[@"Hello", @"There", @"How Are You", [NSNumber numberWithInt:42]]; + + for (id string in array) + NSLog(@"%@\n", string); + + NSArray *array1 = @["Forgot"]; // expected-error {{string literal must be prefixed by '@' in a collection}} + + const char *blah; + NSArray *array2 = @[blah]; // expected-error{{collection element of type 'const char *' is not an Objective-C object}} +} diff --git a/clang/test/SemaObjC/objc-buffered-methods.m b/clang/test/SemaObjC/objc-buffered-methods.m new file mode 100644 index 0000000..a4b83be --- /dev/null +++ b/clang/test/SemaObjC/objc-buffered-methods.m @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://8843851 + +int* global; + +@interface I +- (void) Meth; +@property int prop; +@property int prop1; +@end + +@implementation I ++ (void) _defaultMinSize { }; +static void _initCommon() { + Class graphicClass; + [graphicClass _defaultMinSize]; +} + +- (void) Meth { [self Forw]; } // No warning now +- (void) Forw {} +- (int) func { return prop; } // compiles - synthesized ivar will be accessible here. +- (int)get_g { return global; } // No warning here - synthesized ivar will be accessible here. +@synthesize prop; +@synthesize prop1=global; +@end diff --git a/clang/test/SemaObjC/objc-container-subscripting-1.m b/clang/test/SemaObjC/objc-container-subscripting-1.m new file mode 100644 index 0000000..a58a7c3 --- /dev/null +++ b/clang/test/SemaObjC/objc-container-subscripting-1.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef unsigned int size_t; +@protocol P @end + +@interface NSMutableArray +@end + +@interface XNSMutableArray +@end + +int main() { +id array; +id oldObject = array[10]; // expected-warning {{instance method '-objectAtIndexedSubscript:' not found (return type defaults to 'id')}} + +array[10] = 0; // expected-warning {{instance method '-setObject:atIndexedSubscript:' not found (return type defaults to 'id')}} + +id<P> p_array; +oldObject = p_array[10]; // expected-warning {{instance method '-objectAtIndexedSubscript:' not found (return type defaults to 'id')}} + +p_array[10] = 0; // expected-warning {{instance method '-setObject:atIndexedSubscript:' not found (return type defaults to 'id')}} +} + diff --git a/clang/test/SemaObjC/objc-container-subscripting-2.m b/clang/test/SemaObjC/objc-container-subscripting-2.m new file mode 100644 index 0000000..3c0081b --- /dev/null +++ b/clang/test/SemaObjC/objc-container-subscripting-2.m @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef unsigned int size_t; +@protocol P @end + +@interface NSMutableArray +- (id)objectAtIndexedSubscript:(size_t)index; +- (void)setObject:(id)object atIndexedSubscript:(size_t)index; +@end + +@interface NSMutableDictionary +- (id)objectForKeyedSubscript:(id)key; +- (void)setObject:(id)object forKeyedSubscript:(size_t)key; +@end + +id func() { + NSMutableArray *array; + float f; + array[f] = array; // expected-error {{indexing expression is invalid because subscript type 'float' is not an integral or objective-C pointer type}} + return array[3.14]; // expected-error {{indexing expression is invalid because subscript type 'double' is not an integral or objective-C pointer type}} +} + +void test_unused() { + NSMutableArray *array; + array[10]; // expected-warning {{container access result unused - container access should not be used for side effects}} + + NSMutableDictionary *dict; + dict[array]; // expected-warning {{container access result unused - container access should not be used for side effects}} +} + diff --git a/clang/test/SemaObjC/objc-container-subscripting-3.m b/clang/test/SemaObjC/objc-container-subscripting-3.m new file mode 100644 index 0000000..5fd1a10 --- /dev/null +++ b/clang/test/SemaObjC/objc-container-subscripting-3.m @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://10904488 + +@interface Test +- (int)objectAtIndexedSubscript:(int)index; // expected-note {{method 'objectAtIndexedSubscript:' declared here}} +- (void)setObject:(int)object atIndexedSubscript:(int)index; // expected-note {{parameter of type 'int' is declared here}} +@end + +@interface NSMutableDictionary +- (int)objectForKeyedSubscript:(id)key; // expected-note {{method 'objectForKeyedSubscript:' declared here}} +- (void)setObject:(int)object forKeyedSubscript:(id)key; // expected-note {{parameter of type 'int' is declared here}} +@end + +int main() { + Test *array; + int i = array[10]; // expected-error {{method for accessing array element must have Objective-C object return type instead of 'int'}} + array[2] = i; // expected-error {{cannot assign to this array because assigning method's 2nd parameter of type 'int' is not an objective-C pointer type}} + + NSMutableDictionary *dict; + id key, val; + val = dict[key]; // expected-error {{method for accessing dictionary element must have Objective-C object return type instead of 'int'}} \ + // expected-warning {{incompatible integer to pointer conversion assigning to 'id' from 'int'}} + dict[key] = val; // expected-error {{method object parameter type 'int' is not object type}} +} + diff --git a/clang/test/SemaObjC/objc-container-subscripting.m b/clang/test/SemaObjC/objc-container-subscripting.m new file mode 100644 index 0000000..4125bc6 --- /dev/null +++ b/clang/test/SemaObjC/objc-container-subscripting.m @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef unsigned int size_t; +@protocol P @end + +@interface NSMutableArray +- (id)objectAtIndexedSubscript:(double)index; // expected-note {{parameter of type 'double' is declared here}} +- (void)setObject:(id *)object atIndexedSubscript:(void *)index; // expected-note {{parameter of type 'void *' is declared here}} \ + // expected-note {{parameter of type 'id *' is declared here}} +@end +@interface I @end + +int main() { + NSMutableArray<P> * array; + id oldObject = array[10]; // expected-error {{method index parameter type 'double' is not integral type}} + array[3] = 0; // expected-error {{method index parameter type 'void *' is not integral type}} \ + // expected-error {{cannot assign to this array because assigning method's 2nd parameter of type 'id *' is not an objective-C pointer type}} + + I* iarray; + iarray[3] = 0; // expected-error {{expected method to write array element not found on object of type 'I *'}} + I* p = iarray[4]; // expected-error {{expected method to read array element not found on object of type 'I *'}} + + oldObject = array[10]++; // expected-error {{illegal operation on objective-c container subscripting}} + oldObject = array[10]--; // expected-error {{illegal operation on objective-c container subscripting}} + oldObject = --array[10]; // expected-error {{illegal operation on objective-c container subscripting}} +} + +@interface NSMutableDictionary +- (id)objectForKeyedSubscript:(id*)key; // expected-note {{parameter of type 'id *' is declared here}} +- (void)setObject:(void*)object forKeyedSubscript:(id*)key; // expected-note {{parameter of type 'void *' is declared here}} \ + // expected-note {{parameter of type 'id *' is declared here}} +@end +@class NSString; + +void testDict() { + NSMutableDictionary *dictionary; + NSString *key; + id newObject, oldObject; + oldObject = dictionary[key]; // expected-error {{method key parameter type 'id *' is not object type}} + dictionary[key] = newObject; // expected-error {{method object parameter type 'void *' is not object type}} \ + // expected-error {{method key parameter type 'id *' is not object type}} +} diff --git a/clang/test/SemaObjC/objc-cstyle-args-in-methods.m b/clang/test/SemaObjC/objc-cstyle-args-in-methods.m new file mode 100644 index 0000000..d37b589 --- /dev/null +++ b/clang/test/SemaObjC/objc-cstyle-args-in-methods.m @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface Foo +- (id)test:(id)one, id two; +- (id)bad:(id)one, id two, double three; +@end + +@implementation Foo +- (id)test:(id )one, id two {return two; } +- (id)bad:(id)one, id two, double three { return two; } +@end + + +int main() { + Foo *foo; + [foo test:@"One", @"Two"]; + [foo bad:@"One", @"Two"]; // expected-error {{too few arguments to method call}} + [foo bad:@"One", @"Two", 3.14]; + [foo bad:@"One", @"Two", 3.14, @"Two"]; // expected-error {{too many arguments to method call}} +} diff --git a/clang/test/SemaObjC/objc-dictionary-literal.m b/clang/test/SemaObjC/objc-dictionary-literal.m new file mode 100644 index 0000000..2acbc39 --- /dev/null +++ b/clang/test/SemaObjC/objc-dictionary-literal.m @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://11062080 + +@interface NSNumber ++ (NSNumber *)numberWithChar:(char)value; ++ (NSNumber *)numberWithInt:(int)value; +@end + +@protocol NSCopying @end +typedef unsigned long NSUInteger; +typedef long NSInteger; + +@interface NSDictionary ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt; +- (void)setObject:(id)object forKeyedSubscript:(id)key; +@end + +@interface NSString<NSCopying> +@end + +@interface NSArray +- (id)objectAtIndexedSubscript:(NSInteger)index; +- (void)setObject:(id)object atIndexedSubscript:(NSInteger)index; +@end + +int main() { + NSDictionary *dict = @{ @"name":@666 }; + dict[@"name"] = @666; + + dict["name"] = @666; // expected-error {{indexing expression is invalid because subscript type 'char *' is not an objective-C pointer}} + + return 0; +} + diff --git a/clang/test/SemaObjC/objc-literal-nsnumber.m b/clang/test/SemaObjC/objc-literal-nsnumber.m new file mode 100644 index 0000000..6635bea --- /dev/null +++ b/clang/test/SemaObjC/objc-literal-nsnumber.m @@ -0,0 +1,85 @@ +// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s +// rdar://10111397 + +#if __LP64__ +typedef unsigned long NSUInteger; +#else +typedef unsigned int NSUInteger; +#endif + +@interface NSObject ++ (NSObject*)nsobject; +@end + +@interface NSNumber : NSObject ++ (NSNumber *)numberWithChar:(char)value; ++ (NSNumber *)numberWithInt:(int)value; ++ (NSNumber *)numberWithFloat:(float)value; +@end + +int main() { + NSNumber * N = @3.1415926535; // expected-error {{declaration of 'numberWithDouble:' is missing in NSNumber class}} + NSNumber *noNumber = @__objc_yes; // expected-error {{declaration of 'numberWithBool:' is missing in NSNumber class}} + NSNumber * NInt = @1000; + NSNumber * NLongDouble = @1000.0l; // expected-error{{'long double' is not a valid literal type for NSNumber}} + id character = @ 'a'; + + NSNumber *NNegativeInt = @-1000; + NSNumber *NPositiveInt = @+1000; + NSNumber *NNegativeFloat = @-1000.1f; + NSNumber *NPositiveFloat = @+1000.1f; + + int five = 5; + @-five; // expected-error{{@- must be followed by a number to form an NSNumber object}} + @+five; // expected-error{{@+ must be followed by a number to form an NSNumber object}} +} + +// Dictionary test +@class NSDictionary; + +NSDictionary *err() { + return @{@"name" : @"value"}; // expected-error {{declaration of 'dictionaryWithObjects:forKeys:count:' is missing in NSDictionary class}} +} + +@interface NSDate : NSObject ++ (NSDate *) date; +@end + +@protocol NSCopying +- copy; +@end + +@interface NSDictionary : NSObject ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(NSUInteger)cnt; +@end + +@interface NSString<NSCopying> +@end + +id NSUserName(); + +int Int(); + +NSDictionary * blocks() { + return @{ @"task" : ^ { return 17; } }; +} + +NSDictionary * warn() { + NSDictionary *dictionary = @{@"name" : NSUserName(), + @"date" : [NSDate date], + @"name2" : @"other", + NSObject.nsobject : @"nsobject" }; // expected-warning{{passing 'NSObject *' to parameter of incompatible type 'const id<NSCopying>'}} + NSDictionary *dictionary2 = @{@"name" : Int()}; // expected-error {{collection element of type 'int' is not an Objective-C object}} + + NSObject *o; + NSDictionary *dictionary3 = @{o : o, // expected-warning{{passing 'NSObject *' to parameter of incompatible type 'const id<NSCopying>'}} + @"date" : [NSDate date] }; + return dictionary3; +} + +// rdar:// 11231426 +typedef float BOOL; + +BOOL radar11231426() { + return __objc_yes; +} diff --git a/clang/test/SemaObjC/objc-literal-sig.m b/clang/test/SemaObjC/objc-literal-sig.m new file mode 100644 index 0000000..fb5c79f --- /dev/null +++ b/clang/test/SemaObjC/objc-literal-sig.m @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +typedef _Bool BOOL; + +@interface NSNumber @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; ++ (int)numberWithBool:(BOOL)value; // expected-note{{method returns unexpected type 'int' (should be an object type)}} +@end + +@interface NSArray +@end + +@interface NSArray (NSArrayCreation) ++ (id)arrayWithObjects:(const int [])objects // expected-note{{first parameter has unexpected type 'const int *' (should be 'const id *')}} + count:(unsigned long)cnt; +@end + +@interface NSDictionary ++ (id)dictionaryWithObjects:(const id [])objects + forKeys:(const int [])keys // expected-note{{second parameter has unexpected type 'const int *' (should be 'const id *')}} + count:(unsigned long)cnt; +@end + +void test_sig() { + (void)@__objc_yes; // expected-error{{literal construction method 'numberWithBool:' has incompatible signature}} + id array = @[ @17 ]; // expected-error{{literal construction method 'arrayWithObjects:count:' has incompatible signature}} + id dict = @{ @"hello" : @17 }; // expected-error{{literal construction method 'dictionaryWithObjects:forKeys:count:' has incompatible signature}} +} diff --git a/clang/test/SemaObjC/objc-qualified-property-lookup.m b/clang/test/SemaObjC/objc-qualified-property-lookup.m new file mode 100644 index 0000000..48b28cb --- /dev/null +++ b/clang/test/SemaObjC/objc-qualified-property-lookup.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://9078584 + +@interface NSObject @end + +@protocol TextInput +-editRange; +@end + +@interface I { + NSObject<TextInput>* editor; +} +- (id) Meth; +@end + +@implementation I +- (id) Meth { + return editor.editRange; +} +@end + diff --git a/clang/test/SemaObjC/objc-string-constant.m b/clang/test/SemaObjC/objc-string-constant.m new file mode 100644 index 0000000..cc6d60c --- /dev/null +++ b/clang/test/SemaObjC/objc-string-constant.m @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -Wsemicolon-before-method-body %s -verify -fsyntax-only + +#define nil 0 /* id of Nil instance */ + +@interface NSObject +@end + +@interface NSString : NSObject + +@end + +@interface NSMutableString : NSString + +@end + +@interface NSSimpleCString : NSString { +@protected + char *bytes; + int numBytes; +} +@end + +@interface NSConstantString : NSSimpleCString +@end + + +@interface Subclass : NSObject +- (NSString *)token; +@end + +@implementation Subclass +- (NSString *)token; // expected-warning {{semicolon before method body is ignored}} +{ + NSMutableString *result = nil; + + return (result != nil) ? result : @""; +} +@end + diff --git a/clang/test/SemaObjC/objc2-merge-gc-attribue-decl.m b/clang/test/SemaObjC/objc2-merge-gc-attribue-decl.m new file mode 100644 index 0000000..673a741 --- /dev/null +++ b/clang/test/SemaObjC/objc2-merge-gc-attribue-decl.m @@ -0,0 +1,29 @@ +// 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 __weak id WLoopGetMain(); // expected-note {{previous declaration is here}} +extern id WLoopGetMain(); // expected-error {{conflicting types for 'WLoopGetMain'}} + +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/SemaObjC/objc2-warn-weak-decl.m b/clang/test/SemaObjC/objc2-warn-weak-decl.m new file mode 100644 index 0000000..b85f768 --- /dev/null +++ b/clang/test/SemaObjC/objc2-warn-weak-decl.m @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -fobjc-gc -verify %s +// RUN: %clang_cc1 -x objective-c++ -triple i386-apple-darwin9 -fsyntax-only -fobjc-gc -verify %s +struct S { + __weak id p; // expected-warning {{__weak attribute cannot be specified on a field declaration}} +}; + +int main () +{ + __weak id local; // expected-warning {{Objective-C GC does not allow weak variables on the stack}} +} + diff --git a/clang/test/SemaObjC/pedantic-dynamic-test.m b/clang/test/SemaObjC/pedantic-dynamic-test.m new file mode 100644 index 0000000..61f36b3 --- /dev/null +++ b/clang/test/SemaObjC/pedantic-dynamic-test.m @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wno-objc-root-class %s +// rdar: // 7860960 + +@interface I +{ + int window; +} +@property int window, noWarningNeeded; +@end + +@implementation I + +@synthesize window; + +@dynamic noWarningNeeded; +@end diff --git a/clang/test/SemaObjC/pragma-pack.m b/clang/test/SemaObjC/pragma-pack.m new file mode 100644 index 0000000..ba39257 --- /dev/null +++ b/clang/test/SemaObjC/pragma-pack.m @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -verify -Wno-objc-root-class %s + +// Make sure pragma pack works inside ObjC methods. <rdar://problem/10893316> +@interface X +@end +@implementation X +- (void)Y { +#pragma pack(push, 1) + struct x { + char a; + int b; + }; +#pragma pack(pop) + typedef char check_[sizeof (struct x) == 5 ? 1 : -1]; +} +@end diff --git a/clang/test/SemaObjC/property-10.m b/clang/test/SemaObjC/property-10.m new file mode 100644 index 0000000..51eb39c --- /dev/null +++ b/clang/test/SemaObjC/property-10.m @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -fsyntax-only -Wreadonly-setter-attrs -verify %s -fblocks + +// Check property attribute consistency. + +@interface I0 +@property(readonly, readwrite) int p0; // expected-error {{property attributes 'readonly' and 'readwrite' are mutually exclusive}} + +@property(retain) int p1; // expected-error {{property with 'retain (or strong)' attribute must be of object type}} +@property(strong) int s1; // expected-error {{property with 'retain (or strong)' attribute must be of object type}} + +@property(copy) int p2; // expected-error {{property with 'copy' attribute must be of object type}} + +@property(assign, copy) id p3_0; // expected-error {{property attributes 'assign' and 'copy' are mutually exclusive}} +@property(assign, retain) id p3_1; // expected-error {{property attributes 'assign' and 'retain' are mutually exclusive}} +@property(assign, strong) id s3_1; // expected-error {{property attributes 'assign' and 'strong' are mutually exclusive}} +@property(copy, retain) id p3_2; // expected-error {{property attributes 'copy' and 'retain' are mutually exclusive}} +@property(copy, strong) id s3_2; // expected-error {{property attributes 'copy' and 'strong' are mutually exclusive}} +@property(assign, copy, retain) id p3_3; // expected-error {{property attributes 'assign' and 'copy' are mutually exclusive}}, expected-error {{property attributes 'assign' and 'retain' are mutually exclusive}} +@property(assign, copy, strong) id s3_3; // expected-error {{property attributes 'assign' and 'copy' are mutually exclusive}}, expected-error {{property attributes 'assign' and 'strong' are mutually exclusive}} + +@property(unsafe_unretained, copy) id p4_0; // expected-error {{property attributes 'unsafe_unretained' and 'copy' are mutually exclusive}} +@property(unsafe_unretained, retain) id p4_1; // expected-error {{property attributes 'unsafe_unretained' and 'retain' are mutually exclusive}} +@property(unsafe_unretained, strong) id s4_1; // expected-error {{property attributes 'unsafe_unretained' and 'strong' are mutually exclusive}} +@property(unsafe_unretained, copy, retain) id p4_3; // expected-error {{property attributes 'unsafe_unretained' and 'copy' are mutually exclusive}}, expected-error {{property attributes 'unsafe_unretained' and 'retain' are mutually exclusive}} +@property(unsafe_unretained, copy, strong) id s4_3; // expected-error {{property attributes 'unsafe_unretained' and 'copy' are mutually exclusive}}, expected-error {{property attributes 'unsafe_unretained' and 'strong' are mutually exclusive}} + +@property id p4; // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}}, expected-warning {{default property attribute 'assign' not appropriate for non-gc object}} + +@property(nonatomic,copy) int (^includeMailboxCondition)(); +@property(nonatomic,copy) int (*includeMailboxCondition2)(); // expected-error {{property with 'copy' attribute must be of object type}} + +@end + +@interface I0() +@property (retain) int PROP; // expected-error {{property with 'retain (or strong)' attribute must be of object type}} +@property (strong) int SPROP; // expected-error {{property with 'retain (or strong)' attribute must be of object type}} +@property(nonatomic,copy) int (*PROP1)(); // expected-error {{property with 'copy' attribute must be of object type}} +@property(nonatomic,weak) int (*PROP2)(); // expected-error {{property with 'weak' attribute must be of object type}} +@end + +// rdar://10357768 +@interface rdar10357768 +{ + int n1; +} +@property (readonly, setter=crushN1:) int n1; // expected-warning {{setter cannot be specified for a readonly property}} +@end + diff --git a/clang/test/SemaObjC/property-11.m b/clang/test/SemaObjC/property-11.m new file mode 100644 index 0000000..2976115 --- /dev/null +++ b/clang/test/SemaObjC/property-11.m @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface NSSound +@end +@interface NSFont +@end + +@interface NSSound (Adds) +@end + +@implementation NSSound (Adds) +- foo { + return self; +} +- (void)setFoo:obj { +} +@end + +@implementation NSFont (Adds) + +- xx { + NSSound *x; + id o; + + // GCC does *not* warn about the following. Since foo/setFoo: are not in the + // class or category interface for NSSound, the compiler shouldn't find them. + // For now, we will support GCC's behavior (sigh). + o = [x foo]; + o = x.foo; + [x setFoo:o]; + x.foo = o; + return 0; +} + +@end + diff --git a/clang/test/SemaObjC/property-12.m b/clang/test/SemaObjC/property-12.m new file mode 100644 index 0000000..cd0fccf --- /dev/null +++ b/clang/test/SemaObjC/property-12.m @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -fsyntax-only -Wreadonly-setter-attrs -verify %s + +@protocol P0 +@property(readonly,assign) id X; // expected-warning {{property attributes 'readonly' and 'assign' are mutually exclusive}} +@end + +@protocol P1 +@property(readonly,retain) id X; // expected-warning {{property attributes 'readonly' and 'retain' are mutually exclusive}} +@end + +@protocol P2 +@property(readonly,copy) id X; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} +@end + +@protocol P3 +@property(readonly,readwrite) id X; // expected-error {{property attributes 'readonly' and 'readwrite' are mutually exclusive}} +@end + +@protocol P4 +@property(assign,copy) id X; // expected-error {{property attributes 'assign' and 'copy' are mutually exclusive}} +@end + +@protocol P5 +@property(assign,retain) id X; // expected-error {{property attributes 'assign' and 'retain' are mutually exclusive}} +@end + +@protocol P6 +@property(copy,retain) id X; // expected-error {{property attributes 'copy' and 'retain' are mutually exclusive}} +@end + + + diff --git a/clang/test/SemaObjC/property-13.m b/clang/test/SemaObjC/property-13.m new file mode 100644 index 0000000..2ca3416 --- /dev/null +++ b/clang/test/SemaObjC/property-13.m @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-unreachable-code + +@interface NSObject ++ alloc; +- init; +@end + +@protocol Test + @property int required; + +@optional + @property int optional; + @property int optional1; + @property int optional_preexisting_setter_getter; + @property (setter = setOptional_preexisting_setter_getter: , + getter = optional_preexisting_setter_getter) int optional_with_setter_getter_attr; +@required + @property int required1; +@optional + @property int optional_to_be_defined; + @property (readonly, getter = optional_preexisting_setter_getter) int optional_getter_attr; +@end + +@interface Test : NSObject <Test> { + int ivar; + int ivar1; + int ivar2; +} +@property int required; +@property int optional_to_be_defined; +- (int) optional_preexisting_setter_getter; +- (void) setOptional_preexisting_setter_getter:(int)value; +@end + +@implementation Test +@synthesize required = ivar; +@synthesize required1 = ivar1; +@synthesize optional_to_be_defined = ivar2; +- (int) optional_preexisting_setter_getter { return ivar; } +- (void) setOptional_preexisting_setter_getter:(int)value + { + ivar = value; + } +- (void) setOptional_getter_attr:(int)value { ivar = value; } +@end + +void abort(void); +int main () +{ + Test *x = [[Test alloc] init]; + /* 1. Test of a required property */ + x.required1 = 100; + if (x.required1 != 100) + abort (); + + /* 2. Test of a synthesize optional property */ + x.optional_to_be_defined = 123; + if (x.optional_to_be_defined != 123) + abort (); + + /* 3. Test of optional property with pre-sxisting defined setter/getter */ + x.optional_preexisting_setter_getter = 200; + if (x.optional_preexisting_setter_getter != 200) + abort (); + + /* 4. Test of optional property with setter/getter attribute */ + if (x.optional_with_setter_getter_attr != 200) + abort (); + return 0; + + /* 5. Test of optional property with getter attribute and default setter method. */ + x.optional_getter_attr = 1000; + if (x.optional_getter_attr != 1000) + abort (); + + return 0; +} + diff --git a/clang/test/SemaObjC/property-2.m b/clang/test/SemaObjC/property-2.m new file mode 100644 index 0000000..f95af59 --- /dev/null +++ b/clang/test/SemaObjC/property-2.m @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface Tester +@property char PropertyAtomic_char; +@property short PropertyAtomic_short; +@property int PropertyAtomic_int; +@property long PropertyAtomic_long; +@property long long PropertyAtomic_longlong; +@property float PropertyAtomic_float; +@property double PropertyAtomic_double; +@property(assign) id PropertyAtomic_id; +@property(retain) id PropertyAtomicRetained_id; +@property(copy) id PropertyAtomicRetainedCopied_id; +@property(retain) id PropertyAtomicRetainedGCOnly_id; +@property(copy) id PropertyAtomicRetainedCopiedGCOnly_id; +@end + +@implementation Tester +@dynamic PropertyAtomic_char; +@dynamic PropertyAtomic_short; +@dynamic PropertyAtomic_int; +@dynamic PropertyAtomic_long; +@dynamic PropertyAtomic_longlong; +@dynamic PropertyAtomic_float; +@dynamic PropertyAtomic_double; +@dynamic PropertyAtomic_id; +@dynamic PropertyAtomicRetained_id; +@dynamic PropertyAtomicRetainedCopied_id; +@dynamic PropertyAtomicRetainedGCOnly_id; +@dynamic PropertyAtomicRetainedCopiedGCOnly_id; +@end + +@interface SubClass : Tester +{ + char PropertyAtomic_char; + short PropertyAtomic_short; + int PropertyAtomic_int; + long PropertyAtomic_long; + long long PropertyAtomic_longlong; + float PropertyAtomic_float; + double PropertyAtomic_double; + id PropertyAtomic_id; + id PropertyAtomicRetained_id; + id PropertyAtomicRetainedCopied_id; + id PropertyAtomicRetainedGCOnly_id; + id PropertyAtomicRetainedCopiedGCOnly_id; +} +@end + +@implementation SubClass +@synthesize PropertyAtomic_char; +@synthesize PropertyAtomic_short; +@synthesize PropertyAtomic_int; +@synthesize PropertyAtomic_long; +@synthesize PropertyAtomic_longlong; +@synthesize PropertyAtomic_float; +@synthesize PropertyAtomic_double; +@synthesize PropertyAtomic_id; +@synthesize PropertyAtomicRetained_id; +@synthesize PropertyAtomicRetainedCopied_id; +@synthesize PropertyAtomicRetainedGCOnly_id; +@synthesize PropertyAtomicRetainedCopiedGCOnly_id; +@end diff --git a/clang/test/SemaObjC/property-3.m b/clang/test/SemaObjC/property-3.m new file mode 100644 index 0000000..439dc28 --- /dev/null +++ b/clang/test/SemaObjC/property-3.m @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -verify %s + +@interface I +{ + id d1; +} +@property (readwrite, copy) id d1; +@property (readwrite, copy) id d2; +@end + +@interface NOW : I +@property (readonly) id d1; // expected-warning {{attribute 'readonly' of property 'd1' restricts attribute 'readwrite' of property inherited from 'I'}} expected-warning {{property 'd1' 'copy' attribute does not match the property inherited from 'I'}} +@property (readwrite, copy) I* d2; +@end diff --git a/clang/test/SemaObjC/property-4.m b/clang/test/SemaObjC/property-4.m new file mode 100644 index 0000000..2168048 --- /dev/null +++ b/clang/test/SemaObjC/property-4.m @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -verify %s + +@interface Object +@end + +@protocol ProtocolObject +@property int class; +@property (copy) id MayCauseError; +@end + +@protocol ProtocolDerivedGCObject <ProtocolObject> +@property int Dclass; +@end + +@interface GCObject : Object <ProtocolDerivedGCObject> { + int ifield; + int iOwnClass; + int iDclass; +} +@property int OwnClass; +@end + +@interface ReleaseObject : GCObject <ProtocolObject> { + int newO; + int oldO; +} +@property (retain) id MayCauseError; // expected-warning {{property 'MayCauseError' 'copy' attribute does not match the property inherited from 'ProtocolObject'}} +@end + diff --git a/clang/test/SemaObjC/property-5.m b/clang/test/SemaObjC/property-5.m new file mode 100644 index 0000000..cd7cc24 --- /dev/null +++ b/clang/test/SemaObjC/property-5.m @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -verify %s + +@protocol P1 @end +@protocol P2 @end +@protocol P3 @end + +@interface NSData @end + +@interface MutableNSData : NSData @end + +@interface Base : NSData <P1> +@property(readonly) id ref; +@property(readonly) Base *p_base; +@property(readonly) NSData *nsdata; +@property(readonly) NSData * m_nsdata; +@end + +@interface Data : Base <P1, P2> +@property(readonly) NSData *ref; +@property(readonly) Data *p_base; +@property(readonly) MutableNSData * m_nsdata; +@end + +@interface MutedData: Data +@property(readonly) id p_base; +@end + +@interface ConstData : Data <P1, P2, P3> +@property(readonly) ConstData *p_base; +@end + +void foo(Base *b, id x) { + [ b setRef: x ]; // expected-warning {{method '-setRef:' not found}} +} diff --git a/clang/test/SemaObjC/property-6.m b/clang/test/SemaObjC/property-6.m new file mode 100644 index 0000000..933a4f0 --- /dev/null +++ b/clang/test/SemaObjC/property-6.m @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fobjc-exceptions %s +# 1 "<command line>" +# 1 "/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h" 1 3 +typedef signed char BOOL; +typedef unsigned int NSUInteger; +typedef struct _NSZone NSZone; + +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; + +@protocol NSObject +- (BOOL)isEqual:(id)object; ++ class; +@end + +@protocol NSCopying +- (id)copyWithZone:(NSZone *)zone; +@end + +@protocol NSMutableCopying +- (id)mutableCopyWithZone:(NSZone *)zone; +@end + +@protocol NSCoding +- (void)encodeWithCoder:(NSCoder *)aCoder; +@end + +@interface NSObject <NSObject> {} +@end + +typedef struct {} NSFastEnumerationState; + +@protocol NSFastEnumeration +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; +@end + +@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> +- (NSUInteger)count; +@end + +@interface NSMutableArray : NSArray +- (void)addObject:(id)anObject; ++ (id)arrayWithCapacity:(int)numItems; +@end + +@interface NSBundle : NSObject {} ++ (NSBundle *)bundleForClass:(Class)aClass; +- (NSString *)bundlePath; +- (void)setBundlePath:(NSString *)x; +@end + +@interface NSException : NSObject <NSCopying, NSCoding> {} +@end + +@class NSArray, NSDictionary, NSError, NSString, NSURL; + +@interface DTPlugInManager : NSObject +@end + +@implementation DTPlugInManager ++ (DTPlugInManager *)defaultPlugInManager { + @try { + NSMutableArray *plugInPaths = [NSMutableArray arrayWithCapacity:100]; + NSBundle *frameworkBundle = [NSBundle bundleForClass:[DTPlugInManager class]]; + frameworkBundle.bundlePath = 0; + [plugInPaths addObject:frameworkBundle.bundlePath]; + } + @catch (NSException *exception) {} +} +@end diff --git a/clang/test/SemaObjC/property-7.m b/clang/test/SemaObjC/property-7.m new file mode 100644 index 0000000..e6cba50 --- /dev/null +++ b/clang/test/SemaObjC/property-7.m @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +typedef signed char BOOL; +typedef struct _NSZone NSZone; + +@protocol NSObject +- (BOOL)isEqual:(id)object; +@end + +@protocol NSCopying +- (id)copyWithZone:(NSZone *)zone; +@end + +@interface NSObject <NSObject> {} +@end + +@class NSString, NSData, NSMutableData, NSMutableDictionary, NSMutableArray; + +@interface SCMObject : NSObject <NSCopying> {} + @property(assign) SCMObject *__attribute__((objc_gc(weak))) parent; +@end + +@interface SCMNode : SCMObject +{ + NSString *_name; +} +@property(copy) NSString *name; +@end + +@implementation SCMNode + @synthesize name = _name; + - (void) setParent:(SCMObject *__attribute__((objc_gc(weak)))) inParent { + super.parent = inParent; + } +@end diff --git a/clang/test/SemaObjC/property-8.m b/clang/test/SemaObjC/property-8.m new file mode 100644 index 0000000..8647aba --- /dev/null +++ b/clang/test/SemaObjC/property-8.m @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +typedef signed char BOOL; +typedef unsigned int NSUInteger; +typedef struct _NSZone NSZone; + +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; + +@protocol NSObject - (BOOL)isEqual:(id)object; @end +@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end +@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end +@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end + +@interface NSObject <NSObject> {} @end + +typedef float CGFloat; + +typedef enum { NSMinXEdge = 0, NSMinYEdge = 1, NSMaxXEdge = 2, NSMaxYEdge = 3 } NSFastEnumerationState; + +@protocol NSFastEnumeration +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; +@end + +@class NSString; + +@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> +- (NSUInteger)count; +@end + +extern NSString * const NSBundleDidLoadNotification; + +@interface NSObject(NSKeyValueObserving) +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context; +- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath; +@end + +enum { NSCaseInsensitivePredicateOption = 0x01, NSDiacriticInsensitivePredicateOption = 0x02 }; + +@interface NSResponder : NSObject <NSCoding> {} +@end + +extern NSString * const NSFullScreenModeAllScreens; +@interface NSWindowController : NSResponder <NSCoding> {} +@end + +extern NSString *NSAlignmentBinding ; + +@interface _XCOQQuery : NSObject {} +@end + +extern NSString *PBXWindowDidChangeFirstResponderNotification; + +@interface PBXModule : NSWindowController {} +@end + +@class _XCOQHelpTextBackgroundView; +@interface PBXOpenQuicklyModule : PBXModule +{ +@private + _XCOQQuery *_query; +} +@end + +@interface PBXOpenQuicklyModule () +@property(readwrite, retain) _XCOQQuery *query; +@end + +@implementation PBXOpenQuicklyModule +@synthesize query = _query; +- (void) _clearQuery +{ + [self.query removeObserver: self forKeyPath: @"matches"]; +} +@end + diff --git a/clang/test/SemaObjC/property-9-impl-method.m b/clang/test/SemaObjC/property-9-impl-method.m new file mode 100644 index 0000000..84eb363 --- /dev/null +++ b/clang/test/SemaObjC/property-9-impl-method.m @@ -0,0 +1,95 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify +// rdar://5967199 + +typedef signed char BOOL; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; + +@protocol NSObject +- (BOOL) isEqual:(id) object; +@end + +@protocol NSCoding +- (void) encodeWithCoder:(NSCoder *) aCoder; +@end + +@interface NSObject < NSObject > {} +@end + +typedef float CGFloat; +typedef struct _NSPoint {} NSSize; +typedef struct _NSRect {} NSRect; +typedef enum { NSMinXEdge = 0, NSMinYEdge = 1, NSMaxXEdge = 2, NSMaxYEdge = 3} NSRectEdge; +extern void NSDivideRect(NSRect inRect, NSRect * slice, NSRect * rem, CGFloat amount, NSRectEdge edge); + +@interface NSResponder:NSObject < NSCoding > {} +@end + +@protocol NSAnimatablePropertyContainer +- (id) animator; +@end + +extern NSString *NSAnimationTriggerOrderIn; + +@interface NSView:NSResponder < NSAnimatablePropertyContainer > {} +-(NSRect) bounds; +@end + +enum { + NSBackgroundStyleLight = 0, NSBackgroundStyleDark, NSBackgroundStyleRaised, NSBackgroundStyleLowered +}; + +@interface NSTabView:NSView {} +@end + +@ class OrganizerTabHeader; + +@interface OrganizerTabView:NSTabView {} +@property(assign) +NSSize minimumSize; +@end + +@interface OrganizerTabView() +@property(readonly) OrganizerTabHeader *tabHeaderView; +@property(readonly) NSRect headerRect; +@end + +@implementation OrganizerTabView +@dynamic tabHeaderView, headerRect, minimumSize; +-(CGFloat) tabAreaThickness { return 0; } +-(NSRectEdge) rectEdgeForTabs { + NSRect dummy, result = {}; + NSDivideRect(self.bounds, &result, &dummy, self.tabAreaThickness, self.rectEdgeForTabs); + return 0; +} +@end + +@class NSImage; + +@interface XCImageArchiveEntry : NSObject +{ + NSImage *_cachedImage; +} + +@end + +@implementation XCImageArchiveEntry + +- (NSImage *)image +{ + return _cachedImage; +} + +@end + +@interface XCImageArchive : NSObject +@end + +@implementation XCImageArchive + +- (NSImage *)imageNamed:(NSString *)name +{ + XCImageArchiveEntry * entry; + return entry ? entry.image : ((void *)0); +} + +@end diff --git a/clang/test/SemaObjC/property-9.m b/clang/test/SemaObjC/property-9.m new file mode 100644 index 0000000..4bed875 --- /dev/null +++ b/clang/test/SemaObjC/property-9.m @@ -0,0 +1,108 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +typedef signed char BOOL; +@protocol NSObject - (BOOL)isEqual:(id)object; @end + +@interface NSObject <NSObject> {} @end + +@interface _NSServicesInContextMenu : NSObject { + id _requestor; + NSObject *_appleEventDescriptor; +} + +@property (retain, nonatomic) id requestor; +@property (retain, nonatomic) id appleEventDescriptor; + +@end + +@implementation _NSServicesInContextMenu + +@synthesize requestor = _requestor, appleEventDescriptor = _appleEventDescriptor; + +@end + +@class NSString; + +@protocol MyProtocol +- (NSString *)stringValue; +@end + +@interface MyClass : NSObject { + id _myIvar; +} +@property (readwrite, retain) id<MyProtocol> myIvar; +@end + +@implementation MyClass +@synthesize myIvar = _myIvar; +@end + + +@interface BadPropClass +{ + int _awesome; +} + +@property (readonly) int; // expected-warning {{declaration does not declare anything}} +@property (readonly) ; // expected-error {{type name requires a specifier or qualifier}} +@property (readonly) int : 4; // expected-error {{property requires fields to be named}} + + +// test parser recovery: rdar://6254579 +@property ( // expected-note {{to match this '('}} + readonly getter=isAwesome) // expected-error {{expected ')'}} + + int _awesome; +@property (readonlyx) // expected-error {{unknown property attribute 'readonlyx'}} + int _awesome2; + +@property ( // expected-note {{to match this '('}} + +) // expected-error {{expected ')'}} + + int _awesome3; + +@end + +@protocol PVImageViewProtocol +@property int inEyeDropperMode; +@end + +@interface Cls +@property int inEyeDropperMode; +@end + +@interface PVAdjustColor @end + +@implementation PVAdjustColor + +- xx { + id <PVImageViewProtocol> view; + Cls *c; + + c.inEyeDropperMode = 1; + view.inEyeDropperMode = 1; +} +@end + +// radar 7427072 +@interface MyStyleIntf +{ + int _myStyle; +} + +@property(readonly) int myStyle; + +- (float)setMyStyle:(int)style; +@end + +// rdar://8774513 +@class MDAInstance; // expected-note {{forward declaration of class here}} + +@interface MDATestDocument +@property(retain) MDAInstance *instance; +@end + +id f0(MDATestDocument *d) { + return d.instance.path; // expected-error {{property 'path' cannot be found in forward class object 'MDAInstance'}} +} + diff --git a/clang/test/SemaObjC/property-and-class-extension.m b/clang/test/SemaObjC/property-and-class-extension.m new file mode 100644 index 0000000..7040078 --- /dev/null +++ b/clang/test/SemaObjC/property-and-class-extension.m @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +/** +When processing @synthesize, treat ivars in a class extension the same as ivars in the class @interface, +and treat ivars in a superclass extension the same as ivars in the superclass @interface. +In particular, when searching for an ivar to back an @synthesize, do look at ivars in the class's own class +extension but ignore any ivars in superclass class extensions. +*/ + +@interface Super { + int ISA; +} +@end + +@interface Super() { + int Property; // expected-note {{previously declared 'Property' here}} +} +@end + +@interface SomeClass : Super { + int interfaceIvar1; + int interfaceIvar2; +} +@property int Property; +@property int Property1; +@end + +@interface SomeClass () { + int Property1; +} +@end + +@implementation SomeClass +@synthesize Property; // expected-error {{property 'Property' attempting to use ivar 'Property' declared in super class 'Super'}} +@synthesize Property1; // OK +@end diff --git a/clang/test/SemaObjC/property-and-ivar-use.m b/clang/test/SemaObjC/property-and-ivar-use.m new file mode 100644 index 0000000..5b40d85 --- /dev/null +++ b/clang/test/SemaObjC/property-and-ivar-use.m @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// Do not issue error if 'ivar' used previously belongs to the inherited class +// and has same name as @dynalic property in current class. + +typedef signed char BOOL; + +@protocol IDEBuildable +@property (readonly) BOOL hasRecursiveDependencyCycle; +@end + +@protocol IDEBuildableProduct <IDEBuildable> +@end + +@interface IDEBuildableSupportMixIn +@property (readonly) BOOL hasRecursiveDependencyCycle; +@end + +@interface Xcode3TargetBuildable <IDEBuildable> +{ + IDEBuildableSupportMixIn *_buildableMixIn; +} +@end + +@interface Xcode3TargetProduct : Xcode3TargetBuildable <IDEBuildableProduct> +@end + +@implementation Xcode3TargetBuildable +- (BOOL)hasRecursiveDependencyCycle +{ + return [_buildableMixIn hasRecursiveDependencyCycle]; +} +@end + +@implementation Xcode3TargetProduct +@dynamic hasRecursiveDependencyCycle; +@end diff --git a/clang/test/SemaObjC/property-category-1.m b/clang/test/SemaObjC/property-category-1.m new file mode 100644 index 0000000..3788bc9 --- /dev/null +++ b/clang/test/SemaObjC/property-category-1.m @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface Object ++ (id)new; +@end + +@interface ReadOnly : Object +{ + int _object; + int _Anotherobject; +} +@property(readonly) int object; +@property(readonly) int Anotherobject; +@end + +@interface ReadOnly () +@property(readwrite) int object; +@property(readwrite, setter = myAnotherobjectSetter:) int Anotherobject; +@end + +@implementation ReadOnly +@synthesize object = _object; +@synthesize Anotherobject = _Anotherobject; +- (void) myAnotherobjectSetter : (int)val { + _Anotherobject = val; +} +- (int) Anotherobject { return _Anotherobject; } +@end + +int main(int argc, char **argv) { + ReadOnly *test = [ReadOnly new]; + test.object = 12345; + test.Anotherobject = 200; + return test.object - 12345 + test.Anotherobject - 200; +} + +/// + +@interface I0 +@property(readonly) int p0; // expected-note {{property declared here}} +@end + +@interface I0 (Cat0) +@end + +@interface I0 (Cat1) +@end + +@implementation I0 // expected-warning {{property 'p0' requires method 'p0' to be define}} +- (void) foo { + self.p0 = 0; // expected-error {{assignment to readonly property}} +} +@end diff --git a/clang/test/SemaObjC/property-category-2.m b/clang/test/SemaObjC/property-category-2.m new file mode 100644 index 0000000..ecc3681 --- /dev/null +++ b/clang/test/SemaObjC/property-category-2.m @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// Test that a property can be synthesize in a category +// implementation with no error. + +@protocol MyProtocol +@property float myFloat; +@property float anotherFloat; // expected-note 2 {{property declared}} +@end + +@interface MyObject { float anotherFloat; } +@end + +@interface MyObject (CAT) <MyProtocol> +@end + +@implementation MyObject (CAT) // expected-warning {{property 'anotherFloat' requires method}} \ + // expected-warning {{property 'anotherFloat' requires method 'setAnotherFloat:'}} +@dynamic myFloat; // OK +@synthesize anotherFloat; // expected-error {{@synthesize not allowed in a category's implementation}} +@end diff --git a/clang/test/SemaObjC/property-category-3.m b/clang/test/SemaObjC/property-category-3.m new file mode 100644 index 0000000..47e93a3 --- /dev/null +++ b/clang/test/SemaObjC/property-category-3.m @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@protocol P + @property(readonly) int X; // expected-note {{property declared here}} +@end + +@protocol P1<P> + @property (copy) id ID; +@end + +@interface I +@end + +@interface I (Cat) <P> +@property float X; // expected-warning {{property type 'float' is incompatible with type 'int' inherited from 'P'}} +@end + +@interface I (Cat2) <P1> +@property (retain) id ID; // expected-warning {{property 'ID' 'copy' attribute does not match the property inherited from 'P1'}} +@end + + +@interface A +@property(assign) int categoryProperty; +@end + +// Don't issue warning on unimplemented setter/getter +// because property is @dynamic. +@implementation A +@dynamic categoryProperty; +@end diff --git a/clang/test/SemaObjC/property-category-4.m b/clang/test/SemaObjC/property-category-4.m new file mode 100644 index 0000000..e7939b3 --- /dev/null +++ b/clang/test/SemaObjC/property-category-4.m @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface IDELogNavigator +{ + id selectedObjects; +} +@end + +@interface IDELogNavigator (CAT) + @property (readwrite, retain) id selectedObjects; // expected-note {{property declared here}} + @property (readwrite, retain) id d_selectedObjects; // expected-note {{property declared here}} +@end + +@implementation IDELogNavigator +@synthesize selectedObjects = _selectedObjects; // expected-error {{property declared in category 'CAT' cannot be implemented in class implementation}} +@dynamic d_selectedObjects; // expected-error {{property declared in category 'CAT' cannot be implemented in class implementation}} +@end + diff --git a/clang/test/SemaObjC/property-category-impl.m b/clang/test/SemaObjC/property-category-impl.m new file mode 100644 index 0000000..9524c22 --- /dev/null +++ b/clang/test/SemaObjC/property-category-impl.m @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +/* This test is for categories which don't implement the accessors but some accessors are + implemented in their base class implementation. In this case,no warning must be issued. +*/ + +@interface MyClass +{ + int _foo; +} +@property(readonly) int foo; +@end + +@implementation MyClass +- (int) foo { return _foo; } +@end + +@interface MyClass (private) +@property(readwrite) int foo; +@end + +@implementation MyClass (private) +- (void) setFoo:(int)foo { _foo = foo; } +@end + +@interface MyClass (public) +@property(readwrite) int foo; // expected-note {{property declared here}} +@end + +@implementation MyClass (public)// expected-warning {{property 'foo' requires method 'setFoo:' to be defined }} +@end diff --git a/clang/test/SemaObjC/property-dot-receiver.m b/clang/test/SemaObjC/property-dot-receiver.m new file mode 100644 index 0000000..c5a928b --- /dev/null +++ b/clang/test/SemaObjC/property-dot-receiver.m @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://8962253 + +@interface Singleton { +} ++ (Singleton*) instance; +@end + +@implementation Singleton + +- (void) someSelector { } + ++ (Singleton*) instance { return 0; } + ++ (void) compileError +{ + [Singleton.instance someSelector]; // clang issues error here +} + +@end + diff --git a/clang/test/SemaObjC/property-error-readonly-assign.m b/clang/test/SemaObjC/property-error-readonly-assign.m new file mode 100644 index 0000000..3484172 --- /dev/null +++ b/clang/test/SemaObjC/property-error-readonly-assign.m @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface A + -(int) x; +@property (readonly) int x; +@property int ok; +@end + +@interface B + -(void) setOk:(int)arg; + -(int) x; + -(int) ok; +@end + +void f0(A *a, B* b) { + a.x = 10; // expected-error {{assignment to readonly property}} + a.ok = 20; + b.x = 10; // expected-error {{no setter method 'setX:' for assignment to property}} + b.ok = 20; +} + +typedef struct { + int i1, i2; +} NSRect; + +NSRect NSMakeRect(); + +@interface NSWindow +{ + NSRect _frame; +} +- (NSRect)frame; +@end + +@interface NSWindow (Category) +-(void)methodToMakeClangCrash; +@end + +@implementation NSWindow (Category) +-(void)methodToMakeClangCrash +{ + self.frame = NSMakeRect(); // expected-error {{no setter method 'setFrame:' for assignment to property}} +} +@end diff --git a/clang/test/SemaObjC/property-expression-error.m b/clang/test/SemaObjC/property-expression-error.m new file mode 100644 index 0000000..e306722 --- /dev/null +++ b/clang/test/SemaObjC/property-expression-error.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface AddressMyProperties +{ + unsigned index; +} +@property unsigned index; +@end + +@implementation AddressMyProperties +@synthesize index; +@end + +int main() { + AddressMyProperties *object; + &object.index; // expected-error {{address of property expression requested}} + return 0; +} + +typedef int Foo; +void test() { + Foo.x; // expected-error {{expected identifier or '('}} +} diff --git a/clang/test/SemaObjC/property-impl-misuse.m b/clang/test/SemaObjC/property-impl-misuse.m new file mode 100644 index 0000000..c3cedb0 --- /dev/null +++ b/clang/test/SemaObjC/property-impl-misuse.m @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface I { + int Y; +} +@property int X; +@property int Y; +@property int Z; +@end + +@implementation I +@dynamic X; // expected-note {{previous declaration is here}} +@dynamic X; // expected-error {{property 'X' is already implemented}} +@synthesize Y; // expected-note {{previous use is here}} +@synthesize Z=Y; // expected-error {{synthesized properties 'Z' and 'Y' both claim ivar 'Y'}} +@end + +// rdar://8703553 +@interface IDEPathCell +{ +@private + id _gradientStyle; +} + +@property (readwrite, assign, nonatomic) id gradientStyle; +@end + +@implementation IDEPathCell + +@synthesize gradientStyle = _gradientStyle; +- (void)setGradientStyle:(id)value { } + ++ (void)_componentCellWithRepresentedObject { + self.gradientStyle; // expected-error {{property 'gradientStyle' not found on object of type 'Class'}} +} +@end diff --git a/clang/test/SemaObjC/property-in-class-extension.m b/clang/test/SemaObjC/property-in-class-extension.m new file mode 100644 index 0000000..a7b5130 --- /dev/null +++ b/clang/test/SemaObjC/property-in-class-extension.m @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://7766184 + +@interface Foo @end + +@interface Foo () + @property (readonly) int bar; +@end + +void FUNC () { + Foo *foo; + foo.bar = 0; // expected-error {{assignment to readonly property}} +} + +// rdar://8747333 +@class NSObject; + +@interface rdar8747333 { +@private + NSObject *_bar; + NSObject *_baz; + NSObject *_bam; +} +- (NSObject *)baz; +@end + +@interface rdar8747333 () +- (NSObject *)bar; +@end + +@interface rdar8747333 () +@property (readwrite, assign) NSObject *bar; +@property (readwrite, assign) NSObject *baz; +@property (readwrite, assign) NSObject *bam; +@property (readwrite, assign) NSObject *warn; +@end + +@interface rdar8747333 () +- (NSObject *)bam; +- (NSObject *)warn; // expected-note {{method definition for 'warn' not found}} +- (void)setWarn : (NSObject *)val; // expected-note {{method definition for 'setWarn:' not found}} +@end + +@implementation rdar8747333 // expected-warning {{incomplete implementation}} +@synthesize bar = _bar; +@synthesize baz = _baz; +@synthesize bam = _bam; +@dynamic warn; +@end + diff --git a/clang/test/SemaObjC/property-inherited.m b/clang/test/SemaObjC/property-inherited.m new file mode 100644 index 0000000..f5f1b42 --- /dev/null +++ b/clang/test/SemaObjC/property-inherited.m @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify +// RUN: %clang_cc1 -x objective-c++ %s -fsyntax-only -verify + +// rdar://6497242 Inherited overridden protocol declared objects don't work +// rdar://9740328 Case for c++ + +@protocol NSObject @end +@interface NSObject @end + +@protocol FooDelegate<NSObject> +@optional +- (void)fooTask; +@end + +@protocol BarDelegate<NSObject, FooDelegate> +@optional +- (void)barTask; +@end + +@interface Foo : NSObject { + id _delegate; +} +@property(nonatomic, assign) id<FooDelegate> delegate; +@property(nonatomic, assign) id<BarDelegate> delegate2; // expected-note {{property declared here}} +@end +@interface Bar : Foo { +} +@property(nonatomic, assign) id<BarDelegate> delegate; +@property(nonatomic, assign) id<FooDelegate> delegate2; // expected-warning{{property type 'id<FooDelegate>' is incompatible with type 'id<BarDelegate>' inherited from 'Foo'}} +@end + +@interface NSData @end + +@interface NSMutableData : NSData @end + +@interface Base : NSData +@property(assign) id ref; +@property(assign) Base *p_base; +@property(assign) NSMutableData *p_data; // expected-note {{property declared here}} +@end + +@interface Data : Base +@property(assign) NSData *ref; +@property(assign) Data *p_base; +@property(assign) NSData *p_data; // expected-warning{{property type 'NSData *' is incompatible with type 'NSMutableData *' inherited from 'Base'}} +@end diff --git a/clang/test/SemaObjC/property-ivar-mismatch.m b/clang/test/SemaObjC/property-ivar-mismatch.m new file mode 100644 index 0000000..6abd6e6 --- /dev/null +++ b/clang/test/SemaObjC/property-ivar-mismatch.m @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// Test that arithmatic types on property and its ivar have exact match. + +@interface Test4 +{ + char ivar; // expected-note{{ivar is declared here}} +} +@property int prop; +@end + +@implementation Test4 +@synthesize prop = ivar; // expected-error {{type of property 'prop' ('int') does not match type of ivar 'ivar' ('char')}} +@end + diff --git a/clang/test/SemaObjC/property-lookup-in-id.m b/clang/test/SemaObjC/property-lookup-in-id.m new file mode 100644 index 0000000..38aa32c --- /dev/null +++ b/clang/test/SemaObjC/property-lookup-in-id.m @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://9106929 + +typedef struct objc_class *Class; + +typedef struct objc_object { + Class isa; +} *id; + + +typedef struct __FSEventStream* FSEventStreamRef; + +extern id NSApp; + +@interface FileSystemMonitor { + + FSEventStreamRef fsEventStream; +} +@property(assign) FSEventStreamRef fsEventStream; + +@end + +@implementation FileSystemMonitor +@synthesize fsEventStream; + +- (void)startFSEventGathering:(id)sender +{ + fsEventStream = [NSApp delegate].fsEventStream; // expected-warning {{instance method '-delegate' not found (return type defaults to 'id')}} \ + // expected-error {{property 'fsEventStream' not found on object of type 'id'}} + +} +@end + diff --git a/clang/test/SemaObjC/property-method-lookup-impl.m b/clang/test/SemaObjC/property-method-lookup-impl.m new file mode 100644 index 0000000..19d4e68 --- /dev/null +++ b/clang/test/SemaObjC/property-method-lookup-impl.m @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface SSyncCEList +{ + id _list; +} +@end + +@implementation SSyncCEList + +- (id) list { return 0; } +@end + +@interface SSyncConflictList : SSyncCEList +@end + +@implementation SSyncConflictList + +- (id)Meth : (SSyncConflictList*)other + { + return other.list; + } +@end + diff --git a/clang/test/SemaObjC/property-missing.m b/clang/test/SemaObjC/property-missing.m new file mode 100644 index 0000000..3ebf0a8 --- /dev/null +++ b/clang/test/SemaObjC/property-missing.m @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// PR3234 + +@protocol NSCopying @end +@interface NSObject @end + +void f1(NSObject *o) +{ + o.foo; // expected-error{{property 'foo' not found on object of type 'NSObject *'}} +} + +void f2(id<NSCopying> o) +{ + o.foo; // expected-error{{property 'foo' not found on object of type 'id<NSCopying>'}} +} + +void f3(id o) +{ + o.foo; // expected-error{{property 'foo' not found on object of type 'id'}} +} + +// rdar://8851803 +@class SomeOtherClass; // expected-note {{forward declaration of class here}} + +@interface MyClass { + SomeOtherClass *someOtherObject; +} +@end + +void foo(MyClass *myObject) { + myObject.someOtherObject.someProperty = 0; // expected-error {{property 'someOtherObject' refers to an incomplete Objective-C class 'SomeOtherClass' (with no @interface available)}} +} + diff --git a/clang/test/SemaObjC/property-nonfragile-abi.m b/clang/test/SemaObjC/property-nonfragile-abi.m new file mode 100644 index 0000000..55bf91f --- /dev/null +++ b/clang/test/SemaObjC/property-nonfragile-abi.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef signed char BOOL; + +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; + +@protocol NSObject +- (BOOL)isEqual:(id)object; +@end + +@interface NSObject <NSObject> {} +@end + +@interface XCDeviceWillExecuteInfoBaton : NSObject {} + @property (retain) __attribute__((objc_gc(strong))) NSString *sdkPath; +@end + +@implementation XCDeviceWillExecuteInfoBaton + @synthesize sdkPath; +@end + diff --git a/clang/test/SemaObjC/property-noprotocol-warning.m b/clang/test/SemaObjC/property-noprotocol-warning.m new file mode 100644 index 0000000..71bb86a --- /dev/null +++ b/clang/test/SemaObjC/property-noprotocol-warning.m @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + + +@interface Object ++ (id) new; +@end + +@protocol GCObject +@property int class; +@end + +@protocol DerivedGCObject <GCObject> +@property int Dclass; +@end + +@interface GCObject : Object <DerivedGCObject> { + int ifield; + int iOwnClass; + int iDclass; +} +@property int OwnClass; +@end + +@implementation GCObject : Object +@synthesize class=ifield; +@synthesize Dclass=iDclass; +@synthesize OwnClass=iOwnClass; +@end + +int main(int argc, char **argv) { + GCObject *f = [GCObject new]; + f.class = 5; + f.Dclass = 1; + f.OwnClass = 3; + return f.class + f.Dclass + f.OwnClass - 9; +} diff --git a/clang/test/SemaObjC/property-not-lvalue.m b/clang/test/SemaObjC/property-not-lvalue.m new file mode 100644 index 0000000..12d2cc6 --- /dev/null +++ b/clang/test/SemaObjC/property-not-lvalue.m @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +typedef struct NSSize { + int width; + struct { + int dim; + } inner; +} NSSize; + +@interface Foo { + NSSize _size; +} +@property NSSize size; +@end + +void foo() { + Foo *f; + f.size.width = 2.2; // expected-error {{expression is not assignable}} + f.size.inner.dim = 200; // expected-error {{expression is not assignable}} +} + +// radar 7628953 + +@interface Gorf { +} +- (NSSize)size; +@end + +@implementation Gorf +- (void)MyView_sharedInit { + self.size.width = 2.2; // expected-error {{expression is not assignable}} +} +- (NSSize)size {} +@end diff --git a/clang/test/SemaObjC/property-ns-returns-not-retained-attr.m b/clang/test/SemaObjC/property-ns-returns-not-retained-attr.m new file mode 100644 index 0000000..96ef3ed --- /dev/null +++ b/clang/test/SemaObjC/property-ns-returns-not-retained-attr.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://9636091 + +@interface I +@property (nonatomic, retain) id newName __attribute__((ns_returns_not_retained)) ; + +@property (nonatomic, retain) id newName1 __attribute__((ns_returns_not_retained)) ; +- (id) newName1 __attribute__((ns_returns_not_retained)); + +@property (nonatomic, retain) id newName2 __attribute__((ns_returns_not_retained)); // expected-note {{roperty declared here}} +- (id) newName2; // expected-warning {{property declared as returning non-retained objects; getter returning retained objects}} +@end + +@implementation I +@synthesize newName; + +@synthesize newName1; +- (id) newName1 { return 0; } + +@synthesize newName2; +@end diff --git a/clang/test/SemaObjC/property-redundant-decl-accessor.m b/clang/test/SemaObjC/property-redundant-decl-accessor.m new file mode 100644 index 0000000..3b0e825 --- /dev/null +++ b/clang/test/SemaObjC/property-redundant-decl-accessor.m @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -Werror -verify -Wno-objc-root-class %s + +@interface MyClass { + const char *_myName; +} + +@property const char *myName; + +- (const char *)myName; +- (void)setMyName:(const char *)name; + +@end + +@implementation MyClass + +@synthesize myName = _myName; + +@end diff --git a/clang/test/SemaObjC/property-typecheck-1.m b/clang/test/SemaObjC/property-typecheck-1.m new file mode 100644 index 0000000..f71e4a0 --- /dev/null +++ b/clang/test/SemaObjC/property-typecheck-1.m @@ -0,0 +1,101 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface A +-(float) x; // expected-note {{declared here}} +@property int x; // expected-warning {{type of property 'x' does not match type of accessor 'x'}} +@end + +@interface A (Cat) +@property int moo; // expected-note {{previous definition is here}} +@end + +@implementation A (Cat) +-(int) moo { + return 0; +} +-(void) setMoo: (float) x { // expected-warning {{conflicting parameter types in implementation of 'setMoo:': 'int' vs 'float'}} +} +@end + + +typedef int T[2]; +typedef void (F)(void); + +@interface C +@property(assign) T p2; // expected-error {{property cannot have array or function type 'T'}} + +@property(assign) F f2; // expected-error {{property cannot have array or function type 'F'}} + +@end + + +@class SSyncSet; + +@interface SPeer + @property(nonatomic,readonly,retain) SSyncSet* syncSet; +@end + +@class SSyncSet_iDisk; + +@interface SPeer_iDisk_remote1 : SPeer +- (SSyncSet_iDisk*) syncSet; // expected-note {{declared here}} +@end + +@interface SPeer_iDisk_local +- (SSyncSet_iDisk*) syncSet; +@end + +@interface SSyncSet +@end + +@interface SSyncSet_iDisk +@property(nonatomic,readonly,retain) SPeer_iDisk_local* localPeer; +@end + +@interface SPeer_iDisk_remote1 (protected) +@end + +@implementation SPeer_iDisk_remote1 (protected) +- (id) preferredSource1 +{ + return self.syncSet.localPeer; // expected-warning {{type of property 'syncSet' does not match type of accessor 'syncSet'}} +} +@end + +@interface NSArray @end + +@interface NSMutableArray : NSArray +@end + +@interface Class1 +{ + NSMutableArray* pieces; + NSArray* first; +} + +@property (readonly) NSArray* pieces; // expected-warning {{type of property 'pieces' does not match type of accessor 'pieces'}} +@property (readonly) NSMutableArray* first; + +- (NSMutableArray*) pieces; // expected-note {{declared here}} // expected-note {{declared here}} +- (NSArray*) first; +@end + +@interface Class2 { + Class1* container; +} + +@end + +@implementation Class2 + +- (id) lastPiece +{ + return container.pieces; // expected-warning {{type of property 'pieces' does not match type of accessor 'pieces'}} +} + +- (id)firstPeice +{ + return container.first; +} +@end + diff --git a/clang/test/SemaObjC/property-user-setter.m b/clang/test/SemaObjC/property-user-setter.m new file mode 100644 index 0000000..7d4e544 --- /dev/null +++ b/clang/test/SemaObjC/property-user-setter.m @@ -0,0 +1,104 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface I0 +@property(readonly) int x; +@property(readonly) int y; +@property(readonly) int z; +-(void) setY: (int) y0; +@end + +@interface I0 (Cat0) +-(void) setX: (int) a0; +@end + +@implementation I0 +@dynamic x; +@dynamic y; +@dynamic z; +-(void) setY: (int) y0{} + +-(void) im0 { + self.x = 0; + self.y = 2; + self.z = 2; // expected-error {{assignment to readonly property}} +} +@end + +// Test when property is 'readonly' but it has a setter in +// its implementation only. +@interface I1 { +} +@property(readonly) int identifier; +@end + + +@implementation I1 +@dynamic identifier; +- (void)setIdentifier:(int)ident {} + +- (id)initWithIdentifier:(int)Arg { + self.identifier = 0; +} + +@end + + +// Also in a category implementation +@interface I1(CAT) +@property(readonly) int rprop; +@end + + +@implementation I1(CAT) +@dynamic rprop; +- (void)setRprop:(int)ident {} + +- (id)initWithIdentifier:(int)Arg { + self.rprop = 0; +} + +@end + +static int g_val; + +@interface Root ++ alloc; +- init; +@end + +@interface Subclass : Root +{ + int setterOnly; +} +- (void) setSetterOnly:(int)value; +@end + +@implementation Subclass +- (void) setSetterOnly:(int)value { + setterOnly = value; + g_val = setterOnly; +} +@end + +@interface C {} +// - (int)Foo; +- (void)setFoo:(int)value; +@end + +void g(int); // expected-note {{passing argument to parameter here}} + +void f(C *c) { + c.Foo = 17; // OK + g(c.Foo); // expected-error {{expected getter method not found on object of type 'C *'}} +} + + +void abort(void); +int main (void) { + Subclass *x = [[Subclass alloc] init]; + + x.setterOnly = 4; // OK + if (g_val != 4) + abort (); + return 0; +} diff --git a/clang/test/SemaObjC/property-weak.m b/clang/test/SemaObjC/property-weak.m new file mode 100644 index 0000000..a4397a6 --- /dev/null +++ b/clang/test/SemaObjC/property-weak.m @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s + +@interface foo +@property(nonatomic) int foo __attribute__((weak_import)); +@end diff --git a/clang/test/SemaObjC/property.m b/clang/test/SemaObjC/property.m new file mode 100644 index 0000000..a948741 --- /dev/null +++ b/clang/test/SemaObjC/property.m @@ -0,0 +1,83 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-fragile-abi -fsyntax-only -verify -Wno-objc-root-class %s + +@interface I +{ + int IVAR; // expected-note{{ivar is declared here}} + int name; +} +@property int d1; +@property id prop_id; // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}}, expected-warning {{default property attribute 'assign' not appropriate for non-gc object}} +@property int name; +@end + +@interface I(CAT) +@property int d1; // expected-note 2 {{property declared here}} +@end + +@implementation I +@synthesize d1; // expected-error {{synthesized property 'd1' must either be named the same as}} +@dynamic bad; // expected-error {{property implementation must have its declaration in interface 'I'}} +@synthesize prop_id; // expected-error {{synthesized property 'prop_id' must either be named the same}} // expected-note {{previous declaration is here}} +@synthesize prop_id = IVAR; // expected-error {{type of property 'prop_id' ('id') does not match type of ivar 'IVAR' ('int')}} // expected-error {{property 'prop_id' is already implemented}} +@synthesize name; // OK! property with same name as an accessible ivar of same name +@end + +@implementation I(CAT) // expected-warning {{property 'd1' requires method 'd1' to be defined }} \ + // expected-warning {{property 'd1' requires method 'setD1:' to be defined }} +@synthesize d1; // expected-error {{@synthesize not allowed in a category's implementation}} +@dynamic bad; // expected-error {{property implementation must have its declaration in the category 'CAT'}} +@end + +@implementation E // expected-warning {{cannot find interface declaration for 'E'}} +@dynamic d; // expected-error {{property implementation must have its declaration in interface 'E'}} +@end + +@implementation Q(MYCAT) // expected-error {{cannot find interface declaration for 'Q'}} +@dynamic d; // expected-error {{property implementation in a category with no category declaration}} +@end + +@interface Foo +@property double bar; +@end + +int func1() { + id foo; + double bar = [foo bar]; + return 0; +} + +// PR3932 +typedef id BYObjectIdentifier; +@interface Foo1 { + void *isa; +} +@property(copy) BYObjectIdentifier identifier; +@end + +@interface Foo2 +{ + int ivar; +} +@property int treeController; // expected-note {{property declared here}} +@property int ivar; // OK +@property int treeController; // expected-error {{property has a previous declaration}} +@end + +// rdar://10127639 +@synthesize window; // expected-error {{missing context for property implementation declaration}} + +// rdar://10408414 +Class test6_getClass(); +@interface Test6 +@end +@implementation Test6 ++ (float) globalValue { return 5.0f; } ++ (float) gv { return test6_getClass().globalValue; } +@end + +@interface Test7 +@property unsigned length; +@end +void test7(Test7 *t) { + char data[t.length] = {}; // expected-error {{variable-sized object may not be initialized}} +} diff --git a/clang/test/SemaObjC/props-on-prots.m b/clang/test/SemaObjC/props-on-prots.m new file mode 100644 index 0000000..c01e833 --- /dev/null +++ b/clang/test/SemaObjC/props-on-prots.m @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +typedef signed char BOOL; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; + +@protocol NSObject +- (BOOL) isEqual:(id) object; +@end + +@protocol NSCoding +- (void) encodeWithCoder:(NSCoder *) aCoder; +@end + +@interface NSObject < NSObject > {} @end + +typedef float CGFloat; + +@interface NSResponder:NSObject < NSCoding > {} @end + +@class XCElementView; + +typedef struct _XCElementInset {} XCElementInset; + +@protocol XCElementP < NSObject > +-(id) vertical; +@end + +@protocol XCElementDisplayDelegateP; +@protocol XCElementTabMarkerP; + +typedef NSObject < XCElementTabMarkerP > XCElementTabMarker; + +@protocol XCElementTabberP < XCElementP > +-(void) setMarker:(XCElementTabMarker *) marker; +@end + +typedef NSObject < XCElementTabberP > XCElementTabber; + +@protocol XCElementTabMarkerP < NSObject > +@property(nonatomic) +BOOL variableSized; +@end + +@protocol XCElementJustifierP < XCElementP > +-(void) setHJustification:(CGFloat) hJust; +@end + +typedef NSObject < XCElementJustifierP > XCElementJustifier; +@interface XCElementImp:NSObject < XCElementP > {} +@end + +@class XCElementImp; + +@interface XCElementTabberImp:XCElementImp < XCElementTabberP > { + XCElementTabMarker *_marker; +} +@end + +@implementation XCElementTabberImp +- (void) setMarker:(XCElementTabMarker *) marker { + if (_marker && _marker.variableSized) { + } +} +- (id)vertical { return self; } +- (BOOL)isEqual:x { return 1; } +@end diff --git a/clang/test/SemaObjC/protocol-archane.m b/clang/test/SemaObjC/protocol-archane.m new file mode 100644 index 0000000..49c9851 --- /dev/null +++ b/clang/test/SemaObjC/protocol-archane.m @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://5986251 + +@protocol SomeProtocol +- (void) bar; +@end + +void bar(); +void foo(id x) { + bar((short<SomeProtocol>)x); // expected-error {{expected ')'}} expected-note {{to match this '('}} + bar((<SomeProtocol>)x); // expected-warning {{protocol qualifiers without 'id' is archaic}} + + [(<SomeProtocol>)x bar]; // expected-warning {{protocol qualifiers without 'id' is archaic}} +} + +@protocol MyProtocol +- (void)doSomething; +@end + +@interface MyClass +- (void)m1:(id <MyProtocol> const)arg1; + +// FIXME: provide a better diagnostic (no typedef). +- (void)m2:(id <MyProtocol> short)arg1; // expected-error {{'short type-name' is invalid}} +@end + +typedef int NotAnObjCObjectType; + +// GCC doesn't diagnose this. +NotAnObjCObjectType <SomeProtocol> *obj; // expected-error {{invalid protocol qualifiers on non-ObjC type}} + +typedef struct objc_class *Class; + +Class <SomeProtocol> UnfortunateGCCExtension; + +// rdar://10238337 +@protocol Broken @end +@interface Crash @end +@implementation Crash +- (void)crashWith:(<Broken>)a { // expected-warning {{protocol qualifiers without 'id' is archaic}} +} +@end diff --git a/clang/test/SemaObjC/protocol-attribute.m b/clang/test/SemaObjC/protocol-attribute.m new file mode 100644 index 0000000..178774c --- /dev/null +++ b/clang/test/SemaObjC/protocol-attribute.m @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +__attribute ((unavailable)) +@protocol FwProto; // expected-note{{marked unavailable}} + +Class <FwProto> cFw = 0; // expected-error {{'FwProto' is unavailable}} + + +__attribute ((deprecated)) @protocol MyProto1 +@end + +@protocol Proto2 <MyProto1> // expected-warning {{'MyProto1' is deprecated}} ++method2; +@end + + +@interface MyClass1 <MyProto1> // expected-warning {{'MyProto1' is deprecated}} +{ + Class isa; +} +@end + +@interface Derived : MyClass1 <MyProto1> // expected-warning {{'MyProto1' is deprecated}} +{ + id <MyProto1> ivar; // expected-warning {{'MyProto1' is deprecated}} +} +@end + +@interface MyClass1 (Category) <MyProto1, Proto2> // expected-warning {{'MyProto1' is deprecated}} +@end + + + +Class <MyProto1> clsP1 = 0; // expected-warning {{'MyProto1' is deprecated}} + +@protocol FwProto @end // expected-note{{marked unavailable}} + +@interface MyClass2 <FwProto> // expected-error {{'FwProto' is unavailable}} +@end + +__attribute ((unavailable)) __attribute ((deprecated)) @protocol XProto; // expected-note{{marked unavailable}} + +id <XProto> idX = 0; // expected-error {{'XProto' is unavailable}} + +int main () +{ + MyClass1 <MyProto1> *p1; // expected-warning {{'MyProto1' is deprecated}} +} + diff --git a/clang/test/SemaObjC/protocol-expr-1.m b/clang/test/SemaObjC/protocol-expr-1.m new file mode 100644 index 0000000..fe01d1d --- /dev/null +++ b/clang/test/SemaObjC/protocol-expr-1.m @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@protocol fproto; + +@protocol p1 +@end + +@class cl; + +int main() +{ + Protocol *proto = @protocol(p1); + Protocol *fproto = @protocol(fproto); +} + diff --git a/clang/test/SemaObjC/protocol-expr-neg-1.m b/clang/test/SemaObjC/protocol-expr-neg-1.m new file mode 100644 index 0000000..58ac8c0 --- /dev/null +++ b/clang/test/SemaObjC/protocol-expr-neg-1.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@class Protocol; + +@protocol fproto; + +@protocol p1 +@end + +@class cl; + +int main() +{ + Protocol *proto = @protocol(p1); + Protocol *fproto = @protocol(fproto); + Protocol *pp = @protocol(i); // expected-error {{cannot find protocol declaration for 'i'}} + Protocol *p1p = @protocol(cl); // expected-error {{cannot find protocol declaration for 'cl'}} +} + diff --git a/clang/test/SemaObjC/protocol-id-test-1.m b/clang/test/SemaObjC/protocol-id-test-1.m new file mode 100644 index 0000000..19a4432 --- /dev/null +++ b/clang/test/SemaObjC/protocol-id-test-1.m @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -verify -Wno-objc-root-class %s + +@interface FF +- (void) Meth; +@end + +@protocol P +@end + +@interface INTF<P> +- (void)IMeth; +@end + +@implementation INTF +- (void)IMeth {INTF<P> *pi; [pi Meth]; } // expected-warning {{method '-Meth' not found (return type defaults to 'id')}} +@end diff --git a/clang/test/SemaObjC/protocol-id-test-2.m b/clang/test/SemaObjC/protocol-id-test-2.m new file mode 100644 index 0000000..6bd2fee --- /dev/null +++ b/clang/test/SemaObjC/protocol-id-test-2.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -verify -Wno-objc-root-class %s + +@protocol P +@end + +@interface INTF<P> +- (void)IMeth; +@end + +@implementation INTF +- (void)IMeth { [(id<P>)self Meth]; } // expected-warning {{method '-Meth' not found (return type defaults to 'id')}} +@end diff --git a/clang/test/SemaObjC/protocol-id-test-3.m b/clang/test/SemaObjC/protocol-id-test-3.m new file mode 100644 index 0000000..624bab0 --- /dev/null +++ b/clang/test/SemaObjC/protocol-id-test-3.m @@ -0,0 +1,94 @@ +// RUN: %clang_cc1 -pedantic -fsyntax-only -verify %s + +@protocol MyProto1 +@end + +@protocol MyProto2 +@end + +@interface INTF @end + +id<MyProto1> Func(INTF <MyProto1, MyProto2> *p2) // expected-note 2{{passing argument to parameter 'p2' here}} +{ + return p2; +} + + + + + id<MyProto1> Gunc(id <MyProto1, MyProto2>p2) +{ + return p2; +} + + + id<MyProto1> Gunc1(id <MyProto1, MyProto2>p2) +{ + return p2; +} + +id<MyProto1, MyProto2> Gunc2(id <MyProto1>p2) +{ + Func(p2); // expected-warning {{passing 'id<MyProto1>' to parameter of incompatible type 'INTF<MyProto1,MyProto2> *'}} + return p2; // expected-warning {{returning 'id<MyProto1>' from a function with incompatible result type 'id<MyProto1,MyProto2>'}} +} + + + +id<MyProto1> Gunc3(id <MyProto2>p2) +{ + return p2; // expected-warning {{returning 'id<MyProto2>' from a function with incompatible result type 'id<MyProto1>'}} +} + + +id<MyProto1, MyProto2> Gunc4(id <MyProto2, MyProto1>p2) +{ + return p2; +} + + + +INTF<MyProto1> * Hunc(id <MyProto1, MyProto2>p2) +{ + return p2; +} + + +INTF<MyProto1> * Hunc1(id <MyProto1, MyProto2>p2) +{ + return p2; +} + +INTF<MyProto1, MyProto2> * Hunc2(id <MyProto1>p2) +{ + Func(p2); // expected-warning {{passing 'id<MyProto1>' to parameter of incompatible type 'INTF<MyProto1,MyProto2> *'}} + return p2; // expected-warning {{returning 'id<MyProto1>' from a function with incompatible result type 'INTF<MyProto1,MyProto2> *'}} +} + +INTF<MyProto1> * Hunc3(id <MyProto2>p2) +{ + return p2; // expected-warning {{returning 'id<MyProto2>' from a function with incompatible result type 'INTF<MyProto1> *'}} +} + + +INTF<MyProto1, MyProto2> * Hunc4(id <MyProto2, MyProto1>p2) +{ + return p2; +} + +id Iunc(id <MyProto1, MyProto2>p2) +{ + return p2; +} + + +id<MyProto1> Iunc1(id p2) +{ + return p2; +} + +id<MyProto1, MyProto2> Iunc2(id p2) +{ + Iunc(p2); + return p2; +} diff --git a/clang/test/SemaObjC/protocol-implementation-inherited.m b/clang/test/SemaObjC/protocol-implementation-inherited.m new file mode 100644 index 0000000..c333bb5 --- /dev/null +++ b/clang/test/SemaObjC/protocol-implementation-inherited.m @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@protocol P0 +-bar; +@end + +@interface A <P0> +@end + +// Interface conforms to inherited protocol + +@interface B0 : A <P0> +@end + +@implementation B0 +@end + +// Interface conforms to a protocol which extends another. The other +// protocol is inherited, and extended methods are implemented. + +@protocol P1 <P0> +-foo; +@end + +@interface B1 : A <P1> +@end + +@implementation B1 +-foo { return 0; }; +@end + +// Interface conforms to a protocol whose methods are provided by an +// alternate inherited protocol. + +@protocol P2 +-bar; +@end + +@interface B2 : A <P2> +@end + +@implementation B2 +@end + +// Interface conforms to a protocol whose methods are provided by a base class. + +@interface A1 +-bar; +@end + +@interface B3 : A1 <P2> +@end + +@implementation B3 +@end + diff --git a/clang/test/SemaObjC/protocol-implementing-class-methods.m b/clang/test/SemaObjC/protocol-implementing-class-methods.m new file mode 100644 index 0000000..503eef1 --- /dev/null +++ b/clang/test/SemaObjC/protocol-implementing-class-methods.m @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://7020493 + +@protocol P1 +@optional +- (int) PMeth; +@required +- (void) : (double) arg; // expected-note {{method ':' declared here}} +@end + +@interface NSImage <P1> +- (void) initialize; // expected-note {{method 'initialize' declared here}} +@end + +@interface NSImage (AirPortUI) +- (void) initialize; +@end + +@interface NSImage() +- (void) CEMeth; // expected-note {{method 'CEMeth' declared here}} +@end + +@implementation NSImage (AirPortUI) +- (void) initialize {NSImage *p=0; [p initialize]; } // expected-warning {{category is implementing a method which will also be implemented by its primary class}} +- (int) PMeth{ return 0; } +- (void) : (double) arg{}; // expected-warning {{category is implementing a method which will also be implemented by its primary class}} +- (void) CEMeth {}; // expected-warning {{category is implementing a method which will also be implemented by its primary class}} +@end + +// rdar://10014946 +typedef char BOOL; +@interface I +{ + BOOL allowsDeleting; +} +@property (nonatomic, assign, readwrite) BOOL allowsDeleting; +@end + +@implementation I(CAT) +- (BOOL) allowsDeleting { return 1; } +@end diff --git a/clang/test/SemaObjC/protocol-lookup-2.m b/clang/test/SemaObjC/protocol-lookup-2.m new file mode 100644 index 0000000..bf07523 --- /dev/null +++ b/clang/test/SemaObjC/protocol-lookup-2.m @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +@interface NSObject @end + +@protocol ProtocolA + ++ (id)classMethod; +- (id)instanceMethod; + +@end + +@protocol ProtocolB <ProtocolA> + +@end + +@interface Foo : NSObject <ProtocolB> + +@end + +@interface SubFoo : Foo + +@end + +@implementation SubFoo + ++ (id)method { + return [super classMethod]; +} + +- (id)method { + return [super instanceMethod]; +} + +@end diff --git a/clang/test/SemaObjC/protocol-lookup.m b/clang/test/SemaObjC/protocol-lookup.m new file mode 100644 index 0000000..ed3fbe0 --- /dev/null +++ b/clang/test/SemaObjC/protocol-lookup.m @@ -0,0 +1,51 @@ +// 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 + diff --git a/clang/test/SemaObjC/protocol-qualified-class-unsupported.m b/clang/test/SemaObjC/protocol-qualified-class-unsupported.m new file mode 100644 index 0000000..4bf6b28 --- /dev/null +++ b/clang/test/SemaObjC/protocol-qualified-class-unsupported.m @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#include <stddef.h> + +typedef struct objc_class *Class; +typedef struct objc_object { + Class isa; +} *id; +id objc_getClass(const char *s); + +@interface Object ++ self; +@end + +@protocol Func ++ (void) class_func0; +- (void) instance_func0; +@end + +@interface Derived: Object <Func> +@end + +@interface Derived2: Object <Func> +@end + +static void doSomething(Class <Func> unsupportedObjectType) { + [unsupportedObjectType class_func0]; +} + +static void doSomethingElse(id <Func> pleaseConvertToThisType) { + [pleaseConvertToThisType class_func0]; +} + +int main(int argv, char *argc[]) { + doSomething([Derived self]); + doSomething([Derived2 self]); + doSomethingElse([Derived self]); + doSomethingElse([Derived2 self]); +} + diff --git a/clang/test/SemaObjC/protocol-typecheck.m b/clang/test/SemaObjC/protocol-typecheck.m new file mode 100644 index 0000000..4eb1b26 --- /dev/null +++ b/clang/test/SemaObjC/protocol-typecheck.m @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface NSObject @end +@protocol XCElementP @end +@protocol XCElementSpacerP <XCElementP> @end + +@protocol PWhatever @end + +@interface XX + +- (void)setFlexElement:(NSObject <PWhatever, XCElementP> *)flexer; +- (void)setFlexElement2:(NSObject <PWhatever, XCElementSpacerP> *)flexer; // expected-note{{passing argument to parameter 'flexer' here}} + +@end + +void func() { + NSObject <PWhatever, XCElementSpacerP> * flexer; + NSObject <PWhatever, XCElementP> * flexer2; + XX *obj; + [obj setFlexElement:flexer]; + // FIXME: GCC provides the following diagnostic (which is much better): + // protocol-typecheck.m:21: warning: class 'NSObject <PWhatever, XCElementP>' does not implement the 'XCElementSpacerP' protocol + [obj setFlexElement2:flexer2]; // expected-warning{{incompatible pointer types sending 'NSObject<PWhatever,XCElementP> *' to parameter of type 'NSObject<PWhatever,XCElementSpacerP> *'}} +} + diff --git a/clang/test/SemaObjC/protocol-warn.m b/clang/test/SemaObjC/protocol-warn.m new file mode 100644 index 0000000..2d04238 --- /dev/null +++ b/clang/test/SemaObjC/protocol-warn.m @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// radar 7638810 + +@protocol NSObject @end + +@interface NSObject <NSObject> @end + +@interface UIResponder : NSObject +@end + +@implementation UIResponder +@end + +@interface UIView : UIResponder +@end + +@implementation UIView +@end + +@interface UIWebTiledView : UIView +@end + +@implementation UIWebTiledView +@end + +@interface UIWebDocumentView : UIWebTiledView +@end + +@implementation UIWebDocumentView +@end + +@interface UIWebBrowserView : UIWebDocumentView +@end + +@implementation UIWebBrowserView +@end + +@interface UIPDFView : UIView +@end + +@implementation UIPDFView +@end + +@interface UIWebPDFView : UIPDFView +@end + +@implementation UIWebPDFView +@end + +UIWebPDFView *getView() +{ + UIWebBrowserView *browserView; + UIWebPDFView *pdfView; + return pdfView ? pdfView : browserView; // expected-warning {{incompatible pointer types returning 'UIView<NSObject> *' from a function with result type 'UIWebPDFView *'}} +} diff --git a/clang/test/SemaObjC/protocols.m b/clang/test/SemaObjC/protocols.m new file mode 100644 index 0000000..ca38f20 --- /dev/null +++ b/clang/test/SemaObjC/protocols.m @@ -0,0 +1,67 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface INTF1 +@required // expected-error {{directive may only be specified in protocols only}} +- (int) FooBar; +- (int) FooBar1; +- (int) FooBar2; +@optional // expected-error {{directive may only be specified in protocols only}} ++ (int) C; + +- (int)I; +@end + +@protocol p1,p2,p3; + +@protocol p1; + +@protocol PROTO1 +@required +- (int) FooBar; +@optional +- (void) MyMethod1; ++ (int) S; +@end + + +@protocol PROTO2<p1> +@end + +@protocol p1 @end + +@protocol PROTO<p1> // expected-note {{previous definition is here}} +@end + +@protocol PROTO<p1> // expected-warning {{duplicate protocol definition of 'PROTO'}} +@end + +@protocol PROTO3<p1, p1> +@end + +@protocol p2 <p1> +@end + +@protocol PROTO4 <p1, p2, PROTO, PROTO3, p3> +@end + + +// rdar://6771034 +@protocol XX; +@protocol YY <XX> // Use of declaration of XX here should not cause a warning. +- zz; +@end + + +// Detect circular dependencies. +@protocol B; +@protocol C < B > // expected-note{{previous definition is here}} +@end +@protocol A < C > +@end +@protocol B < A > // expected-error{{protocol has circular dependency}} +@end + +@protocol P +- (int)test:(int)param, ..; // expected-warning{{type specifier missing}} \ + // expected-error{{expected ';' after method prototype}} +@end diff --git a/clang/test/SemaObjC/provisional-ivar-lookup.m b/clang/test/SemaObjC/provisional-ivar-lookup.m new file mode 100644 index 0000000..2ec23a5 --- /dev/null +++ b/clang/test/SemaObjC/provisional-ivar-lookup.m @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-default-synthesize-properties -verify -Wno-objc-root-class %s + +// rdar:// 8565343 +@interface Foo { +@private + int _foo; + int _foo2; +} +@property (readwrite, nonatomic) int foo, foo1, foo2, foo3; +@property (readwrite, nonatomic) int PROP; +@end + +@implementation Foo + +@synthesize foo = _foo; +@synthesize foo1; + +- (void)setFoo:(int)value { + _foo = foo; // expected-error {{use of undeclared identifier 'foo'}} +} + +- (void)setFoo1:(int)value { + _foo = foo1; // OK +} + +- (void)setFoo2:(int)value { + _foo = foo2; // expected-error {{use of undeclared identifier 'foo2'}} +} + +- (void)setFoo3:(int)value { + _foo = foo3; // OK +} + +@synthesize foo2 = _foo2; +@synthesize foo3; + +@synthesize PROP=PROP; +- (void)setPROP:(int)value { + PROP = PROP; // OK +} + +@end + diff --git a/clang/test/SemaObjC/qualified-protocol-method-conflicts.m b/clang/test/SemaObjC/qualified-protocol-method-conflicts.m new file mode 100644 index 0000000..d1d5612 --- /dev/null +++ b/clang/test/SemaObjC/qualified-protocol-method-conflicts.m @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -Woverriding-method-mismatch -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://6191214 + +@protocol Xint +-(void) setX: (int) arg0; // expected-note {{previous declaration is here}} ++(int) C; // expected-note {{previous declaration is here}} +@end + +@protocol Xfloat +-(void) setX: (float) arg0; // expected-note 2 {{previous declaration is here}} ++(float) C; // expected-note 2 {{previous declaration is here}} +@end + +@interface A <Xint, Xfloat> +@end + +@implementation A +-(void) setX: (int) arg0 { } // expected-warning {{conflicting parameter types in declaration of 'setX:': 'float' vs 'int'}} ++(int) C {return 0; } // expected-warning {{conflicting return type in declaration of 'C': 'float' vs 'int'}} +@end + +@interface B <Xfloat, Xint> +@end + +@implementation B +-(void) setX: (float) arg0 { } // expected-warning {{conflicting parameter types in declaration of 'setX:': 'int' vs 'float'}} ++ (float) C {return 0.0; } // expected-warning {{conflicting return type in declaration of 'C': 'int' vs 'float'}} +@end + +@protocol Xint_float<Xint, Xfloat> +@end + +@interface C<Xint_float> +@end + +@implementation C +-(void) setX: (int) arg0 { } // expected-warning {{conflicting parameter types in declaration of 'setX:': 'float' vs 'int'}} ++ (int) C {return 0;} // expected-warning {{conflicting return type in declaration of 'C': 'float' vs 'int'}} +@end diff --git a/clang/test/SemaObjC/rdar6248119.m b/clang/test/SemaObjC/rdar6248119.m new file mode 100644 index 0000000..046992c --- /dev/null +++ b/clang/test/SemaObjC/rdar6248119.m @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only %s -verify -fobjc-exceptions +// Test case for: +// <rdar://problem/6248119> @finally doesn't introduce a new scope + +void f0() { + int i; + @try { + } @finally { + int i = 0; + } +} + +void f1() { + int i; + @try { + int i =0; + } @finally { + } +} + +void f2() { + int i; + @try { + } @catch(id e) { + int i = 0; + } +} diff --git a/clang/test/SemaObjC/rdr-6211479-array-property.m b/clang/test/SemaObjC/rdr-6211479-array-property.m new file mode 100644 index 0000000..39c056c --- /dev/null +++ b/clang/test/SemaObjC/rdr-6211479-array-property.m @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// <rdar://problem/6211479> + +typedef int T[2]; + +@interface A +@property(assign) T p2; // expected-error {{property cannot have array or function type 'T' (aka 'int [2]')}} +@end diff --git a/clang/test/SemaObjC/receiver-forward-class.m b/clang/test/SemaObjC/receiver-forward-class.m new file mode 100644 index 0000000..cefb5d7 --- /dev/null +++ b/clang/test/SemaObjC/receiver-forward-class.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -Wreceiver-forward-class -verify %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -Wreceiver-forward-class -verify %s +// rdar://10686120 + +@class A; // expected-note {{forward declaration of class here}} + +@interface B +-(int) width; // expected-note {{using}} +@end +@interface C +-(float) width; // expected-note {{also found}} +@end + +int f0(A *x) { + return [x width]; // expected-warning {{receiver type 'A' for instance message is a forward declaration}} \ + // expected-warning {{multiple methods named 'width' found}} \ + // expected-note {{receiver is treated with 'id' type for purpose of method lookup}} +} + diff --git a/clang/test/SemaObjC/related-result-type-inference.m b/clang/test/SemaObjC/related-result-type-inference.m new file mode 100644 index 0000000..124767c --- /dev/null +++ b/clang/test/SemaObjC/related-result-type-inference.m @@ -0,0 +1,180 @@ +// RUN: %clang_cc1 -verify -Wno-objc-root-class %s + +@interface Unrelated +@end + +@interface NSObject ++ (id)new; ++ (id)alloc; +- (NSObject *)init; + +- (id)retain; // expected-note{{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 *'}} +} + +@implementation NSBlah ++ (Unrelated *)newUnrelated { + return (Unrelated *)0; +} +@end + +@implementation NSBlah (Cat) ++ (Unrelated *)newUnrelated2 { + return (Unrelated *)0; +} +@end + +@interface A +- (id)initBlah; // expected-note 2{{overridden method is part of the 'init' method family}} +@end + +@interface B : A +- (Unrelated *)initBlah; // expected-warning{{method is expected to return an instance of its class type 'B', but is declared to return 'Unrelated *'}} +@end + +@interface C : A +@end + +@implementation C +- (Unrelated *)initBlah { // expected-warning{{method is expected to return an instance of its class type 'C', but is declared to return 'Unrelated *'}} + return (Unrelated *)0; +} +@end + +@interface D ++ (id)newBlarg; // expected-note{{overridden method is part of the 'new' method family}} +@end + +@interface D () ++ alloc; // expected-note{{overridden method is part of the 'alloc' method family}} +@end + +@implementation D ++ (Unrelated *)newBlarg { // expected-warning{{method is expected to return an instance of its class type 'D', but is declared to return 'Unrelated *'}} + return (Unrelated *)0; +} + ++ (Unrelated *)alloc { // expected-warning{{method is expected to return an instance of its class type 'D', but is declared to return 'Unrelated *'}} + return (Unrelated *)0; +} +@end + +@protocol P1 +- (id)initBlah; // expected-note{{overridden method is part of the 'init' method family}} +- (int)initBlarg; +@end + +@protocol P2 <P1> +- (int)initBlah; // expected-warning{{protocol method is expected to return an instance of the implementing class, but is declared to return 'int'}} +- (int)initBlarg; +- (int)initBlech; +@end + +@interface E +- init; +@end + +@implementation E +- init { + return self; +} +@end + +@protocol P3 ++ (NSString *)newString; +@end + +@interface F<P3> +@end + +@implementation F ++ (NSString *)newString { return @"blah"; } +@end + +// <rdar://problem/9340699> +@interface G +- (id)_ABC_init __attribute__((objc_method_family(init))); // expected-note {{method '_ABC_init' declared here}} +@end + +@interface G (Additions) +- (id)_ABC_init2 __attribute__((objc_method_family(init))); +@end + +@implementation G (Additions) +- (id)_ABC_init { // expected-warning {{category is implementing a method which will also be implemented by its primary class}} + return 0; +} +- (id)_ABC_init2 { + return 0; +} +- (id)_ABC_init3 { + return 0; +} +@end + +// PR12384 +@interface Fail @end +@protocol X @end +@implementation Fail +- (id<X>) initWithX +{ + return (id)self; // expected-warning {{returning 'Fail *' from a function with incompatible result type 'id<X>'}} +} +@end diff --git a/clang/test/SemaObjC/restrict-id-type.m b/clang/test/SemaObjC/restrict-id-type.m new file mode 100644 index 0000000..b24fcb0 --- /dev/null +++ b/clang/test/SemaObjC/restrict-id-type.m @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -std=gnu99 -fsyntax-only -verify %s + +void f0(restrict id a0) {} + +void f1(restrict id *a0) {} + +void f2(restrict Class a0) {} + +void f3(restrict Class *a0) {} diff --git a/clang/test/SemaObjC/return.m b/clang/test/SemaObjC/return.m new file mode 100644 index 0000000..f69d41e --- /dev/null +++ b/clang/test/SemaObjC/return.m @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wmissing-noreturn -fobjc-exceptions -Wno-objc-root-class %s + +int test1() { + id a; + @throw a; +} + +// PR5286 +void test2(int a) { + while (1) { + if (a) + return; + } +} + +// PR5286 +void test3(int a) { // expected-warning {{function 'test3' could be declared with attribute 'noreturn'}} + while (1) { + if (a) + @throw (id)0; + } +} + +// <rdar://problem/4289832> - This code always returns, we should not +// issue a noreturn warning. +@class NSException; +@class NSString; +NSString *rdar_4289832() { // no-warning + @try + { + return @"a"; + } + @catch(NSException *exception) + { + return @"b"; + } + @finally + { + } +} + +void exit(int) __attribute__((noreturn)); +@interface rdar10098695 +@end + +@implementation rdar10098695 +- (void)method { // expected-warning{{method 'method' could be declared with attribute 'noreturn'}} + exit(1); +} +@end diff --git a/clang/test/SemaObjC/scope-check.m b/clang/test/SemaObjC/scope-check.m new file mode 100644 index 0000000..e19ba47 --- /dev/null +++ b/clang/test/SemaObjC/scope-check.m @@ -0,0 +1,103 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fobjc-exceptions -Wno-objc-root-class %s + +@class A, B, C; + +void test1() { + goto L; // expected-error{{goto into protected scope}} + goto L2; // expected-error{{goto into protected scope}} + goto L3; // expected-error{{goto into protected scope}} + @try { // expected-note {{jump bypasses initialization of @try block}} +L: ; + } @catch (A *x) { // expected-note {{jump bypasses initialization of @catch block}} +L2: ; + } @catch (B *x) { + } @catch (C *c) { + } @finally {// expected-note {{jump bypasses initialization of @finally block}} +L3: ; + } + + @try { + goto L4; // expected-error{{goto into protected scope}} + goto L5; // expected-error{{goto into protected scope}} + } @catch (C *c) { // expected-note {{jump bypasses initialization of @catch block}} + L5: ; + goto L6; // expected-error{{goto into protected scope}} + } @catch (B *c) { // expected-note {{jump bypasses initialization of @catch block}} + L6: ; + } @finally { // expected-note {{jump bypasses initialization of @finally block}} + L4: ; + } + + + @try { // expected-note 2 {{jump bypasses initialization of @try block}} + L7: ; + } @catch (C *c) { + goto L7; // expected-error{{goto into protected scope}} + } @finally { + goto L7; // expected-error{{goto into protected scope}} + } + + goto L8; // expected-error{{goto into protected scope}} + @try { + } @catch (A *c) { + } @catch (B *c) { + } @catch (C *c) { // expected-note {{jump bypasses initialization of @catch block}} + L8: ; + } + + // rdar://6810106 + id X; + goto L9; // expected-error{{goto into protected scope}} + goto L10; // ok + @synchronized // expected-note {{jump bypasses initialization of @synchronized block}} + ( ({ L10: ; X; })) { + L9: + ; + } +} + +void test2(int a) { + if (a) goto L0; + @try {} @finally {} + L0: + return; +} + +// rdar://6803963 +void test3() { + @try { + goto blargh; + blargh: ; + } @catch (...) {} +} + +@interface Greeter ++ (void) hello; +@end + +@implementation Greeter ++ (void) hello { + + @try { + goto blargh; // expected-error {{goto into protected scope}} + } @catch (...) { // expected-note {{jump bypasses initialization of @catch block}} + blargh: ; + } +} + ++ (void)meth2 { + int n; void *P; + goto L0; // expected-error {{goto into protected scope}} + typedef int A[n]; // expected-note {{jump bypasses initialization of VLA typedef}} + L0: + + goto L1; // expected-error {{goto into protected scope}} + A b, c[10]; // expected-note 2 {{jump bypasses initialization of variable length array}} + L1: + goto L2; // expected-error {{goto into protected scope}} + A d[n]; // expected-note {{jump bypasses initialization of variable length array}} + L2: + return; +} + +@end diff --git a/clang/test/SemaObjC/selector-1.m b/clang/test/SemaObjC/selector-1.m new file mode 100644 index 0000000..16d44cb --- /dev/null +++ b/clang/test/SemaObjC/selector-1.m @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -verify %s + +@interface I +- (id) compare: (char) arg1; +- length; +@end + +@interface J +- (id) compare: (id) arg1; +@end + +SEL func() +{ + return @selector(compare:); // Non warning on multiple selector found. +} + +int main() { + SEL s = @selector(retain); + SEL s1 = @selector(meth1:); + SEL s2 = @selector(retainArgument::); + SEL s3 = @selector(retainArgument:::::); + SEL s4 = @selector(retainArgument:with:); + SEL s5 = @selector(meth1:with:with:); + SEL s6 = @selector(getEnum:enum:bool:); + SEL s7 = @selector(char:float:double:unsigned:short:long:); + + SEL s9 = @selector(:enum:bool:); +} diff --git a/clang/test/SemaObjC/selector-2.m b/clang/test/SemaObjC/selector-2.m new file mode 100644 index 0000000..fb75369 --- /dev/null +++ b/clang/test/SemaObjC/selector-2.m @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -Wselector -verify %s +// rdar://8851684 +@interface I +- length; +@end + +static inline SEL IsEmpty() { + return @selector(length); +} + +int main (int argc, const char * argv[]) { + return 0; +} + diff --git a/clang/test/SemaObjC/selector-3.m b/clang/test/SemaObjC/selector-3.m new file mode 100644 index 0000000..4c12a93 --- /dev/null +++ b/clang/test/SemaObjC/selector-3.m @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -fsyntax-only -Wselector -verify -Wno-objc-root-class %s +// rdar://8851684 + +@interface Foo +- (void) foo; +- (void) bar; +@end + +@implementation Foo +- (void) bar +{ +} + +- (void) foo +{ + SEL a,b,c; + a = @selector(b1ar); // expected-warning {{unimplemented selector 'b1ar'}} + b = @selector(bar); +} +@end + +@interface I +- length; +@end + +SEL func() +{ + return @selector(length); // expected-warning {{unimplemented selector 'length'}} +} + +// rdar://9545564 +@class MSPauseManager; + +@protocol MSPauseManagerDelegate +@optional +- (void)pauseManagerDidPause:(MSPauseManager *)manager; +- (int)respondsToSelector:(SEL)aSelector; +@end + +@interface MSPauseManager +{ + id<MSPauseManagerDelegate> _delegate; +} +@end + + +@implementation MSPauseManager +- (id) Meth { + if ([_delegate respondsToSelector:@selector(pauseManagerDidPause:)]) + return 0; + return 0; +} +@end + diff --git a/clang/test/SemaObjC/selector-error.m b/clang/test/SemaObjC/selector-error.m new file mode 100644 index 0000000..f59dec8 --- /dev/null +++ b/clang/test/SemaObjC/selector-error.m @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface Foo +- (char*) foo; +- (void) bar; +@end + +@implementation Foo +- (void) bar +{ +} + +- (char*) foo +{ + char* a,b,c; + a = (char*)@selector(bar); // expected-error {{cannot type cast @selector expression}} + return (char*)@selector(bar); // expected-error {{cannot type cast @selector expression}} +} +@end + diff --git a/clang/test/SemaObjC/selector-overload.m b/clang/test/SemaObjC/selector-overload.m new file mode 100644 index 0000000..53ba6f7 --- /dev/null +++ b/clang/test/SemaObjC/selector-overload.m @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 %s -fsyntax-only + +@interface NSObject ++ alloc; +- init; +@end + +struct D { + double d; +}; + +@interface Foo : NSObject + +- method:(int)a; +- method:(int)a; + +@end + +@interface Bar : NSObject + +- method:(void *)a; + +@end + +@interface Car : NSObject + +- method:(struct D)a; + +@end + +@interface Zar : NSObject + +- method:(float)a; + +@end + +@interface Rar : NSObject + +- method:(float)a; + +@end + +int main() { + id xx = [[Car alloc] init]; // expected-warning {{incompatible types assigning 'int' to 'id'}} + + [xx method:4]; +} diff --git a/clang/test/SemaObjC/self-assign.m b/clang/test/SemaObjC/self-assign.m new file mode 100644 index 0000000..e0f5f43 --- /dev/null +++ b/clang/test/SemaObjC/self-assign.m @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +@interface A +@end + +@implementation A +- (id):(int)x :(int)y { + int z; + // <rdar://problem/8939352> + if (self = [self :x :y]) {} // expected-warning{{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '==' to turn this assignment into an equality comparison}} \ + // expected-note{{place parentheses around the assignment to silence this warning}} + return self; +} +@end diff --git a/clang/test/SemaObjC/self-declared-in-block.m b/clang/test/SemaObjC/self-declared-in-block.m new file mode 100644 index 0000000..40a0331 --- /dev/null +++ b/clang/test/SemaObjC/self-declared-in-block.m @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin10 -fblocks -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -triple x86_64-apple-darwin10 -fblocks -verify -Wno-objc-root-class %s +// rdar://9154582 + +@interface Blocky @end + +@implementation Blocky { + int _a; +} +- (int)doAThing { + ^{ + char self; + return _a; + }(); + return _a; +} + +@end + + +// rdar://9284603 +@interface ShadowSelf +{ + int _anIvar; +} +@end + +@interface C { + int _cIvar; +} +@end + +@implementation ShadowSelf +- (void)doSomething { + __typeof(self) newSelf = self; + { + __typeof(self) self = newSelf; + (void)_anIvar; + } + { + C* self; + (void) _anIvar; + } +} +- (void)doAThing { + ^{ + id self; + (void)_anIvar; + }(); +} +@end + diff --git a/clang/test/SemaObjC/self-in-function.m b/clang/test/SemaObjC/self-in-function.m new file mode 100644 index 0000000..9027a94 --- /dev/null +++ b/clang/test/SemaObjC/self-in-function.m @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s +// rdar://9181463 + +typedef struct objc_class *Class; + +typedef struct objc_object { + Class isa; +} *id; + +@interface NSObject ++ (id) alloc; +@end + + +void foo(Class self) { + [self alloc]; + (^() { + [self alloc]; + })(); +} + +void bar(Class self) { + Class y = self; + [y alloc]; +} + diff --git a/clang/test/SemaObjC/setter-dotsyntax.m b/clang/test/SemaObjC/setter-dotsyntax.m new file mode 100644 index 0000000..e0b51e8 --- /dev/null +++ b/clang/test/SemaObjC/setter-dotsyntax.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://8528170 + +@interface NSObject @end + +@protocol MyProtocol +- (int) level; +- (void) setLevel:(int)inLevel; +@end + +@interface MyClass : NSObject <MyProtocol> +@end + +int main () +{ + id<MyProtocol> c; + c.level = 10; + return 0; +} diff --git a/clang/test/SemaObjC/severe-syntax-error.m b/clang/test/SemaObjC/severe-syntax-error.m new file mode 100644 index 0000000..8c59151 --- /dev/null +++ b/clang/test/SemaObjC/severe-syntax-error.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://10633434 + +@interface testClass +@end + +@class NSArray; + +@implementation testClass + +static NSArray* prefixArray[] = @"BEGIN:", @"END:", @"VERSION:", @"N:", @"FN:", @"TEL;", @"TEL:", nil; // expected-error {{array initializer must be an initializer list}} \ + // expected-error {{expected identifier or '('}} \ + // expected-error {{expected ';' after top level declarator}} + +static NSString* prefixArray1[] = @"BEGIN:", @"END:", @"VERSION:", @"N:", @"FN:", @"TEL;", @"TEL:", nil; // expected-error {{unknown type name 'NSString'}} \ + // expected-error {{expected identifier or '('}} \ + // expected-error {{expected ';' after top level declarator}} + +static char* cArray[] = "BEGIN:", "END"; // expected-error {{array initializer must be an initializer list}} \ + // expected-error {{expected identifier or '('}} \ + // expected-error {{expected ';' after top level declarator}} + +@end diff --git a/clang/test/SemaObjC/sizeof-interface.m b/clang/test/SemaObjC/sizeof-interface.m new file mode 100644 index 0000000..7304b6c --- /dev/null +++ b/clang/test/SemaObjC/sizeof-interface.m @@ -0,0 +1,90 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -Wno-objc-root-class %s + +@class I0; // expected-note 2{{forward declaration of class here}} + +// rdar://6811884 +int g0 = sizeof(I0); // expected-error{{invalid application of 'sizeof' to an incomplete type 'I0'}} + +// rdar://6821047 +void *g3(I0 *P) { + P = P+5; // expected-error {{arithmetic on a pointer to an incomplete type 'I0'}} + + return &P[4]; // expected-error{{expected method to read array element not found on object of type 'I0 *'}} +} + + + +@interface I0 { +@public + char x[4]; +} + +@property int p0; +@end + +// size == 4 +int g1[ sizeof(I0) // expected-error {{invalid application of 'sizeof' to interface 'I0' in non-fragile ABI}} + == 4 ? 1 : -1]; + +@implementation I0 +@synthesize p0 = _p0; +@end + +// size == 4 (we do not include extended properties in the +// sizeof). +int g2[ sizeof(I0) // expected-error {{invalid application of 'sizeof' to interface 'I0' in non-fragile ABI}} + == 4 ? 1 : -1]; + +@interface I1 +@property int p0; +@end + +@implementation I1 +@synthesize p0 = _p0; +@end + +typedef struct { @defs(I1); } I1_defs; // expected-error {{invalid application of @defs in non-fragile ABI}} + +// FIXME: This is currently broken due to the way the record layout we +// create is tied to whether we have seen synthesized properties. Ugh. +// int g3[ sizeof(I1) == 0 ? 1 : -1]; + +// rdar://6821047 +int bar(I0 *P) { + P = P+5; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}} + P = 5+P; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}} + P = P-5; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}} + + return P[4].x[2]; // expected-error {{expected method to read array element not found on object of type 'I0 *'}} +} + + +@interface I @end + +@interface XCAttributeRunDirectNode +{ + @public + unsigned long attributeRuns[1024 + sizeof(I)]; // expected-error {{invalid application of 'sizeof' to interface 'I' in non-fragile ABI}} + int i; +} +@end + +@implementation XCAttributeRunDirectNode + +- (unsigned long)gatherStats:(id )stats +{ + return attributeRuns[i]; +} +@end + + +@interface Foo @end + +int foo() +{ + Foo *f; + + // Both of these crash clang nicely + ++f; // expected-error {{arithmetic on pointer to interface 'Foo', which is not a constant size in non-fragile ABI}} + --f; // expected-error {{arithmetic on pointer to interface 'Foo', which is not a constant size in non-fragile ABI}} +} diff --git a/clang/test/SemaObjC/special-dep-unavail-warning.m b/clang/test/SemaObjC/special-dep-unavail-warning.m new file mode 100644 index 0000000..754bf5f --- /dev/null +++ b/clang/test/SemaObjC/special-dep-unavail-warning.m @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://8769853 + +@interface B +- (void) depInA; +- (void) unavailMeth __attribute__((unavailable)); // expected-note {{has been explicitly marked unavailable here}} +- (void) depInA1 __attribute__((deprecated)); +- (void) unavailMeth1; +- (void) depInA2 __attribute__((deprecated)); +- (void) unavailMeth2 __attribute__((unavailable)); // expected-note {{has been explicitly marked unavailable here}} +- (void) depunavailInA; +- (void) depunavailInA1 __attribute__((deprecated)) __attribute__((unavailable)); // expected-note {{has been explicitly marked unavailable here}} +- (void)FuzzyMeth __attribute__((deprecated)); +- (void)FuzzyMeth1 __attribute__((unavailable)); +@end + +@interface A +- (void) unavailMeth1 __attribute__((unavailable)); // expected-note {{has been explicitly marked unavailable here}} +- (void) depInA __attribute__((deprecated)); +- (void) depInA2 __attribute__((deprecated)); +- (void) depInA1; +- (void) unavailMeth2 __attribute__((unavailable)); +- (void) depunavailInA __attribute__((deprecated)) __attribute__((unavailable)); // expected-note {{has been explicitly marked unavailable here}} +- (void) depunavailInA1; +- (void)FuzzyMeth __attribute__((unavailable)); +- (void)FuzzyMeth1 __attribute__((deprecated)); +@end + + +@class C; // expected-note 5 {{forward declaration of class here}} + +void test(C *c) { + [c depInA]; // expected-warning {{'depInA' maybe deprecated because receiver type is unknown}} + [c unavailMeth]; // expected-warning {{'unavailMeth' maybe unavailable because receiver type is unknown}} + [c depInA1]; // expected-warning {{'depInA1' maybe deprecated because receiver type is unknown}} + [c unavailMeth1]; // expected-warning {{'unavailMeth1' maybe unavailable because receiver type is unknown}} + [c depInA2]; // expected-warning {{'depInA2' maybe deprecated because receiver type is unknown}} + [c unavailMeth2]; // expected-warning {{'unavailMeth2' maybe unavailable because receiver type is unknown}} + [c depunavailInA]; // expected-warning {{'depunavailInA' maybe unavailable because receiver type is unknown}} + [c depunavailInA1];// expected-warning {{'depunavailInA1' maybe unavailable because receiver type is unknown}} + [c FuzzyMeth]; // expected-warning {{'FuzzyMeth' maybe deprecated because receiver type is unknown}} + [c FuzzyMeth1]; // expected-warning {{'FuzzyMeth1' maybe deprecated because receiver type is unknown}} + +} + +// rdar://10268422 +__attribute ((deprecated)) +@interface DEPRECATED ++(id)new; +@end + +void foo() { + [DEPRECATED new]; // expected-warning {{'DEPRECATED' is deprecated}} +} + diff --git a/clang/test/SemaObjC/stand-alone-implementation.m b/clang/test/SemaObjC/stand-alone-implementation.m new file mode 100644 index 0000000..6fa9b4b --- /dev/null +++ b/clang/test/SemaObjC/stand-alone-implementation.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// radar 7547942 +// Allow injection of ivars into implementation's implicit class. + +@implementation INTFSTANDALONE // expected-warning {{cannot find interface declaration for 'INTFSTANDALONE'}} +{ + id IVAR1; + id IVAR2; +} +- (id) Meth { return IVAR1; } +@end + diff --git a/clang/test/SemaObjC/static-ivar-ref-1.m b/clang/test/SemaObjC/static-ivar-ref-1.m new file mode 100644 index 0000000..d9f99f5 --- /dev/null +++ b/clang/test/SemaObjC/static-ivar-ref-1.m @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -ast-print %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -ast-print %s 2>&1 | FileCheck %s + +@interface current +{ +@public + int ivar; + int ivar1; + int ivar2; +} +@end + +current *pc; + +int foo() +{ + return pc->ivar2 + (*pc).ivar + pc->ivar1; +} + +// CHECK: @interface current{ +// CHECK: int ivar; +// CHECK: int ivar1; +// CHECK: int ivar2; +// CHECK: } +// CHECK: @end +// CHECK: current *pc; +// CHECK: int foo() { +// CHECK: return pc->ivar2 + (*pc).ivar + pc->ivar1; +// CHECK: } + diff --git a/clang/test/SemaObjC/stmts.m b/clang/test/SemaObjC/stmts.m new file mode 100644 index 0000000..d452db8 --- /dev/null +++ b/clang/test/SemaObjC/stmts.m @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only -fobjc-exceptions + +struct some_struct; + +@interface NSObject +@end + +// Note: NSException is not declared. +void f0(id x) { + @try { + } @catch (NSException *x) { // expected-error {{unknown type name 'NSException'}} + } @catch (struct some_struct x) { // expected-error {{@catch parameter is not a pointer to an interface type}} + } @catch (int x) { // expected-error {{@catch parameter is not a pointer to an interface type}} + } @catch (static NSObject *y) { // expected-error {{@catch parameter cannot have storage specifier 'static'}} + } @catch (...) { + } +} + diff --git a/clang/test/SemaObjC/string.m b/clang/test/SemaObjC/string.m new file mode 100644 index 0000000..04f20ab --- /dev/null +++ b/clang/test/SemaObjC/string.m @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only +// RUN: %clang_cc1 %s -verify -fsyntax-only -DDECLAREIT + +// a declaration of NSConstantString is not required. +#ifdef DECLAREIT +@interface NSConstantString; +@end +#endif + + + +id s = @"123"; // simple +id t = @"123" @"456"; // concat +id u = @"123" @ blah; // expected-error {{unexpected token}} + diff --git a/clang/test/SemaObjC/super-cat-prot.m b/clang/test/SemaObjC/super-cat-prot.m new file mode 100644 index 0000000..3e28986 --- /dev/null +++ b/clang/test/SemaObjC/super-cat-prot.m @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +typedef signed char BOOL; +typedef unsigned int NSUInteger; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; +@protocol NSObject - (BOOL)isEqual:(id)object; @end +@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end +@interface NSObject <NSObject> {} @end +typedef float CGFloat; +typedef struct _NSSize {} NSSize; +typedef struct _NSRect {} NSRect; +@interface NSResponder : NSObject <NSCoding> {} @end +@protocol NSAnimatablePropertyContainer - (id)animator; @end +extern NSString *NSAnimationTriggerOrderIn ; +@interface NSView : NSResponder <NSAnimatablePropertyContainer> {} @end +@class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView; +enum { NSBoxPrimary = 0, NSBoxSecondary = 1, NSBoxSeparator = 2, NSBoxOldStyle = 3, NSBoxCustom = 4}; +typedef NSUInteger NSBoxType; +@interface NSBox : NSView {} - (NSBoxType)boxType; @end +@class NSArray, NSError, NSImage, NSView, NSNotificationCenter, NSURL; +@interface NSProBox:NSBox {} @end +enum IBKnobPosition { IBNoKnobPosition = -1, IBBottomLeftKnobPosition = 0, + IBMiddleLeftKnobPosition, IBTopLeftKnobPosition, + IBTopMiddleKnobPosition, IBTopRightKnobPosition, + IBMiddleRightKnobPosition, IBBottomRightKnobPosition, + IBBottomMiddleKnobPosition }; +typedef enum IBKnobPosition IBKnobPosition; +typedef struct _IBInset {} IBInset; +@protocol IBObjectProtocol -(NSString *)inspectorClassName; @end +@protocol IBViewProtocol + -(NSSize)minimumFrameSizeFromKnobPosition:(IBKnobPosition)position; + -(IBInset)ibShadowInset; +@end +@class NSPasteboard; +@interface NSObject (NSObject_IBObjectProtocol) <IBObjectProtocol> @end +@interface NSView (NSView_IBViewProtocol) <IBViewProtocol> - (NSRect)layoutRect; @end +typedef enum { NSProTextFieldSquareBezel = 0, NSProTextFieldRoundedBezel = 1, NSProTextFieldDisplayBezel = 2 } MKModuleReusePolicy; +@implementation NSProBox(IBAdditions) +-(NSString *)inspectorClassName { return 0; } +-(IBInset)ibShadowInset { + if ([self boxType] == NSBoxSeparator) { + return [super ibShadowInset]; + } + while (1) {} +} +-(NSSize)minimumFrameSizeFromKnobPosition:(IBKnobPosition)knobPosition { + if ([self boxType] != NSBoxSeparator) + return [super minimumFrameSizeFromKnobPosition:knobPosition]; + while (1) {} +} +@end diff --git a/clang/test/SemaObjC/super-class-protocol-conformance.m b/clang/test/SemaObjC/super-class-protocol-conformance.m new file mode 100644 index 0000000..32d5392 --- /dev/null +++ b/clang/test/SemaObjC/super-class-protocol-conformance.m @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://7884086 + +@interface NSObject @end + +@protocol TopProtocol + @property (readonly) id myString; // expected-note {{property}} +@end + +@protocol SubProtocol <TopProtocol> +@end + +@interface TopClass : NSObject <TopProtocol> {} +@end + +@interface SubClass : TopClass <SubProtocol> {} +@end + +@interface SubClass1 : TopClass {} +@end + +@implementation SubClass1 @end // Test1 - No Warning + +@implementation TopClass // expected-warning {{property 'myString' requires method 'myString' to be defined}} +@end + +@implementation SubClass // Test3 - No Warning +@end + +@interface SubClass2 : TopClass<TopProtocol> +@end + +@implementation SubClass2 @end // Test 4 - No Warning + +@interface SubClass3 : TopClass<SubProtocol> @end +@implementation SubClass3 @end // Test 5 - No Warning + +@interface SubClass4 : SubClass3 @end +@implementation SubClass4 @end // Test 5 - No Warning + +@protocol NewProtocol + @property (readonly) id myNewString; // expected-note {{property}} +@end + +@interface SubClass5 : SubClass4 <NewProtocol> @end +@implementation SubClass5 @end // expected-warning {{property 'myNewString' requires method 'myNewString' to be defined}} + + +// Radar 8035776 +@protocol SuperProtocol +@end + +@interface Super <SuperProtocol> +@end + +@protocol ProtocolWithProperty <SuperProtocol> +@property (readonly, assign) id invalidationBacktrace; // expected-note {{property}} +@end + +@interface INTF : Super <ProtocolWithProperty> +@end + +@implementation INTF @end // expected-warning{{property 'invalidationBacktrace' requires method 'invalidationBacktrace' to be defined}} diff --git a/clang/test/SemaObjC/super-property-message-expr.m b/clang/test/SemaObjC/super-property-message-expr.m new file mode 100644 index 0000000..c25164e --- /dev/null +++ b/clang/test/SemaObjC/super-property-message-expr.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface SStoreNodeInfo + +@property(nonatomic,readonly,retain) id descriptionShort; + +- (id)stringByAppendingFormat:(int)format, ... ; + +@end + +@interface SStoreNodeInfo_iDisk : SStoreNodeInfo +{ +@private + id _etag; +} +@end + +@implementation SStoreNodeInfo_iDisk +- (id) X { return [super.descriptionShort stringByAppendingFormat:1, _etag]; } + +@end diff --git a/clang/test/SemaObjC/super-property-notation.m b/clang/test/SemaObjC/super-property-notation.m new file mode 100644 index 0000000..7d3f7c7 --- /dev/null +++ b/clang/test/SemaObjC/super-property-notation.m @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface B ++(int) classGetter; +-(int) getter; +@end + +@interface A : B +@end + +@implementation A ++(int) classGetter { + return 0; +} + ++(int) classGetter2 { + return super.classGetter; +} + +-(void) method { + int x = super.getter; +} +@end + +void f0() { + // FIXME: not implemented yet. + //int l1 = A.classGetter; + int l2 = [A classGetter2]; +} + diff --git a/clang/test/SemaObjC/super.m b/clang/test/SemaObjC/super.m new file mode 100644 index 0000000..cf48c19 --- /dev/null +++ b/clang/test/SemaObjC/super.m @@ -0,0 +1,87 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s + +void takevoidptr(void*); + + +@interface Foo +- iMethod; ++ cMethod; +@end + +@interface A ++ superClassMethod; +- (void)instanceMethod; +@end + +@interface B : A +- (void)instanceMethod; ++ classMethod; +@end + +@implementation B + +- (void)instanceMethod { + [super iMethod]; // expected-warning{{'A' may not respond to 'iMethod'}} + + // Use of super in a block is ok and does codegen to the right thing. + // rdar://7852959 + takevoidptr(^{ + [super instanceMethod]; + }); +} + ++ classMethod { + [super cMethod]; // expected-warning{{method '+cMethod' not found (return type defaults to 'id')}} + + id X[] = { [ super superClassMethod] }; + id Y[] = { + [ super.superClassMethod iMethod], + super.superClassMethod, + (id)super.superClassMethod // not a cast of super: rdar://7853261 + }; + return 0; +} +@end + +@interface XX +- m; +@end + +void f(id super) { + [super m]; +} +void f0(int super) { + [super m]; // expected-warning{{receiver type 'int' is not 'id'}} \ + expected-warning {{method '-m' not found (return type defaults to 'id')}} +} +void f1(id puper) { // expected-note {{'puper' declared here}} + [super m]; // expected-error{{use of undeclared identifier 'super'}} +} + +// radar 7400691 +typedef Foo super; + +typedef Foo FooTD; + +void test() { + [FooTD cMethod]; + [super cMethod]; +} + +struct SomeStruct { + int X; +}; + +int test2() { + struct SomeStruct super = { 0 }; + return super.X; +} + +int test3() { + id super = 0; + [(B*)super instanceMethod]; + int *s1 = (int*)super; + + id X[] = { [ super superClassMethod] }; + return 0; +} diff --git a/clang/test/SemaObjC/synchronized.m b/clang/test/SemaObjC/synchronized.m new file mode 100644 index 0000000..c158815 --- /dev/null +++ b/clang/test/SemaObjC/synchronized.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface PBXTrackableTaskManager @end + +@implementation PBXTrackableTaskManager +- (id) init { return 0; } +- (void) unregisterTask:(id) task { + @synchronized (self) { + id taskID = [task taskIdentifier]; // expected-warning {{method '-taskIdentifier' not found (return type defaults to 'id')}} + } +} +@end + + +struct x { int a; } b; + +void test1() { + @synchronized (b) { // expected-error {{@synchronized requires an Objective-C object type ('struct x' invalid)}} + } + + @synchronized (42) { // expected-error {{@synchronized requires an Objective-C object type ('int' invalid)}} + } +} diff --git a/clang/test/SemaObjC/synth-provisional-ivars-1.m b/clang/test/SemaObjC/synth-provisional-ivars-1.m new file mode 100644 index 0000000..0e155f4 --- /dev/null +++ b/clang/test/SemaObjC/synth-provisional-ivars-1.m @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-default-synthesize-properties -verify -Wno-objc-root-class %s +// rdar://8913053 + +typedef unsigned char BOOL; + +@interface MailApp +{ + BOOL _isAppleInternal; +} +@property(assign) BOOL isAppleInternal; +@end + +static BOOL isAppleInternal() {return 0; } + +@implementation MailApp + +- (BOOL)isAppleInternal { + return _isAppleInternal; +} + +- (void)setIsAppleInternal:(BOOL)flag { + _isAppleInternal= !!flag; +} + +- (void) Meth { + self.isAppleInternal = isAppleInternal(); +} +@end diff --git a/clang/test/SemaObjC/synth-provisional-ivars.m b/clang/test/SemaObjC/synth-provisional-ivars.m new file mode 100644 index 0000000..9d7abd5 --- /dev/null +++ b/clang/test/SemaObjC/synth-provisional-ivars.m @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-default-synthesize-properties -verify -Wno-objc-root-class %s + +int bar; + +@interface I +{ + int _bar; +} +@property int PROP; +@property int PROP1; +@property int PROP2; +@property int PROP3; +@property int PROP4; + +@property int bar; +@property int bar1; + +@end + +@implementation I +- (int) Meth { return _PROP; } + +@dynamic PROP1; +- (int) Meth1 { return PROP1; } // expected-error {{use of undeclared identifier 'PROP1'}} + +- (int) Meth2 { return PROP2; } // expected-error {{use of undeclared identifier 'PROP2'}} +@dynamic PROP2; + +- (int) Meth3 { return PROP3; } // expected-error {{use of undeclared identifier 'PROP3'}} +@synthesize PROP3=IVAR; + +- (int) Meth4 { return PROP4; } +@synthesize PROP4=PROP4; // expected-note 4 {{'PROP4' declared here}} + +- (int) Meth5 { return bar; } +@synthesize bar = _bar; + +- (int) Meth6 { return _bar1; } + +@end + +@implementation I(CAT) +- (int) Meth { return PROP1; } // expected-error {{use of undeclared identifier 'PROP1'}} +@end + +@implementation I(r8251648) +- (int) Meth1: (int) bar { + return bar; +} +@end diff --git a/clang/test/SemaObjC/synthesize-setter-contclass.m b/clang/test/SemaObjC/synthesize-setter-contclass.m new file mode 100644 index 0000000..d754415 --- /dev/null +++ b/clang/test/SemaObjC/synthesize-setter-contclass.m @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface TestClass +{ + int _isItIsOrIsItAint; +} +@property (readonly) int itIsOrItAint; +-(void) doSomething; +@end + +@interface TestClass() +@property (readwrite) int itIsOrItAint; +@end + +@implementation TestClass +@synthesize itIsOrItAint = _isItIsOrIsItAint; + +-(void) doSomething +{ + int i = [self itIsOrItAint]; + + [self setItIsOrItAint:(int)1]; +} +@end diff --git a/clang/test/SemaObjC/synthesized-ivar.m b/clang/test/SemaObjC/synthesized-ivar.m new file mode 100644 index 0000000..8c9d905 --- /dev/null +++ b/clang/test/SemaObjC/synthesized-ivar.m @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-default-synthesize-properties -verify -Wno-objc-root-class %s +@interface I +{ +} +@property int IP; +@end + +@implementation I +@synthesize IP; +- (int) Meth { + return IP; +} +@end + +// rdar://7823675 +int f0(I *a) { return a->IP; } // expected-error {{instance variable 'IP' is private}} + +// rdar://8769582 + +@interface I1 { + int protected_ivar; +} +@property int PROP_INMAIN; +@end + +@interface I1() { + int private_ivar; +} +@property int PROP_INCLASSEXT; +@end + +@implementation I1 +- (int) Meth { + _PROP_INMAIN = 1; + _PROP_INCLASSEXT = 2; + protected_ivar = 1; // OK + return private_ivar; // OK +} +@end + + +@interface DER : I1 +@end + +@implementation DER +- (int) Meth { + protected_ivar = 1; // OK + _PROP_INMAIN = 1; // expected-error {{instance variable '_PROP_INMAIN' is private}} + _PROP_INCLASSEXT = 2; // expected-error {{instance variable '_PROP_INCLASSEXT' is private}} + return private_ivar; // expected-error {{instance variable 'private_ivar' is private}} +} +@end + +@interface A +@property (weak) id testObjectWeakProperty; // expected-note {{declared here}} +@end + +@implementation A +// rdar://9605088 +@synthesize testObjectWeakProperty; // expected-error {{@synthesize of 'weak' property is only allowed in ARC or GC mode}} +@end diff --git a/clang/test/SemaObjC/transparent-union.m b/clang/test/SemaObjC/transparent-union.m new file mode 100644 index 0000000..6f2dbf9 --- /dev/null +++ b/clang/test/SemaObjC/transparent-union.m @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +typedef union { + struct xx_object_s *_do; + struct xx_continuation_s *_dc; + struct xx_queue_s *_dq; + struct xx_queue_attr_s *_dqa; + struct xx_group_s *_dg; + struct xx_source_s *_ds; + struct xx_source_attr_s *_dsa; + struct xx_semaphore_s *_dsema; +} xx_object_t __attribute__((transparent_union)); + +@interface INTF +- (void) doSomething : (xx_object_t) xxObject; +- (void)testMeth; +@end + +@implementation INTF +- (void) doSomething : (xx_object_t) xxObject {} +- (void)testMeth { struct xx_queue_s *sq; [self doSomething:sq ]; } +@end diff --git a/clang/test/SemaObjC/try-catch.m b/clang/test/SemaObjC/try-catch.m new file mode 100644 index 0000000..5afbbb6 --- /dev/null +++ b/clang/test/SemaObjC/try-catch.m @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fobjc-exceptions %s +typedef signed char BOOL; +typedef struct _NSZone NSZone; + +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; + +@protocol NSObject +- (BOOL)isEqual:(id)object; +@end + +@protocol NSCopying +- (id)copyWithZone:(NSZone *)zone; +@end + +@protocol NSCoding +- (void)encodeWithCoder:(NSCoder *)aCoder; +@end + +@interface NSObject <NSObject> {} +@end + +@class NSData, NSArray, NSDictionary, NSCharacterSet, NSData, NSURL, NSError, NSLocale; + +@interface NSException : NSObject <NSCopying, NSCoding> {} +@end + +@class ASTNode, XCRefactoringParser, Transform, TransformInstance, XCRefactoringSelectionInfo; + +@interface XCRefactoringTransformation : NSObject {} +@end + +@implementation XCRefactoringTransformation +- (NSDictionary *)setUpInfoForTransformKey:(NSString *)transformKey outError:(NSError **)outError { + @try {} + // the exception name is optional (weird) + @catch (NSException *) {} +} +@end + +int foo() { + struct s { int a, b; } agg, *pagg; + + @throw 42; // expected-error {{@throw requires an Objective-C object type ('int' invalid)}} + @throw agg; // expected-error {{@throw requires an Objective-C object type ('struct s' invalid)}} + @throw pagg; // expected-error {{@throw requires an Objective-C object type ('struct s *' invalid)}} + @throw; // expected-error {{@throw (rethrow) used outside of a @catch block}} +} diff --git a/clang/test/SemaObjC/typedef-class.m b/clang/test/SemaObjC/typedef-class.m new file mode 100644 index 0000000..bd68397 --- /dev/null +++ b/clang/test/SemaObjC/typedef-class.m @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +typedef signed char BOOL; +typedef unsigned int NSUInteger; +typedef struct _NSZone NSZone; + +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; + +@protocol NSObject - (BOOL) isEqual:(id) object; - (id)init; @end +@protocol NSCopying - (id) copyWithZone:(NSZone *) zone; @end +@protocol NSCoding - (void) encodeWithCoder:(NSCoder *) aCoder; @end + +@interface NSObject < NSObject > {} ++(id) alloc; +@end + +typedef float CGFloat; + +@interface NSTask:NSObject +- (id) init; +@end + +typedef NSUInteger NSControlSize; +typedef struct __CFlags {} _CFlags; + +@interface NSCell:NSObject < NSCopying, NSCoding > {} +@end + +@interface NSActionCell:NSCell {} @end + +@class NSAttributedString, NSFont, NSImage, NSSound; + +typedef struct _XCElementInset {} XCElementInset; + +@protocol XCElementP < NSObject > +-(BOOL) vertical; +@end + +@protocol XCElementDisplayDelegateP; +@protocol XCElementDisplayDelegateP < NSObject > +-(void) configureForControlSize:(NSControlSize)size font:(NSFont *)font addDefaultSpace:(XCElementInset) additionalSpace; +@end + +@protocol XCElementSpacerP < XCElementP > +@end + +typedef NSObject < XCElementSpacerP > XCElementSpacer; + +@protocol XCElementTogglerP < XCElementP > -(void) setDisplayed:(BOOL) displayed; +@end + +typedef NSObject < XCElementTogglerP > XCElementToggler; // expected-note {{previous definition is here}} + +@interface XCElementRootFace:NSObject {} @end + +@interface XCElementFace:XCElementRootFace {} @end + +@class XCElementToggler; // expected-warning {{redefinition of forward class 'XCElementToggler' of a typedef name of an object type is ignored}} + +@interface XCRASlice:XCElementFace {} @end + +@class XCElementSpacings; + +@interface XCElementDisplay:NSObject < XCElementDisplayDelegateP > {} @end +@interface XCElementDisplayRect:XCElementDisplay {} @end + +typedef XCElementDisplayRect XCElementGraphicsRect; + +@interface XCElementDisplayFillerImage:XCElementDisplay {} @end + +@implementation XCRASlice +- (void) addSliceWithLabel:(NSString *)label statusKey:(NSString *)statusKey disclosed:(BOOL)disclosed +{ + static XCElementGraphicsRect *_sGraphicsDelegate = ((void *) 0); + if (!_sGraphicsDelegate) { + _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init]; + } +} +@end diff --git a/clang/test/SemaObjC/ucn-objc-string.m b/clang/test/SemaObjC/ucn-objc-string.m new file mode 100644 index 0000000..6070278 --- /dev/null +++ b/clang/test/SemaObjC/ucn-objc-string.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only +@class NSString; +extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); + +int main() { + NSLog(@"Hi…"); + NSLog(@"Exposé"); + NSLog(@"\U00010400\U0001D12B"); + NSLog(@"hello \u2192 \u2603 \u2190 world"); + NSLog(@"hello → ☃ ← world"); + return 0; +} + diff --git a/clang/test/SemaObjC/undeclared-selector.m b/clang/test/SemaObjC/undeclared-selector.m new file mode 100644 index 0000000..0914510 --- /dev/null +++ b/clang/test/SemaObjC/undeclared-selector.m @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -fsyntax-only -Wundeclared-selector -verify -Wno-objc-root-class %s + +typedef struct objc_selector *SEL; + +@interface MyClass + ++ (void) methodA; +- (void) methodB; ++ (void) methodD; +- (void) methodF; + +@end + +@implementation MyClass + ++ (void) methodA {} +- (void) methodB {} ++ (void) methodD +{ + SEL d = @selector(methodD); /* Ok */ + SEL e = @selector(methodE); +} + +- (void) methodE +{ + SEL e = @selector(methodE); /* Ok */ +} + +- (void) methodF +{ + SEL e = @selector(methodE); /* Ok */ +} + +@end + +int main (void) +{ + SEL a = @selector(methodA); /* Ok */ + SEL b = @selector(methodB); /* Ok */ + SEL c = @selector(methodC); // expected-warning {{undeclared selector 'methodC'}} + SEL d = @selector(methodD); /* Ok */ + SEL e = @selector(methodE); /* Ok */ + return 0; + +} diff --git a/clang/test/SemaObjC/undef-class-messagin-error.m b/clang/test/SemaObjC/undef-class-messagin-error.m new file mode 100644 index 0000000..63e0b9d --- /dev/null +++ b/clang/test/SemaObjC/undef-class-messagin-error.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface _Child // expected-note{{'_Child' declared here}} ++ (int) flashCache; +@end + +@interface Child (Categ) // expected-error {{cannot find interface declaration for 'Child'; did you mean '_Child'?}} ++ (int) flushCache2; +@end + +@implementation OtherChild (Categ) // expected-error {{cannot find interface declaration for 'OtherChild'}} ++ (int) flushCache2 { [super flashCache]; } // expected-error {{no @interface declaration found in class messaging of 'flushCache2'}} +@end diff --git a/clang/test/SemaObjC/undef-protocol-methods-1.m b/clang/test/SemaObjC/undef-protocol-methods-1.m new file mode 100644 index 0000000..15ba1a1 --- /dev/null +++ b/clang/test/SemaObjC/undef-protocol-methods-1.m @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@protocol P1 +- (void) P1proto; // expected-note {{method 'P1proto' declared here}} ++ (void) ClsP1Proto; // expected-note {{method 'ClsP1Proto' declared here}} +- (void) DefP1proto; +@end +@protocol P2 +- (void) P2proto; // expected-note {{method 'P2proto' declared here}} ++ (void) ClsP2Proto; // expected-note {{method 'ClsP2Proto' declared here}} +@end + +@protocol P3<P2> +- (void) P3proto; // expected-note {{method 'P3proto' declared here}} ++ (void) ClsP3Proto; // expected-note {{method 'ClsP3Proto' declared here}} ++ (void) DefClsP3Proto; +@end + +@protocol PROTO<P1, P3> +- (void) meth; // expected-note {{method 'meth' declared here}} +- (void) meth : (int) arg1; // expected-note {{method 'meth:' declared here}} ++ (void) cls_meth : (int) arg1; // expected-note {{method 'cls_meth:' declared here}} +@end + +@interface INTF <PROTO> // expected-note 3 {{required for direct or indirect protocol 'PROTO'}} \ + // expected-note 2 {{required for direct or indirect protocol 'P1'}} \ + // expected-note 2 {{required for direct or indirect protocol 'P3'}} \ + // expected-note 2 {{required for direct or indirect protocol 'P2'}} +@end + +@implementation INTF // expected-warning {{incomplete implementation}} \ + // expected-warning 9 {{in protocol not implemented}} +- (void) DefP1proto{} + ++ (void) DefClsP3Proto{} + +@end diff --git a/clang/test/SemaObjC/undef-superclass-1.m b/clang/test/SemaObjC/undef-superclass-1.m new file mode 100644 index 0000000..e8e03c5 --- /dev/null +++ b/clang/test/SemaObjC/undef-superclass-1.m @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@class SUPER, Y; // expected-note 2 {{forward declaration of class here}} + +@interface INTF :SUPER // expected-error {{attempting to use the forward class 'SUPER' as superclass of 'INTF'}} +@end + +@interface SUPER @end + +@interface INTF1 : SUPER // expected-note {{previous definition is here}} +@end + +@interface INTF2 : INTF1 +@end + +@interface INTF3 : Y // expected-error {{attempting to use the forward class 'Y' as superclass of 'INTF3'}} \ + // expected-note{{'INTF3' declared here}} +@end + +@interface INTF1 // expected-error {{duplicate interface definition for class 'INTF1'}} +@end + +@implementation SUPER +- (void)dealloc { + [super dealloc]; // expected-error {{'SUPER' cannot use 'super' because it is a root class}} +} +@end + +@interface RecursiveClass : RecursiveClass // expected-error {{trying to recursively use 'RecursiveClass' as superclass of 'RecursiveClass'}} +@end + +@implementation RecursiveClass +@end + +@implementation iNTF3 // expected-warning{{cannot find interface declaration for 'iNTF3'; did you mean 'INTF3'?}} +@end diff --git a/clang/test/SemaObjC/undefined-protocol-type-1.m b/clang/test/SemaObjC/undefined-protocol-type-1.m new file mode 100644 index 0000000..f1a0802 --- /dev/null +++ b/clang/test/SemaObjC/undefined-protocol-type-1.m @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@protocol p1, p4; +@protocol p2 @end + +@interface T +- (T<p2, p3, p1, p4>*) meth; // expected-error {{cannot find protocol declaration for 'p3'}} +- (T<p2, p3, p1, p4>*) meth1; // expected-error {{cannot find protocol declaration for 'p3'}} +@end diff --git a/clang/test/SemaObjC/unimplemented-protocol-prop.m b/clang/test/SemaObjC/unimplemented-protocol-prop.m new file mode 100644 index 0000000..1438cf5 --- /dev/null +++ b/clang/test/SemaObjC/unimplemented-protocol-prop.m @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@protocol PROTOCOL0 +@required +@property float MyProperty0; // expected-note 2 {{property declared}} +@end + +@protocol PROTOCOL<PROTOCOL0> +@required +@property float MyProperty; // expected-note 2 {{property declared}} +@optional +@property float OptMyProperty; +@end + +@interface I <PROTOCOL> +@end + +@implementation I @end // expected-warning {{property 'MyProperty0' requires method 'MyProperty0' to be defined}} \ + // expected-warning {{property 'MyProperty0' requires method 'setMyProperty0:' to be defined}}\ + // expected-warning {{property 'MyProperty' requires method 'MyProperty' to be defined}} \ + // expected-warning {{property 'MyProperty' requires method 'setMyProperty:' to be defined}} + +// rdar://10120691 +// property is implemented in super class. No warning + +@protocol PROTOCOL1 +@property int MyProp; +@end + +@interface superclass +@property int MyProp; +@end + +@interface childclass : superclass <PROTOCOL1> +@end + +@implementation childclass +@end + diff --git a/clang/test/SemaObjC/uninit-variables.m b/clang/test/SemaObjC/uninit-variables.m new file mode 100644 index 0000000..cad0f54 --- /dev/null +++ b/clang/test/SemaObjC/uninit-variables.m @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -fsyntax-only -fblocks %s -verify + +// Duplicated from uninit-variables.c. +// Test just to ensure the analysis is working. +int test1() { + int x; // expected-note{{initialize the variable 'x' to silence this warning}} + return x; // expected-warning{{variable 'x' is uninitialized when used here}} +} + +// Test ObjC fast enumeration. +void test2() { + id collection = 0; + for (id obj in collection) { + if (0 == obj) // no-warning + break; + } +} + +void test3() { + id collection = 0; + id obj; + for (obj in collection) { // no-warning + if (0 == obj) // no-warning + break; + } +} + diff --git a/clang/test/SemaObjC/unknown-anytype.m b/clang/test/SemaObjC/unknown-anytype.m new file mode 100644 index 0000000..38e058c --- /dev/null +++ b/clang/test/SemaObjC/unknown-anytype.m @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -funknown-anytype -fsyntax-only -fdebugger-support -verify %s + +extern __unknown_anytype test0; +extern __unknown_anytype test1(); + +@interface A +- (int*)getIntPtr; +- (double*)getSomePtr; +@end + +@interface B +- (float*)getFloatPtr; +- (short*)getSomePtr; +@end + +void test_unknown_anytype_receiver() { + int *ip = [test0 getIntPtr]; + float *fp = [test1() getFloatPtr]; + double *dp = [test1() getSomePtr]; // okay: picks first method found + [[test0 unknownMethod] otherUnknownMethod]; // expected-error{{no known method '-otherUnknownMethod'; cast the message send to the method's return type}} + (void)(int)[[test0 unknownMethod] otherUnknownMethod];; + [[test1() unknownMethod] otherUnknownMethod]; // expected-error{{no known method '-otherUnknownMethod'; cast the message send to the method's return type}} + (void)(id)[[test1() unknownMethod] otherUnknownMethod]; + + if ([[test0 unknownMethod] otherUnknownMethod]) { // expected-error{{no known method '-otherUnknownMethod'; cast the message send to the method's return type}} + } + if ([[test1() unknownMethod] otherUnknownMethod]) { // expected-error{{no known method '-otherUnknownMethod'; cast the message send to the method's return type}} + } +} diff --git a/clang/test/SemaObjC/unqualified-to-qualified-class-warn.m b/clang/test/SemaObjC/unqualified-to-qualified-class-warn.m new file mode 100644 index 0000000..e6fa138 --- /dev/null +++ b/clang/test/SemaObjC/unqualified-to-qualified-class-warn.m @@ -0,0 +1,72 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://9091389 + +@protocol Fooable +- (void)foo; +@end + +@protocol SubFooable <Fooable> +@end + +@interface AClass +@end + +@interface BClass : AClass <SubFooable> +@end + +@implementation BClass +- (void)foo { +} +@end + +void functionTakingAClassConformingToAProtocol(AClass <Fooable> *instance) { // expected-note {{passing argument to parameter 'instance' here}} +} + +int main () { + AClass *aobject = 0; + BClass *bobject = 0; + functionTakingAClassConformingToAProtocol(aobject); // expected-warning {{incompatible pointer types passing 'AClass *' to parameter of type 'AClass<Fooable> *'}} + functionTakingAClassConformingToAProtocol(bobject); // Shouldn't warn - does implement Fooable + return 0; +} + +// rdar://9267196 +@interface NSObject @end + +@protocol MyProtocol +@end + +@interface MyClass : NSObject +{ +} +@end + +@implementation MyClass +@end + +@interface MySubclass : MyClass <MyProtocol> +{ +} +@end + +@interface MyTestClass : NSObject +{ +@private + NSObject <MyProtocol> *someObj; +} + +@property (nonatomic, assign) NSObject <MyProtocol> *someObj; + +@end + +@implementation MyTestClass + +@synthesize someObj; + +- (void)someMethod +{ + MySubclass *foo; + [self setSomeObj:foo]; // no warning here! +} + +@end diff --git a/clang/test/SemaObjC/unused.m b/clang/test/SemaObjC/unused.m new file mode 100644 index 0000000..975b9a9 --- /dev/null +++ b/clang/test/SemaObjC/unused.m @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -verify -Wunused -Wunused-parameter -fsyntax-only -Wno-objc-root-class %s + +int printf(const char *, ...); + +@interface Greeter ++ (void) hello; +@end + +@implementation Greeter ++ (void) hello { printf("Hello, World!\n"); } +@end + +int test1(void) { + [Greeter hello]; + return 0; +} + +@interface NSObject @end +@interface NSString : NSObject +- (int)length; +@end + +void test2() { + @"pointless example call for test purposes".length; // expected-warning {{property access result unused - getters should not be used for side effects}} +} + +@interface foo +- (int)meth: (int)x: (int)y: (int)z ; +@end + +@implementation foo +- (int) meth: (int)x: +(int)y: // expected-warning{{unused}} +(int) __attribute__((unused))z { return x; } +@end + +//===------------------------------------------------------------------------=== +// The next test shows how clang accepted attribute((unused)) on ObjC +// instance variables, which GCC does not. +//===------------------------------------------------------------------------=== + +#if __has_feature(attribute_objc_ivar_unused) +#define UNUSED_IVAR __attribute__((unused)) +#else +#error __attribute__((unused)) not supported on ivars +#endif + +@interface TestUnusedIvar { + id y __attribute__((unused)); // no-warning + id x UNUSED_IVAR; // no-warning +} +@end + diff --git a/clang/test/SemaObjC/va-method-1.m b/clang/test/SemaObjC/va-method-1.m new file mode 100644 index 0000000..fe7ccd7 --- /dev/null +++ b/clang/test/SemaObjC/va-method-1.m @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#include <stdarg.h> + +@interface NSObject @end +@interface XX : NSObject @end + +@implementation XX +- (void)encodeValuesOfObjCTypes:(const char *)types, ... { + va_list ap; + va_start(ap, types); + while (*types) ; + va_end(ap); +} + +@end + diff --git a/clang/test/SemaObjC/warn-assign-property-nscopying.m b/clang/test/SemaObjC/warn-assign-property-nscopying.m new file mode 100644 index 0000000..1bdb4f0 --- /dev/null +++ b/clang/test/SemaObjC/warn-assign-property-nscopying.m @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fobjc-gc -fsyntax-only -verify %s +// RUN: %clang_cc1 -x objective-c++ -fobjc-gc -fsyntax-only -verify %s + +@protocol NSCopying @end + +@interface NSObject <NSCopying> +@end + +@interface NSDictionary : NSObject +@end + +@interface INTF + @property NSDictionary* undoAction; // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}} // expected-warning {{default assign attribute on property 'undoAction' which implements NSCopying protocol is not appropriate with}} + @property id okAction; // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}} +@end + diff --git a/clang/test/SemaObjC/warn-deprecated-implementations.m b/clang/test/SemaObjC/warn-deprecated-implementations.m new file mode 100644 index 0000000..919b221 --- /dev/null +++ b/clang/test/SemaObjC/warn-deprecated-implementations.m @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -fsyntax-only -Wdeprecated-implementations -verify -Wno-objc-root-class %s +// rdar://8973810 + +@protocol P +- (void) D __attribute__((deprecated)); // expected-note {{method 'D' declared here}} +@end + +@interface A <P> ++ (void)F __attribute__((deprecated)); // expected-note {{method 'F' declared here}} +@end + +@interface A() +- (void) E __attribute__((deprecated)); // expected-note {{method 'E' declared here}} +@end + +@implementation A ++ (void)F { } // expected-warning {{Implementing deprecated method}} +- (void) D {} // expected-warning {{Implementing deprecated method}} +- (void) E {} // expected-warning {{Implementing deprecated method}} +@end + +__attribute__((deprecated)) +@interface CL // expected-note 2 {{class declared here}} +@end + +@implementation CL // expected-warning {{Implementing deprecated class}} +@end + +@implementation CL ( SomeCategory ) // expected-warning {{'CL' is deprecated}} \ + // expected-warning {{Implementing deprecated category}} +@end + +@interface CL_SUB : CL // expected-warning {{'CL' is deprecated}} +@end + +@interface BASE +- (void) B __attribute__((deprecated)); // expected-note {{method 'B' declared here}} +@end + +@interface SUB : BASE +@end + +@implementation SUB +- (void) B {} // expected-warning {{Implementing deprecated method}} +@end + diff --git a/clang/test/SemaObjC/warn-forward-class-attr-deprecated.m b/clang/test/SemaObjC/warn-forward-class-attr-deprecated.m new file mode 100644 index 0000000..854ff69 --- /dev/null +++ b/clang/test/SemaObjC/warn-forward-class-attr-deprecated.m @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://10290322 + +@class ABGroupImportFilesScope; // expected-note {{forward declaration of class here}} + +@interface I1 +- (id) filenames __attribute__((deprecated)); +@end + +@interface I2 +- (id) Meth : (ABGroupImportFilesScope*) scope; +- (id) filenames __attribute__((deprecated)); +- (id)initWithAccount: (id)account filenames:(id)filenames; +@end + +@implementation I2 +- (id) Meth : (ABGroupImportFilesScope*) scope +{ + id p = [self initWithAccount : 0 filenames :[scope filenames]]; // expected-warning {{'filenames' maybe deprecated because receiver type is unknown}} + return 0; +} +- (id) filenames { return 0; } +- (id)initWithAccount: (id)account filenames:(id)filenames { return 0; } +@end diff --git a/clang/test/SemaObjC/warn-implicit-atomic-property.m b/clang/test/SemaObjC/warn-implicit-atomic-property.m new file mode 100644 index 0000000..887a286 --- /dev/null +++ b/clang/test/SemaObjC/warn-implicit-atomic-property.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -Wimplicit-atomic-properties -fobjc-default-synthesize-properties -verify -Wno-objc-root-class %s +// rdar://8774580 + +@interface Super +@property (nonatomic, readwrite) int P; // OK +@property (atomic, readwrite) int P1; // OK +@property (readwrite) int P2; // expected-note {{property declared here}} +@property int P3; // expected-note {{property declared here}} +@end + +@implementation Super // expected-warning {{property is assumed atomic when auto-synthesizing the property}} +@synthesize P,P1,P2; // expected-warning {{property is assumed atomic by default}} +@end diff --git a/clang/test/SemaObjC/warn-incompatible-builtin-types.m b/clang/test/SemaObjC/warn-incompatible-builtin-types.m new file mode 100644 index 0000000..fd4fb7d --- /dev/null +++ b/clang/test/SemaObjC/warn-incompatible-builtin-types.m @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://7634850 + +@interface Foo +- (void)foo:(Class)class; // expected-note{{passing argument to parameter 'class' here}} +@end + +void FUNC() { + Class c, c1; + SEL s1, s2; + id i, i1; + Foo *f; + [f foo:f]; // expected-warning {{incompatible pointer types sending 'Foo *' to parameter of type 'Class'}} + c = f; // expected-warning {{incompatible pointer types assigning to 'Class' from 'Foo *'}} + + c = i; + + i = c; + + c = c1; + + i = i1; + + s1 = i; // expected-warning {{incompatible pointer types assigning to 'SEL' from 'id'}} + i = s1; // expected-warning {{incompatible pointer types assigning to 'id' from 'SEL'}} + + s1 = s2; + + s1 = c; // expected-warning {{incompatible pointer types assigning to 'SEL' from 'Class'}} + + c = s1; // expected-warning {{incompatible pointer types assigning to 'Class' from 'SEL'}} + + f = i; + + f = c; // expected-warning {{incompatible pointer types assigning to 'Foo *' from 'Class'}} + + f = s1; // expected-warning {{incompatible pointer types assigning to 'Foo *' from 'SEL'}} + + i = f; + + s1 = f; // expected-warning {{incompatible pointer types assigning to 'SEL' from 'Foo *'}} +} diff --git a/clang/test/SemaObjC/warn-missing-super.m b/clang/test/SemaObjC/warn-missing-super.m new file mode 100644 index 0000000..02b8165 --- /dev/null +++ b/clang/test/SemaObjC/warn-missing-super.m @@ -0,0 +1,58 @@ +@protocol NSCopying @end + +__attribute__((objc_root_class)) +@interface NSObject <NSCopying> +- (void)dealloc; +@end + +@implementation NSObject +- (void)dealloc { + // Root class, shouldn't warn +} +- (void)finalize { + // Root class, shouldn't warn +} +@end + +@interface Subclass1 : NSObject +- (void)dealloc; +- (void)finalize; +@end + +@implementation Subclass1 +- (void)dealloc { +} +- (void)finalize { +} +@end + +@interface Subclass2 : NSObject +- (void)dealloc; +- (void)finalize; +@end + +@implementation Subclass2 +- (void)dealloc { + [super dealloc]; // Shouldn't warn +} +- (void)finalize { + [super finalize]; // Shouldn't warn +} +@end + +// RUN: %clang_cc1 -fsyntax-only %s 2>&1 | FileCheck %s +// CHECK: warn-missing-super.m:24:1: warning: method possibly missing a [super dealloc] call +// CHECK: 1 warning generated. + +// RUN: %clang_cc1 -fsyntax-only -fobjc-gc %s 2>&1 | FileCheck --check-prefix=CHECK-GC %s +// CHECK-GC: warn-missing-super.m:24:1: warning: method possibly missing a [super dealloc] call +// CHECK-GC: warn-missing-super.m:26:1: warning: method possibly missing a [super finalize] call +// CHECK-GC: 2 warnings generated. + +// RUN: %clang_cc1 -fsyntax-only -fobjc-gc-only %s 2>&1 | FileCheck --check-prefix=CHECK-GC-ONLY %s +// CHECK-GC-ONLY: warn-missing-super.m:26:1: warning: method possibly missing a [super finalize] call +// CHECK-GC-ONLY: 1 warning generated. + +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin10 -fobjc-arc %s 2>&1 | FileCheck --check-prefix=CHECK-ARC %s +// CHECK-ARC: warn-missing-super.m:36:4: error: ARC forbids explicit message send of 'dealloc' +// CHECK-ARC: 1 error generated. diff --git a/clang/test/SemaObjC/warn-retain-cycle.m b/clang/test/SemaObjC/warn-retain-cycle.m new file mode 100644 index 0000000..00fd234 --- /dev/null +++ b/clang/test/SemaObjC/warn-retain-cycle.m @@ -0,0 +1,125 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -verify -Wno-objc-root-class %s + +@interface Test0 +- (void) setBlock: (void(^)(void)) block; +- (void) addBlock: (void(^)(void)) block; +- (void) actNow; +@end +void test0(Test0 *x) { + [x setBlock: // expected-note {{block will be retained by the captured object}} + ^{ [x actNow]; }]; // expected-warning {{capturing 'x' strongly in this block is likely to lead to a retain cycle}} + x.block = // expected-note {{block will be retained by the captured object}} + ^{ [x actNow]; }; // expected-warning {{capturing 'x' strongly in this block is likely to lead to a retain cycle}} + + [x addBlock: // expected-note {{block will be retained by the captured object}} + ^{ [x actNow]; }]; // expected-warning {{capturing 'x' strongly in this block is likely to lead to a retain cycle}} + + // These actually don't cause retain cycles. + __weak Test0 *weakx = x; + [x addBlock: ^{ [weakx actNow]; }]; + [x setBlock: ^{ [weakx actNow]; }]; + x.block = ^{ [weakx actNow]; }; + + // These do cause retain cycles, but we're not clever enough to figure that out. + [weakx addBlock: ^{ [x actNow]; }]; + [weakx setBlock: ^{ [x actNow]; }]; + weakx.block = ^{ [x actNow]; }; +} + +@interface BlockOwner +@property (retain) void (^strong)(void); // expected-warning {{retain'ed block property does not copy the block - use copy attribute instead}} +@end + +@interface Test1 { +@public + BlockOwner *owner; +}; +@property (retain) BlockOwner *owner; +@property (assign) __strong BlockOwner *owner2; // expected-error {{unsafe_unretained property 'owner2' may not also be declared __strong}} +@property (assign) BlockOwner *owner3; +@end +void test1(Test1 *x) { + x->owner.strong = ^{ (void) x; }; // expected-warning {{retain cycle}} expected-note {{block will be retained by an object strongly retained by the captured object}} + x.owner.strong = ^{ (void) x; }; // expected-warning {{retain cycle}} expected-note {{block will be retained by an object strongly retained by the captured object}} + x.owner2.strong = ^{ (void) x; }; + x.owner3.strong = ^{ (void) x; }; +} + +@implementation Test1 { + BlockOwner * __unsafe_unretained owner3ivar; + __weak BlockOwner *weakowner; +} +@dynamic owner; +@dynamic owner2; +@synthesize owner3 = owner3ivar; + +- (id) init { + self.owner.strong = ^{ (void) owner; }; // expected-warning {{retain cycle}} expected-note {{block will be retained by an object strongly retained by the captured object}} + self.owner2.strong = ^{ (void) owner; }; + + // TODO: should we warn here? What's the story with this kind of mismatch? + self.owner3.strong = ^{ (void) owner; }; + + owner.strong = ^{ (void) owner; }; // expected-warning {{retain cycle}} expected-note {{block will be retained by an object strongly retained by the captured object}} + + owner.strong = ^{ ^{ (void) owner; }(); }; // expected-warning {{retain cycle}} expected-note {{block will be retained by an object strongly retained by the captured object}} + + owner.strong = ^{ (void) sizeof(self); // expected-note {{block will be retained by an object strongly retained by the captured object}} + (void) owner; }; // expected-warning {{capturing 'self' strongly in this block is likely to lead to a retain cycle}} + + weakowner.strong = ^{ (void) owner; }; + + return self; +} +- (void) foo { + owner.strong = ^{ (void) owner; }; // expected-warning {{retain cycle}} expected-note {{block will be retained by an object strongly retained by the captured object}} +} +@end + +void test2_helper(id); +@interface Test2 { + void (^block)(void); + id x; +} +@end +@implementation Test2 +- (void) test { + block = ^{ // expected-note {{block will be retained by an object strongly retained by the captured object}} + test2_helper(x); // expected-warning {{capturing 'self' strongly in this block is likely to lead to a retain cycle}} + }; +} +@end + + +@interface NSOperationQueue {} +- (void)addOperationWithBlock:(void (^)(void))block; +- (void)addSomethingElse:(void (^)(void))block; + +@end + +@interface Test3 { + NSOperationQueue *myOperationQueue; + unsigned count; +} +@end +void doSomething(unsigned v); +@implementation Test3 +- (void) test { + // 'addOperationWithBlock:' is specifically whitelisted. + [myOperationQueue addOperationWithBlock:^() { // no-warning + if (count > 20) { + doSomething(count); + } + }]; +} +- (void) test_positive { + // Sanity check that we are really whitelisting 'addOperationWithBlock:' and not doing + // something funny. + [myOperationQueue addSomethingElse:^() { // expected-note {{block will be retained by an object strongly retained by the captured object}} + if (count > 20) { // expected-warning {{capturing 'self' strongly in this block is likely to lead to a retain cycle}} + doSomething(count); + } + }]; +} +@end + diff --git a/clang/test/SemaObjC/warn-selector-selection.m b/clang/test/SemaObjC/warn-selector-selection.m new file mode 100644 index 0000000..e395f43 --- /dev/null +++ b/clang/test/SemaObjC/warn-selector-selection.m @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface Object +- (void)foo; +@end + +@interface Class1 +- (void)setWindow:(Object *)wdw; +@end + +void foo(void) { + Object *obj; + [obj setWindow:0]; // expected-warning{{'Object' may not respond to 'setWindow:'}} +} diff --git a/clang/test/SemaObjC/warn-strict-selector-match.m b/clang/test/SemaObjC/warn-strict-selector-match.m new file mode 100644 index 0000000..34f1712 --- /dev/null +++ b/clang/test/SemaObjC/warn-strict-selector-match.m @@ -0,0 +1,75 @@ +// RUN: %clang_cc1 -Wstrict-selector-match -fsyntax-only -verify %s + +@interface Foo +-(int) method; // expected-note {{using}} +@end + +@interface Bar +-(float) method; // expected-note {{also found}} +@end + +int main() { [(id)0 method]; } // expected-warning {{multiple methods named 'method' found}} + +@interface Object @end + +@interface Class1 +- (void)setWindow:(Object *)wdw; // expected-note {{using}} +@end + +@interface Class2 +- (void)setWindow:(Class1 *)window; // expected-note {{also found}} +@end + +id foo(void) { + Object *obj = 0; + id obj2 = obj; + [obj setWindow:0]; // expected-warning {{Object' may not respond to 'setWindow:'}} + [obj2 setWindow:0]; // expected-warning {{multiple methods named 'setWindow:' found}} + return obj; +} + +@protocol MyObject +- (id)initWithData:(Object *)data; // expected-note {{using}} \ + // expected-note {{passing argument to parameter 'data' here}} +@end + +@protocol SomeOther +- (id)initWithData:(int)data; // expected-note {{also found}} +@end + +@protocol MyCoding +- (id)initWithData:(id<MyObject, MyCoding>)data; // expected-note {{also found}} +@end + +@interface NTGridDataObject: Object <MyCoding> +{ + Object<MyCoding> *_data; +} ++ (NTGridDataObject*)dataObject:(id<MyObject, MyCoding>)data; +@end + +@implementation NTGridDataObject +- (id)initWithData:(id<MyObject, MyCoding>)data { + return data; +} ++ (NTGridDataObject*)dataObject:(id<MyObject, MyCoding>)data +{ + NTGridDataObject *result = [(id)0 initWithData:data]; // expected-warning {{multiple methods named 'initWithData:' found}} \ + expected-warning {{sending 'id<MyObject,MyCoding>' to parameter of incompatible type 'Object *'}} + return result; +} +@end + +@interface Base +- (unsigned)port; +@end + +@interface Derived: Base +- (Object *)port; ++ (Protocol *)port; +@end + +void foo1(void) { + [(Class)0 port]; // OK - gcc issues warning but there is only one Class method so no ambiguity to warn +} + diff --git a/clang/test/SemaObjC/warn-superclass-method-mismatch.m b/clang/test/SemaObjC/warn-superclass-method-mismatch.m new file mode 100644 index 0000000..5205473 --- /dev/null +++ b/clang/test/SemaObjC/warn-superclass-method-mismatch.m @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -fsyntax-only -Wsuper-class-method-mismatch -verify %s + +@interface Root +-(void) method_r: (char)ch : (float*)f1 : (int*) x; // expected-note {{previous declaration is here}} +@end + +@class Sub; + +@interface Base : Root +-(void) method: (int*) x; // expected-note {{previous declaration is here}} +-(void) method1: (Base*) x; // expected-note {{previous declaration is here}} +-(void) method2: (Sub*) x; // expected-note{{passing argument to parameter 'x' here}} ++ method3: (int)x1 : (Base *)x2 : (float)x3; // expected-note {{previous declaration is here}} ++ mathod4: (id)x1; +- method5: (int) x : (double) d; // expected-note {{previous declaration is here}} +- method6: (int) x : (float) d; // expected-note {{previous declaration is here}} +@end + +struct A { + int x,y,z; +}; + +@interface Sub : Base +-(void) method: (struct A*) a; // expected-warning {{method parameter type 'struct A *' does not match super class method parameter type 'int *'}} +-(void) method1: (Sub*) x; // expected-warning {{method parameter type 'Sub *' does not match super class method parameter type 'Base *'}} +-(void) method2: (Base*) x; // no need to warn. At call point we warn if need be. ++ method3: (int)x1 : (Sub *)x2 : (float)x3; // expected-warning {{method parameter type 'Sub *' does not match super class method parameter type 'Base *'}} ++ mathod4: (Base*)x1; +-(void) method_r: (char)ch : (float*)f1 : (Sub*) x; // expected-warning {{method parameter type 'Sub *' does not match super class method parameter type 'int *'}} +- method5: (int) x : (float) d; // expected-warning {{method parameter type 'float' does not match super class method parameter type 'double'}} +- method6: (int) x : (double) d; // expected-warning {{method parameter type 'double' does not match super class method parameter type 'float'}} +@end + +void f(Base *base, Sub *sub) { + int x; + [base method:&x]; // warn. if base is actually 'Sub' it will use -[Sub method] with wrong arguments + + Base *b; + [base method1:b]; // if base is actuall 'Sub' it will use [Sub method1] with wrong argument. + + [base method2:b]; // expected-warning {{}} + + Sub *s; + [base method2:s]; // if base is actually 'Sub' OK. Either way OK. + +} + + + + diff --git a/clang/test/SemaObjC/warn-unreachable.m b/clang/test/SemaObjC/warn-unreachable.m new file mode 100644 index 0000000..832cbd2 --- /dev/null +++ b/clang/test/SemaObjC/warn-unreachable.m @@ -0,0 +1,17 @@ +// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wunreachable-code -Wno-unused-value -Wno-covered-switch-default + +// This previously triggered a warning from -Wunreachable-code because of +// a busted CFG. +typedef signed char BOOL; +BOOL radar10989084() { + @autoreleasepool { // no-warning + return __objc_yes; + } +} + +// Test the warning works. +void test_unreachable() { + return; + return; // expected-warning {{will never be executed}} +} + diff --git a/clang/test/SemaObjC/warn-unused-exception-param.m b/clang/test/SemaObjC/warn-unused-exception-param.m new file mode 100644 index 0000000..221e16f --- /dev/null +++ b/clang/test/SemaObjC/warn-unused-exception-param.m @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fobjc-exceptions -Wunused-exception-parameter %s +void f0() { + @try {} @catch(id a) {} // expected-warning{{unused exception parameter 'a'}} +} diff --git a/clang/test/SemaObjC/warn-weak-field.m b/clang/test/SemaObjC/warn-weak-field.m new file mode 100644 index 0000000..e7b0fe2 --- /dev/null +++ b/clang/test/SemaObjC/warn-weak-field.m @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -fobjc-gc -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -triple i386-apple-darwin9 -fsyntax-only -fobjc-gc -verify -Wno-objc-root-class %s + +struct S { + __weak id w; // expected-warning {{__weak attribute cannot be specified on a field declaration}} + __strong id p1; +}; + +@interface I +{ + __weak id w; // OK + __strong id LHS; +} +- (void) foo; +@end +@implementation I +- (void) foo { w = 0; LHS = w; } +@end + +int main () +{ + struct I { + __weak id w1; // expected-warning {{__weak attribute cannot be specified on a field declaration}} + }; +} diff --git a/clang/test/SemaObjC/warn-write-strings.m b/clang/test/SemaObjC/warn-write-strings.m new file mode 100644 index 0000000..163c864 --- /dev/null +++ b/clang/test/SemaObjC/warn-write-strings.m @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -fconst-strings %s + +// PR4804 +char* x = "foo"; // expected-warning {{initializing 'char *' with an expression of type 'const char [4]' discards qualifiers}} diff --git a/clang/test/SemaObjC/weak-attr-ivar.m b/clang/test/SemaObjC/weak-attr-ivar.m new file mode 100644 index 0000000..e3d96da --- /dev/null +++ b/clang/test/SemaObjC/weak-attr-ivar.m @@ -0,0 +1,84 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef signed char BOOL; +typedef unsigned int NSUInteger; +typedef struct _NSZone NSZone; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; +@protocol NSObject +- (BOOL)isEqual:(id)object; +@end +@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; +@end +@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; +@end +@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; +@end +@interface NSObject <NSObject> {} +@end +extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); +typedef struct { + id *itemsPtr; + unsigned long *mutationsPtr; +} NSFastEnumerationState; +@protocol NSFastEnumeration +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; +@end +@class NSString; +@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count; +@end +@interface NSMutableArray : NSArray - (void)addObject:(id)anObject; +@end +extern NSString * const NSUndoManagerCheckpointNotification; +@interface NSValueTransformer : NSObject {} @end +@class FooModel; +@interface FooObject : NSObject <NSCopying> {} +@end +@interface FooNode : FooObject {} +- (NSArray *) children; +@end +typedef enum { Foo_HUH_NONE } FooHUHCode; +@interface FooPlaypenEntry : FooNode { + NSMutableArray *_interestingChildren; + FooHUHCode _HUH; + __attribute__((objc_gc(weak))) FooPlaypenEntry *_mostInterestingChild; + id _author; +} +@property(copy) NSString *author; +- (BOOL) isInteresting; +@end NSString *FooHUHCodeToString(FooHUHCode HUH) { return 0; } +@interface FooHUHCodeToStringTransformer: NSValueTransformer { +} +@end @implementation FooPlaypenEntry @synthesize author = _author; +- (BOOL) isInteresting { return 1; } +- (NSArray *) interestingChildren { + if (!_interestingChildren) { + for (FooPlaypenEntry *child in [self children]) { + if ([child isInteresting]) { + if (!_mostInterestingChild) + _mostInterestingChild = child; + else if (child->_HUH > _mostInterestingChild->_HUH) + _mostInterestingChild = child; + } + } + } + return 0; +} +- (FooHUHCode) HUH { + if (_HUH == Foo_HUH_NONE) { + if (_mostInterestingChild) + return [_mostInterestingChild HUH]; + } + return 0; +} +@end + +// rdar://problem/9123040 +@interface Test1 { +@public + id ivar __attribute__((objc_gc(weak))); +} +@property (assign) id prop __attribute((objc_gc(weak))); +@end +void test1(Test1 *t) { + id *(__attribute__((objc_gc(strong))) x) = &t->ivar; // expected-warning {{initializing '__strong id *' with an expression of type '__weak id *' discards qualifiers}} +} diff --git a/clang/test/SemaObjC/weak-property.m b/clang/test/SemaObjC/weak-property.m new file mode 100644 index 0000000..8a2adf9 --- /dev/null +++ b/clang/test/SemaObjC/weak-property.m @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -verify -Wno-objc-root-class %s +// rdar://8899430 + +@interface WeakPropertyTest { + Class isa; + __weak id value; + id x; +} +@property (weak) id value1; +@property __weak id value; +@property () __weak id value2; + +@property (weak, assign) id v1; // expected-error {{property attributes 'assign' and 'weak' are mutually exclusive}} +@property (weak, copy) id v2; // expected-error {{property attributes 'copy' and 'weak' are mutually exclusive}} +@property (weak, retain) id v3; // expected-error {{property attributes 'retain' and 'weak' are mutually exclusive}} +@property (weak, assign) id v4; // expected-error {{property attributes 'assign' and 'weak' are mutually exclusive}} + +@property () __weak id x; // expected-note {{property declared here}} +@end + +@implementation WeakPropertyTest +@synthesize x; // expected-error {{existing ivar 'x' for __weak property 'x' must be __weak}} +@dynamic value1, value, value2, v1,v2,v3,v4; +@end diff --git a/clang/test/SemaObjC/weak-receiver-warn.m b/clang/test/SemaObjC/weak-receiver-warn.m new file mode 100644 index 0000000..f3955da --- /dev/null +++ b/clang/test/SemaObjC/weak-receiver-warn.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wreceiver-is-weak -verify %s +// rdar://10225276 + +@interface Test0 +- (void) setBlock: (void(^)(void)) block; +- (void) addBlock: (void(^)(void)) block; +- (void) actNow; +@end + +void test0(Test0 *x) { + __weak Test0 *weakx = x; + [x addBlock: ^{ [weakx actNow]; }]; // expected-warning {{weak receiver may be unpredictably null in ARC mode}} + [x setBlock: ^{ [weakx actNow]; }]; // expected-warning {{weak receiver may be unpredictably null in ARC mode}} + x.block = ^{ [weakx actNow]; }; // expected-warning {{weak receiver may be unpredictably null in ARC mode}} + + [weakx addBlock: ^{ [x actNow]; }]; // expected-warning {{weak receiver may be unpredictably null in ARC mode}} + [weakx setBlock: ^{ [x actNow]; }]; // expected-warning {{weak receiver may be unpredictably null in ARC mode}} + weakx.block = ^{ [x actNow]; }; +} diff --git a/clang/test/SemaObjC/writable-property-in-superclass.m b/clang/test/SemaObjC/writable-property-in-superclass.m new file mode 100644 index 0000000..bbd1f16 --- /dev/null +++ b/clang/test/SemaObjC/writable-property-in-superclass.m @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface MessageStore +@property (assign, readonly) int P; +@end + +@interface MessageStore (CAT) +@property (assign) int P; +@end + +@interface NeXTMbox : MessageStore +@end + +@implementation NeXTMbox +- (void) Meth { self.P = 1; } +@end + |