diff options
author | ed <ed@FreeBSD.org> | 2009-06-02 17:58:47 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2009-06-02 17:58:47 +0000 |
commit | f27e5a09a0d815b8a4814152954ff87dadfdefc0 (patch) | |
tree | ce7d964cbb5e39695b71481698f10cb099c23d4a /test/SemaObjC | |
download | FreeBSD-src-f27e5a09a0d815b8a4814152954ff87dadfdefc0.zip FreeBSD-src-f27e5a09a0d815b8a4814152954ff87dadfdefc0.tar.gz |
Import Clang, at r72732.
Diffstat (limited to 'test/SemaObjC')
187 files changed, 6716 insertions, 0 deletions
diff --git a/test/SemaObjC/ContClassPropertyLookup.m b/test/SemaObjC/ContClassPropertyLookup.m new file mode 100644 index 0000000..aa5afa7 --- /dev/null +++ b/test/SemaObjC/ContClassPropertyLookup.m @@ -0,0 +1,18 @@ +// RUN: clang-cc -fsyntax-only -verify %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 diff --git a/test/SemaObjC/DoubleMethod.m b/test/SemaObjC/DoubleMethod.m new file mode 100644 index 0000000..e43c1a0 --- /dev/null +++ b/test/SemaObjC/DoubleMethod.m @@ -0,0 +1,19 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface Subclass +{ + int ivar; +} + +- (void) method; +- (void) method; +@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/test/SemaObjC/access-property-getter.m b/test/SemaObjC/access-property-getter.m new file mode 100644 index 0000000..50a3016 --- /dev/null +++ b/test/SemaObjC/access-property-getter.m @@ -0,0 +1,35 @@ +// RUN: clang-cc -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; +} +@end diff --git a/test/SemaObjC/alias-test-1.m b/test/SemaObjC/alias-test-1.m new file mode 100644 index 0000000..39358cd --- /dev/null +++ b/test/SemaObjC/alias-test-1.m @@ -0,0 +1,31 @@ +// RUN: clang-cc -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/test/SemaObjC/alias-test-2.m b/test/SemaObjC/alias-test-2.m new file mode 100644 index 0000000..e0baf4e --- /dev/null +++ b/test/SemaObjC/alias-test-2.m @@ -0,0 +1,17 @@ +// RUN: clang-cc -fsyntax-only -verify %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; + +@interface MyAlias : AliasForSuper // expected-error {{duplicate interface definition for class 'MyWpModule'}} +@end + +@implementation MyAlias : AliasForSuper // expected-error {{conflicting super class name 'Super'}} +@end + diff --git a/test/SemaObjC/argument-checking.m b/test/SemaObjC/argument-checking.m new file mode 100644 index 0000000..1b6c10d --- /dev/null +++ b/test/SemaObjC/argument-checking.m @@ -0,0 +1,25 @@ +// RUN: clang-cc -fsyntax-only -verify -pedantic %s + +struct S { int a; }; + +extern int charStarFunc(char *); +extern int charFunc(char); + +@interface Test ++alloc; +-(int)charStarMeth:(char *)s; +-structMeth:(struct S)s; +-structMeth:(struct S)s :(struct S)s2; +@end + +void test() { + id obj = [Test alloc]; + struct S sInst; + + charStarFunc(1); // expected-warning {{incompatible integer to pointer conversion passing 'int', expected 'char *'}} + charFunc("abc"); // expected-warning {{incompatible pointer to integer conversion passing 'char [4]', expected 'char'}} + + [obj charStarMeth:1]; // expected-warning {{incompatible integer to pointer conversion sending 'int'}} + [obj structMeth:1]; // expected-error {{incompatible type sending 'int'}} + [obj structMeth:sInst :1]; // expected-error {{incompatible type sending 'int'}} +} diff --git a/test/SemaObjC/at-defs.m b/test/SemaObjC/at-defs.m new file mode 100644 index 0000000..78ce63c --- /dev/null +++ b/test/SemaObjC/at-defs.m @@ -0,0 +1,29 @@ +// RUN: clang-cc -triple i386-unknown-unknown %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/test/SemaObjC/attr-cleanup.m b/test/SemaObjC/attr-cleanup.m new file mode 100644 index 0000000..f4d057b --- /dev/null +++ b/test/SemaObjC/attr-cleanup.m @@ -0,0 +1,10 @@ +// RUN: clang-cc %s -verify -fsyntax-only + +@class NSString; + +void c1(id *a); + +void t1() +{ + NSString *s __attribute((cleanup(c1))); +} diff --git a/test/SemaObjC/attr-deprecated.m b/test/SemaObjC/attr-deprecated.m new file mode 100644 index 0000000..e385a97 --- /dev/null +++ b/test/SemaObjC/attr-deprecated.m @@ -0,0 +1,99 @@ +// RUN: clang-cc %s -fsyntax-only -verify + +@interface A { + int X __attribute__((deprecated)); +} ++ (void)F __attribute__((deprecated)); +- (void)f __attribute__((deprecated)); +@end + +@implementation A ++ (void)F __attribute__((deprecated)) +{ // expected-warning {{method attribute can only be specified on method declarations}} + [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 {{warning: 'FooBar' is deprecated}} + return f.FooBar; // expected-warning {{warning: 'FooBar' is deprecated}} +} + + +__attribute ((deprecated)) +@interface DEPRECATED { + @public int ivar; +} +- (int) instancemethod; +@property int prop; +@end + +@interface DEPRECATED (Category) // expected-warning {{warning: 'DEPRECATED' is deprecated}} +@end + +@interface NS : DEPRECATED // expected-warning {{warning: 'DEPRECATED' is deprecated}} +@end + + diff --git a/test/SemaObjC/attr-objc-exception.m b/test/SemaObjC/attr-objc-exception.m new file mode 100644 index 0000000..3efb8cf --- /dev/null +++ b/test/SemaObjC/attr-objc-exception.m @@ -0,0 +1,16 @@ +// RUN: clang-cc %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/test/SemaObjC/attr-objc-gc.m b/test/SemaObjC/attr-objc-gc.m new file mode 100644 index 0000000..20da639 --- /dev/null +++ b/test/SemaObjC/attr-objc-gc.m @@ -0,0 +1,8 @@ +// RUN: clang-cc -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 requires 1 argument(s)}} +static id __attribute((objc_gc(hello))) f; // expected-warning{{'objc_gc' attribute argument not supported: 'hello'}} diff --git a/test/SemaObjC/bad-receiver-1.m b/test/SemaObjC/bad-receiver-1.m new file mode 100644 index 0000000..64ff3d1 --- /dev/null +++ b/test/SemaObjC/bad-receiver-1.m @@ -0,0 +1,19 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface I +- (id) retain; +@end + +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 'struct __CFString const *') is not 'id'}} \\ + expected-warning {{method '-self' not found}} +} diff --git a/test/SemaObjC/block-attr.m b/test/SemaObjC/block-attr.m new file mode 100644 index 0000000..d67fd35 --- /dev/null +++ b/test/SemaObjC/block-attr.m @@ -0,0 +1,9 @@ +// RUN: clang-cc -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); + + +@end diff --git a/test/SemaObjC/block-ivar.m b/test/SemaObjC/block-ivar.m new file mode 100644 index 0000000..231c9a2 --- /dev/null +++ b/test/SemaObjC/block-ivar.m @@ -0,0 +1,19 @@ +// RUN: clang-cc -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/test/SemaObjC/blocks.m b/test/SemaObjC/blocks.m new file mode 100644 index 0000000..baadbde --- /dev/null +++ b/test/SemaObjC/blocks.m @@ -0,0 +1,46 @@ +// RUN: clang-cc -fsyntax-only -verify -fblocks %s +@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)); +void foo5(id (^objectCreationBlock)(int)) { + return bar5(objectCreationBlock); // expected-error {{incompatible block pointer types passing 'id (^)(int)', expected 'id (^)(void)'}} +} + +void bar6(id(^)(int)); +void foo6(id (^objectCreationBlock)()) { + return bar6(objectCreationBlock); // expected-error {{incompatible block pointer types passing 'id (^)()', expected 'id (^)(int)'}} +} + +void foo7(id (^x)(int)) { + if (x) { } +} + +@interface itf +@end + +void foo8() { + void *P = ^(itf x) {}; // expected-error {{Objective-C interface type 'itf' cannot be passed by value}} + P = ^itf(int x) {}; // expected-error {{Objective-C interface type 'itf' cannot be returned by value}} + P = ^itf() {}; // expected-error {{Objective-C interface type 'itf' cannot be returned by value}} + P = ^itf{}; // expected-error {{Objective-C interface type 'itf' cannot be returned by value}} +} diff --git a/test/SemaObjC/call-super-2.m b/test/SemaObjC/call-super-2.m new file mode 100644 index 0000000..92bec27 --- /dev/null +++ b/test/SemaObjC/call-super-2.m @@ -0,0 +1,98 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +#include <stddef.h> + +typedef struct objc_object *id; +id objc_getClass(const char *s); + +@interface Object +@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; +@end + +@implementation Derived ++ (int) class_func1 +{ + int i = (size_t)[self class_func0]; // expected-warning {{method '-class_func0' not found (return type defaults to 'id')}} + return i + (size_t)[super class_func0]; // expected-warning {{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]; // expected-error {{protocol qualified 'Class' is unsupported}} + return i + [(Class <Func>)super class_func0]; // expected-error {{protocol qualified 'Class' is unsupported}} // 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 {{method '+class_func0' not found (return type defaults to 'id')}} + return i + (size_t)[Object class_func0]; // expected-warning {{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 {{method '-instance_func0' not found (return type defaults to 'id'))}} + return i + (size_t)[super instance_func0]; // expected-warning {{method '-instance_func0' not found (return type defaults to 'id')}} +} +- (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 {{method '+instance_func1' not found (return type defaults to 'id')}} + return i + (size_t)[Object instance_func1]; // expected-warning {{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]; +} +@end + diff --git a/test/SemaObjC/catch-stmt.m b/test/SemaObjC/catch-stmt.m new file mode 100644 index 0000000..6dcbcde --- /dev/null +++ b/test/SemaObjC/catch-stmt.m @@ -0,0 +1,13 @@ +// RUN: clang-cc -verify %s + +@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}} + } +} + diff --git a/test/SemaObjC/category-1.m b/test/SemaObjC/category-1.m new file mode 100644 index 0000000..6ae7758 --- /dev/null +++ b/test/SemaObjC/category-1.m @@ -0,0 +1,56 @@ +// RUN: clang-cc -fsyntax-only -verify %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 MyClass (Category) @end // expected-error {{cannot find interface declaration for 'MyClass'}} + +@class MyClass2; + +@interface MyClass2 (Category) @end // expected-error {{cannot find interface declaration for '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 + + diff --git a/test/SemaObjC/category-method-lookup-2.m b/test/SemaObjC/category-method-lookup-2.m new file mode 100644 index 0000000..76048cc --- /dev/null +++ b/test/SemaObjC/category-method-lookup-2.m @@ -0,0 +1,22 @@ +// RUN: clang-cc -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]; +} + +@end diff --git a/test/SemaObjC/category-method-lookup.m b/test/SemaObjC/category-method-lookup.m new file mode 100644 index 0000000..bda4657 --- /dev/null +++ b/test/SemaObjC/category-method-lookup.m @@ -0,0 +1,31 @@ +// RUN: clang-cc -fsyntax-only -verify %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/test/SemaObjC/check-dup-decl-methods-1.m b/test/SemaObjC/check-dup-decl-methods-1.m new file mode 100644 index 0000000..ae0cab0 --- /dev/null +++ b/test/SemaObjC/check-dup-decl-methods-1.m @@ -0,0 +1,38 @@ +// RUN: clang-cc -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; +- (T*) meth1; ++ (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/test/SemaObjC/check-dup-objc-decls-1.m b/test/SemaObjC/check-dup-objc-decls-1.m new file mode 100644 index 0000000..1dfaf09 --- /dev/null +++ b/test/SemaObjC/check-dup-objc-decls-1.m @@ -0,0 +1,39 @@ +// RUN: clang-cc -fsyntax-only -verify %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'}} diff --git a/test/SemaObjC/class-bitfield.m b/test/SemaObjC/class-bitfield.m new file mode 100644 index 0000000..01b5324 --- /dev/null +++ b/test/SemaObjC/class-bitfield.m @@ -0,0 +1,37 @@ +// RUN: clang-cc %s -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' 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 bitfield width}} +} +@end diff --git a/test/SemaObjC/class-conforming-protocol-1.m b/test/SemaObjC/class-conforming-protocol-1.m new file mode 100644 index 0000000..a9712b2 --- /dev/null +++ b/test/SemaObjC/class-conforming-protocol-1.m @@ -0,0 +1,21 @@ +// RUN: clang-cc -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<P1,P2>*) METH2; +- (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; +- (INTF<P3,P1,P2, P3>*) METH3; + +@end + +INTF<P2,P1,P3>* p1; + diff --git a/test/SemaObjC/class-conforming-protocol-2.m b/test/SemaObjC/class-conforming-protocol-2.m new file mode 100644 index 0000000..7b218bd --- /dev/null +++ b/test/SemaObjC/class-conforming-protocol-2.m @@ -0,0 +1,22 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@protocol NSWindowDelegate @end + +@interface NSWindow +- (void)setDelegate:(id <NSWindowDelegate>)anObject; +- (id <NSWindowDelegate>) delegate; +@end + +@protocol IBStringsTableWindowDelegate <NSWindowDelegate> +@end + +@interface IBStringsTableWindow : NSWindow {} +@end + +@implementation IBStringsTableWindow +- (void)setDelegate:(id <IBStringsTableWindowDelegate>)delegate { +} +- (id <IBStringsTableWindowDelegate>)delegate { + return 0; +} +@end diff --git a/test/SemaObjC/class-def-test-1.m b/test/SemaObjC/class-def-test-1.m new file mode 100644 index 0000000..da8a326 --- /dev/null +++ b/test/SemaObjC/class-def-test-1.m @@ -0,0 +1,33 @@ +// RUN: clang-cc -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 + + diff --git a/test/SemaObjC/class-extension-dup-methods.m b/test/SemaObjC/class-extension-dup-methods.m new file mode 100644 index 0000000..f50b293 --- /dev/null +++ b/test/SemaObjC/class-extension-dup-methods.m @@ -0,0 +1,15 @@ +// RUN: clang-cc -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/test/SemaObjC/class-impl-1.m b/test/SemaObjC/class-impl-1.m new file mode 100644 index 0000000..5a67bef --- /dev/null +++ b/test/SemaObjC/class-impl-1.m @@ -0,0 +1,40 @@ +// RUN: clang-cc -fsyntax-only -verify %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 + +@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; + +@implementation INTF5 { // expected-warning {{cannot find interface declaration for 'INTF5'}} + int x; +} +@end + diff --git a/test/SemaObjC/class-method-lookup.m b/test/SemaObjC/class-method-lookup.m new file mode 100644 index 0000000..cba9382 --- /dev/null +++ b/test/SemaObjC/class-method-lookup.m @@ -0,0 +1,46 @@ +// RUN: clang-cc -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/test/SemaObjC/class-method-self.m b/test/SemaObjC/class-method-self.m new file mode 100644 index 0000000..d36bc8c --- /dev/null +++ b/test/SemaObjC/class-method-self.m @@ -0,0 +1,26 @@ +// RUN: clang-cc -verify %s + +typedef struct objc_class *Class; +@interface XX + +- (void)addObserver:(XX*)o; + +@end + +@interface YY + ++ (void)classMethod; + +@end + +@implementation YY + +static XX *obj; + ++ (void)classMethod { + [obj addObserver:self]; + Class whatever; + [obj addObserver:whatever]; // GCC warns about this. +} +@end + diff --git a/test/SemaObjC/class-property-access.m b/test/SemaObjC/class-property-access.m new file mode 100644 index 0000000..663b87d --- /dev/null +++ b/test/SemaObjC/class-property-access.m @@ -0,0 +1,12 @@ +// RUN: clang -fsyntax-only -verify %s + +@interface Test {} ++ (Test*)one; +- (int)two; +@end + +int main () +{ + return Test.one.two; +} + diff --git a/test/SemaObjC/class-proto-1.m b/test/SemaObjC/class-proto-1.m new file mode 100644 index 0000000..8f0f3d8 --- /dev/null +++ b/test/SemaObjC/class-proto-1.m @@ -0,0 +1,36 @@ +// RUN: clang-cc -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; + +@interface E3 : U1 @end // expected-error {{cannot find interface declaration for 'U1', superclass of 'E3'}} + + +@interface I3 : E3 @end + +@interface U2 @end + +@interface I4 : U2 <p1,p2> +@end diff --git a/test/SemaObjC/cocoa-pth.m b/test/SemaObjC/cocoa-pth.m new file mode 100644 index 0000000..dc806df --- /dev/null +++ b/test/SemaObjC/cocoa-pth.m @@ -0,0 +1,7 @@ +// RUN: clang-cc -mcpu=pentium4 -emit-pth -o %t %s && +// RUN: clang-cc -mcpu=pentium4 -token-cache %t %s && +// RUN: clang-cc -mcpu=pentium4 -token-cache %t %s -E %s -o /dev/null +#ifdef __APPLE__ +#include <Cocoa/Cocoa.h> +#endif + diff --git a/test/SemaObjC/cocoa.m b/test/SemaObjC/cocoa.m new file mode 100644 index 0000000..b73b3c4 --- /dev/null +++ b/test/SemaObjC/cocoa.m @@ -0,0 +1,5 @@ +// RUN: clang-cc -mcpu=pentium4 %s -print-stats +#ifdef __APPLE__ +#include <Cocoa/Cocoa.h> +#endif + diff --git a/test/SemaObjC/compare-qualified-id.m b/test/SemaObjC/compare-qualified-id.m new file mode 100644 index 0000000..86845c0 --- /dev/null +++ b/test/SemaObjC/compare-qualified-id.m @@ -0,0 +1,33 @@ +// RUN: clang-cc -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 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> { + NSMutableDictionary * _propNamesToPropValuesCache; +} @end + +@protocol XCPropertyValues <NSObject, NSCopying> +- (NSString *)evaluateAsStringInContext:(XCPropertyExpansionContext *)context withNestingState:(const void *)state; +@end + +@implementation XCPropertyExpansionContext +- (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; +} + diff --git a/test/SemaObjC/compatible-protocol-qualified-types.m b/test/SemaObjC/compatible-protocol-qualified-types.m new file mode 100644 index 0000000..3c27b5f --- /dev/null +++ b/test/SemaObjC/compatible-protocol-qualified-types.m @@ -0,0 +1,75 @@ +// RUN: clang-cc -pedantic -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 + +@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; +- (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 {{incompatible type sending 'SKTText *', expected 'id<NSTextStorageDelegate>'}} +} + +@end diff --git a/test/SemaObjC/comptypes-1.m b/test/SemaObjC/comptypes-1.m new file mode 100644 index 0000000..8717bd0 --- /dev/null +++ b/test/SemaObjC/comptypes-1.m @@ -0,0 +1,91 @@ +// RUN: clang-cc -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 'MyOtherClass *', expected 'MyClass *'}} + obj_c = obj_C; + + /* 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 {{incompatible type assigning 'MyClass *', expected 'id<MyProtocol>'}} + obj_p = obj_cp; /* Ok */ + obj_p = obj_C; // Ok + + /* 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 'MyClass *', expected 'MyOtherClass *'}} + obj_cp = obj_p; /* Ok */ + obj_cp = obj_C; + + /* 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. */ + /* FIXME: GCC considers this a warning ("comparison of distinct pointer types"). */ + /* There is a corresponding FIXME in ASTContext::mergeTypes() */ + if (obj_p == obj_c) foo() ; + + 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/test/SemaObjC/comptypes-2.m b/test/SemaObjC/comptypes-2.m new file mode 100644 index 0000000..c24b67b --- /dev/null +++ b/test/SemaObjC/comptypes-2.m @@ -0,0 +1,37 @@ +// RUN: clang-cc -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/test/SemaObjC/comptypes-3.m b/test/SemaObjC/comptypes-3.m new file mode 100644 index 0000000..2d8f19d --- /dev/null +++ b/test/SemaObjC/comptypes-3.m @@ -0,0 +1,64 @@ +// RUN: clang-cc -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 {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolA>'}} + obj_a = obj_ab; /* Ok */ + obj_a = obj_ac; /* Ok */ + + obj_b = obj_a; // expected-warning {{incompatible type assigning 'id<MyProtocolA>', expected 'id<MyProtocolB>'}} + obj_b = obj_ab; /* Ok */ + obj_b = obj_ac; // expected-warning {{incompatible type assigning 'id<MyProtocolAC>', expected 'id<MyProtocolB>'}} + + obj_ab = obj_a; // expected-warning {{incompatible type assigning 'id<MyProtocolA>', expected 'id<MyProtocolAB>'}} + obj_ab = obj_b; // expected-warning {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolAB>'}} + obj_ab = obj_ac; // expected-warning {{incompatible type assigning 'id<MyProtocolAC>', expected 'id<MyProtocolAB>'}} + + obj_ac = obj_a; // expected-warning {{incompatible type assigning 'id<MyProtocolA>', expected 'id<MyProtocolAC>'}} + obj_ac = obj_b; // expected-warning {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolAC>'}} + obj_ac = obj_ab; // expected-warning {{incompatible type assigning 'id<MyProtocolAB>', expected 'id<MyProtocolAC>'}} + + if (obj_a == obj_b) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolA>' and 'id<MyProtocolB>')}} + if (obj_b == obj_a) foo (); // expected-warning {{invalid operands to binary expression ('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 {{invalid operands to binary expression ('id<MyProtocolB>' and 'id<MyProtocolAC>')}} + if (obj_ac == obj_b) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolAC>' and 'id<MyProtocolB>')}} + + if (obj_ab == obj_ac) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolAB>' and 'id<MyProtocolAC>')}} + if (obj_ac == obj_ab) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolAC>' and 'id<MyProtocolAB>')}} + + return 0; +} diff --git a/test/SemaObjC/comptypes-4.m b/test/SemaObjC/comptypes-4.m new file mode 100644 index 0000000..5989011 --- /dev/null +++ b/test/SemaObjC/comptypes-4.m @@ -0,0 +1,25 @@ +// RUN: clang-cc -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; + + if (obj_cp == obj_p) + foo(); + + if (obj_p == obj_cp) + foo(); + +} + + diff --git a/test/SemaObjC/comptypes-5.m b/test/SemaObjC/comptypes-5.m new file mode 100644 index 0000000..afd8a49 --- /dev/null +++ b/test/SemaObjC/comptypes-5.m @@ -0,0 +1,44 @@ +// RUN: clang-cc -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; // expected-warning {{incompatible type assigning 'id<MyProtocol>', expected 'MyClass *'}} + obj_c_super_p = obj_id_p; // expected-warning {{incompatible type assigning 'id<MyProtocol>', expected 'MyOtherClass *'}} + 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/test/SemaObjC/comptypes-6.m b/test/SemaObjC/comptypes-6.m new file mode 100644 index 0000000..3217675 --- /dev/null +++ b/test/SemaObjC/comptypes-6.m @@ -0,0 +1,16 @@ +// RUN: clang-cc -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 'Object *', expected 'Derived *'}} + + return m; +} + diff --git a/test/SemaObjC/comptypes-7.m b/test/SemaObjC/comptypes-7.m new file mode 100644 index 0000000..faca693 --- /dev/null +++ b/test/SemaObjC/comptypes-7.m @@ -0,0 +1,70 @@ +// RUN: clang-cc -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 'int', expected 'id'}} + obj = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'id'}} + + obj_p = i; // expected-warning {{incompatible integer to pointer conversion assigning 'int', expected 'id<MyProtocol>'}} + obj_p = j; // expected-warning {{incompatible type assigning 'int *', expected 'id<MyProtocol>'}} + + obj_c = i; // expected-warning {{incompatible integer to pointer conversion assigning 'int', expected 'MyClass *'}} + obj_c = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'MyClass *'}} + + obj_C = i; // expected-warning {{incompatible integer to pointer conversion assigning 'int', expected 'Class'}} + obj_C = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'Class'}} + + i = obj; // expected-warning {{incompatible pointer to integer conversion assigning 'id', expected 'int'}} + i = obj_p; // expected-warning {{incompatible pointer to integer conversion assigning 'id<MyProtocol>', expected 'int'}} + i = obj_c; // expected-warning {{incompatible pointer to integer conversion assigning 'MyClass *', expected 'int'}} + i = obj_C; // expected-warning {{incompatible pointer to integer conversion assigning 'Class', expected 'int'}} + + j = obj; // expected-warning {{incompatible pointer types assigning 'id', expected 'int *'}} + j = obj_p; // expected-warning {{incompatible type assigning 'id<MyProtocol>', expected 'int *'}} + j = obj_c; // expected-warning {{incompatible pointer types assigning 'MyClass *', expected 'int *'}} + j = obj_C; // expected-warning {{incompatible pointer types assigning 'Class', expected 'int *'}} + + 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')}} + + return 0; +} diff --git a/test/SemaObjC/comptypes-8.m b/test/SemaObjC/comptypes-8.m new file mode 100644 index 0000000..af9267e --- /dev/null +++ b/test/SemaObjC/comptypes-8.m @@ -0,0 +1,12 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@protocol MyProtocol +@end + +id<MyProtocol> obj_p = 0; + +int main() +{ + obj_p = 0; +} + diff --git a/test/SemaObjC/comptypes-9.m b/test/SemaObjC/comptypes-9.m new file mode 100644 index 0000000..caa93b4 --- /dev/null +++ b/test/SemaObjC/comptypes-9.m @@ -0,0 +1,86 @@ +// RUN: clang-cc -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/test/SemaObjC/comptypes-a.m b/test/SemaObjC/comptypes-a.m new file mode 100644 index 0000000..936c6df --- /dev/null +++ b/test/SemaObjC/comptypes-a.m @@ -0,0 +1,32 @@ +// RUN: clang-cc -fsyntax-only -verify -pedantic %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) +{ +} + +@interface TedWantsToVerifyObjCDoesTheRightThing + +- compareThis:(int)a withThat:(id)b; // 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 { + return self; +} + +@end diff --git a/test/SemaObjC/comptypes-legal.m b/test/SemaObjC/comptypes-legal.m new file mode 100644 index 0000000..cd7f89b --- /dev/null +++ b/test/SemaObjC/comptypes-legal.m @@ -0,0 +1,37 @@ +// RUN: clang-cc -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; +@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 *)', expected 'FuncSignature *'}} +} diff --git a/test/SemaObjC/conditional-expr-2.m b/test/SemaObjC/conditional-expr-2.m new file mode 100644 index 0000000..0875848 --- /dev/null +++ b/test/SemaObjC/conditional-expr-2.m @@ -0,0 +1,29 @@ +// RUN: clang-cc -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 'NSKey *', expected 'KeySub *'}} +} diff --git a/test/SemaObjC/conditional-expr-3.m b/test/SemaObjC/conditional-expr-3.m new file mode 100644 index 0000000..31d4834 --- /dev/null +++ b/test/SemaObjC/conditional-expr-3.m @@ -0,0 +1,67 @@ +// RUN: clang-cc -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 {{incompatible type initializing 'id<P1>', expected 'id<P0>'}} +} + +void f3(A *a) { + id<P1> l = a; // expected-warning {{incompatible type initializing 'A *', expected 'id<P1>'}} +} + +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); +} + +void f9(int cond, id<P0,P1> x0, id<P0,P2> x1) { + barP1(cond ? x0 : x1); +} + +void f10(int cond, id<P0,P1> x0, id<P0,P2> x1) { + barP2(cond ? x0 : x1); +} + +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/test/SemaObjC/conditional-expr-4.m b/test/SemaObjC/conditional-expr-4.m new file mode 100644 index 0000000..7d50ba6 --- /dev/null +++ b/test/SemaObjC/conditional-expr-4.m @@ -0,0 +1,78 @@ +// RUN: clang-cc -fsyntax-only %s +// XFAIL +// <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; +} + +// 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) { + // This should result in something with id type, currently. This is + // almost certainly wrong and should be fixed. + return (cond ? a : b).x; // expected-error {{member reference base type ('id') is not a structure or union}} +} +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 ('id') 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) { + // GCC regards this as a warning (comparison of distinct Objective-C types lacks a cast) + return a == b; // expected-error {{invalid operands to binary expression}} +} + +int f9(int cond, id<P1> a, A *b) { + return (cond ? a : b).x; // expected-error {{incompatible operand types}} +} diff --git a/test/SemaObjC/conditional-expr.m b/test/SemaObjC/conditional-expr.m new file mode 100644 index 0000000..ec3613b --- /dev/null +++ b/test/SemaObjC/conditional-expr.m @@ -0,0 +1,44 @@ +// RUN: clang-cc -fsyntax-only -verify -pedantic %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; +@end + +@implementation DTFilterOutputStream2 // expected-warning {{incomplete implementation}} expected-warning {{method definition for 'nextOutputStream' not found}} +- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream { + id <DTOutputStreams> nextOutputStream = [self nextOutputStream]; + // GCC warns about both of these. + self = nextOutputStream; // expected-warning {{incompatible type assigning 'id<DTOutputStreams>', expected 'DTFilterOutputStream2 *'}} + return nextOutputStream ? nextOutputStream : self; +} +@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')}} + // GCC warns about both of these as well (no errors). + self = nextOutputStream; // expected-warning {{incompatible type assigning 'id<DTOutputStreams>', expected 'DTFilterOutputStream3 *'}} + return nextOutputStream ? nextOutputStream : self; +} +@end diff --git a/test/SemaObjC/conflicting-ivar-test-1.m b/test/SemaObjC/conflicting-ivar-test-1.m new file mode 100644 index 0000000..20ed157 --- /dev/null +++ b/test/SemaObjC/conflicting-ivar-test-1.m @@ -0,0 +1,86 @@ +// RUN: clang-cc -fsyntax-only -verify %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/test/SemaObjC/continuation-class-err.m b/test/SemaObjC/continuation-class-err.m new file mode 100644 index 0000000..f516a93 --- /dev/null +++ b/test/SemaObjC/continuation-class-err.m @@ -0,0 +1,15 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface ReadOnly +{ + id _object; + id _object1; +} +@property(readonly) id object; +@property(readwrite, assign) id object1; +@end + +@interface ReadOnly () +@property(readwrite, copy) id object; +@property(readonly) id object1; // expected-error {{attribute of property in continuation class of 'ReadOnly' can only be 'readwrite'}} +@end diff --git a/test/SemaObjC/duplicate-ivar-check.m b/test/SemaObjC/duplicate-ivar-check.m new file mode 100644 index 0000000..7cab982 --- /dev/null +++ b/test/SemaObjC/duplicate-ivar-check.m @@ -0,0 +1,22 @@ +// RUN: clang-cc -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/test/SemaObjC/enhanced-proto-2.m b/test/SemaObjC/enhanced-proto-2.m new file mode 100644 index 0000000..0450d7b --- /dev/null +++ b/test/SemaObjC/enhanced-proto-2.m @@ -0,0 +1,21 @@ +// RUN: clang-cc -verify %s + +@protocol MyProto1 +@optional +- (void) FOO; +@optional +- (void) FOO; +@optional +- (void) REQ; +@optional +@end + +@interface MyProto2 <MyProto1> +- (void) FOO2; +- (void) FOO3; +@end + +@implementation MyProto2 +- (void) FOO2{} +- (void) FOO3{} +@end diff --git a/test/SemaObjC/error-property-gc-attr.m b/test/SemaObjC/error-property-gc-attr.m new file mode 100644 index 0000000..a44ba4f --- /dev/null +++ b/test/SemaObjC/error-property-gc-attr.m @@ -0,0 +1,27 @@ +// RUN: clang-cc -triple i386-apple-darwin9 -fobjc-gc -fsyntax-only -verify %s + +@interface INTF +{ + id IVAR; + __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 a __strong property 'not' must be garbage collectable}} +@synthesize WID; +@synthesize ID; +@synthesize AWEAK; // expected-error {{existing ivar 'AWEAK' for a __strong property 'AWEAK' must be garbage collectable}} +@synthesize WI; +@end diff --git a/test/SemaObjC/exprs.m b/test/SemaObjC/exprs.m new file mode 100644 index 0000000..d51d135 --- /dev/null +++ b/test/SemaObjC/exprs.m @@ -0,0 +1,21 @@ +// RUN: clang-cc %s -fsyntax-only -verify + +// rdar://6597252 +Class test1(Class X) { + return 1 ? X : X; +} + + +// rdar://6079877 +void test2() { + id str = @"foo" + "bar\0" // expected-warning {{literal contains NUL character}} + @"baz" " blarg"; + id str2 = @"foo" + "bar" + @"baz" + " b\0larg"; // expected-warning {{literal contains NUL character}} + + + if (@encode(int) == "foo") { } // expected-warning {{result of comparison against @encode is unspecified}} +} diff --git a/test/SemaObjC/foreach.m b/test/SemaObjC/foreach.m new file mode 100644 index 0000000..f136adf --- /dev/null +++ b/test/SemaObjC/foreach.m @@ -0,0 +1,18 @@ +/* RUN: clang-cc -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); +} diff --git a/test/SemaObjC/format-arg-attribute.m b/test/SemaObjC/format-arg-attribute.m new file mode 100644 index 0000000..60cc7cb --- /dev/null +++ b/test/SemaObjC/format-arg-attribute.m @@ -0,0 +1,28 @@ +// RUN: clang-cc -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 requires 1 argument(s)}} +extern void fc2 (const NSString *) __attribute__((format_arg())); // expected-error {{attribute requires 1 argument(s)}} +extern void fc3 (const NSString *) __attribute__((format_arg(1, 2))); // expected-error {{attribute requires 1 argument(s)}} + +struct s1 { int i; } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to function types}} +union u1 { int i; } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to function types}} +// FIXME: We don't flag this yet. +enum e1 { E1V0 } __attribute__((format_arg(1))); /* { dg-error "does not apply|only applies" "format_arg on enum" } */ + +extern NSString *ff3 (const NSString *) __attribute__((format_arg(3-2))); +extern NSString *ff4 (const NSString *) __attribute__((format_arg(foo))); // expected-error {{attribute requires 1 argument(s)}} + +/* 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/test/SemaObjC/format-strings-objc.m b/test/SemaObjC/format-strings-objc.m new file mode 100644 index 0000000..4b84902 --- /dev/null +++ b/test/SemaObjC/format-strings-objc.m @@ -0,0 +1,43 @@ +// RUN: clang-cc -fsyntax-only -verify %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. +//===----------------------------------------------------------------------===// + +typedef signed char BOOL; +typedef unsigned int NSUInteger; +@class NSString, Protocol; +extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); +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))); + +//===----------------------------------------------------------------------===// +// Test cases. +//===----------------------------------------------------------------------===// + +void check_nslog(unsigned k) { + NSLog(@"%d%%", k); // no-warning + NSLog(@"%s%lb%d", "unix", 10,20); // expected-warning {{lid conversion '%lb'}} +} + +// 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}} diff --git a/test/SemaObjC/forward-class-1.m b/test/SemaObjC/forward-class-1.m new file mode 100644 index 0000000..f5f9505 --- /dev/null +++ b/test/SemaObjC/forward-class-1.m @@ -0,0 +1,47 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@class FOO, BAR; +@class FOO, BAR; + +@interface INTF : FOO // expected-error {{cannot find interface declaration for 'FOO', 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; + +@interface XCElementMainImp { + XCElement * _editingElement; +} +@end + +@class XCElement; + +@implementation XCElementMainImp +- (XCElement *)editingElement { return _editingElement; } +@end + + diff --git a/test/SemaObjC/forward-class-receiver.m b/test/SemaObjC/forward-class-receiver.m new file mode 100644 index 0000000..ebba0fd --- /dev/null +++ b/test/SemaObjC/forward-class-receiver.m @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface I ++ new; // expected-note {{method 'new' is used for the forward class}} +@end +Class isa; + +@class NotKnown; + +void foo(NotKnown *n) { + [isa new]; + [NotKnown new]; /* expected-warning {{receiver 'NotKnown' is a forward class and corresponding}} */ +} diff --git a/test/SemaObjC/gcc-cast-ext.m b/test/SemaObjC/gcc-cast-ext.m new file mode 100644 index 0000000..5d6670e --- /dev/null +++ b/test/SemaObjC/gcc-cast-ext.m @@ -0,0 +1,24 @@ +// RUN: clang-cc %s -verify -fms-extensions +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; +typedef struct _NSRange { } NSRange; + +@class PBXFileReference; + +@interface PBXDocBookmark ++ alloc; +- autorelease; +@end + +// GCC allows pointer expressions in integer constant expressions. +struct { + char control[((int)(char *)2)]; +} xx; + +@implementation PBXDocBookmark // expected-warning {{incomplete implementation}} expected-warning {{method definition for 'autorelease' not found}} expected-warning {{method definition for 'alloc' not found}} + ++ (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/test/SemaObjC/id.m b/test/SemaObjC/id.m new file mode 100644 index 0000000..1781ce7 --- /dev/null +++ b/test/SemaObjC/id.m @@ -0,0 +1,20 @@ +// RUN: clang-cc -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; T = S; + R = T; T = R; + R = S; S = R; +} + +// Test attempt to redefine 'id' in an incompatible fashion. +typedef int id; // expected-error {{typedef redefinition with different types}} +id b; + diff --git a/test/SemaObjC/id_builtin.m b/test/SemaObjC/id_builtin.m new file mode 100644 index 0000000..1347537 --- /dev/null +++ b/test/SemaObjC/id_builtin.m @@ -0,0 +1,10 @@ +// RUN: clang-cc %s -fsyntax-only -verify + +// id is now builtin. There should be no errors. +id obj; + +@interface Foo + +- defaultToId; + +@end diff --git a/test/SemaObjC/ignore-weakimport-method.m b/test/SemaObjC/ignore-weakimport-method.m new file mode 100644 index 0000000..369d902 --- /dev/null +++ b/test/SemaObjC/ignore-weakimport-method.m @@ -0,0 +1,7 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface foo ++ (void) cx __attribute__((weak_import)); +- (void) x __attribute__((weak_import)); +@end + diff --git a/test/SemaObjC/incompatible-protocol-qualified-types.m b/test/SemaObjC/incompatible-protocol-qualified-types.m new file mode 100644 index 0000000..862265c --- /dev/null +++ b/test/SemaObjC/incompatible-protocol-qualified-types.m @@ -0,0 +1,40 @@ +// RUN: clang-cc -pedantic -fsyntax-only -verify %s + +@protocol MyProto1 +@end + +@protocol MyProto2 +@end + +@interface INTF @end + +INTF <MyProto1> * Func(INTF <MyProto1, MyProto2> *p2) +{ + 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> *', expected 'INTF<MyProto1,MyProto2> *}} + return p2; // expected-warning {{incompatible pointer types returning 'INTF<MyProto1> *', expected 'INTF<MyProto1,MyProto2> *}} +} + + + +INTF <MyProto1> * Func3(INTF <MyProto2> *p2) +{ + return p2; // expected-warning {{incompatible pointer types returning 'INTF<MyProto2> *', expected 'INTF<MyProto1> *}} +} + + +INTF <MyProto1, MyProto2> * Func4(INTF <MyProto2, MyProto1> *p2) +{ + return p2; +} + diff --git a/test/SemaObjC/inst-method-lookup-in-root.m b/test/SemaObjC/inst-method-lookup-in-root.m new file mode 100644 index 0000000..93f28e6 --- /dev/null +++ b/test/SemaObjC/inst-method-lookup-in-root.m @@ -0,0 +1,27 @@ +// RUN: clang-cc -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/test/SemaObjC/interface-1.m b/test/SemaObjC/interface-1.m new file mode 100644 index 0000000..85a2a91 --- /dev/null +++ b/test/SemaObjC/interface-1.m @@ -0,0 +1,38 @@ +// RUN: clang-cc -triple i386-apple-darwin9 %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/test/SemaObjC/interface-layout-2.m b/test/SemaObjC/interface-layout-2.m new file mode 100644 index 0000000..ec03a00 --- /dev/null +++ b/test/SemaObjC/interface-layout-2.m @@ -0,0 +1,16 @@ +// RUN: clang-cc %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/test/SemaObjC/interface-layout.m b/test/SemaObjC/interface-layout.m new file mode 100644 index 0000000..6ad8915 --- /dev/null +++ b/test/SemaObjC/interface-layout.m @@ -0,0 +1,27 @@ +// RUN: clang-cc %s -fsyntax-only -verify -triple i386-apple-darwin9 +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/test/SemaObjC/interface-scope-2.m b/test/SemaObjC/interface-scope-2.m new file mode 100644 index 0000000..d054e71 --- /dev/null +++ b/test/SemaObjC/interface-scope-2.m @@ -0,0 +1,126 @@ +// RUN: clang-cc -fsyntax-only -verify -triple i686-apple-darwin9 %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]); +} +@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)); + } +} +@end + +@interface Blah { + struct X { + int x; + } value; +} +@end + +@implementation Blah +- (int)getValue { + struct X *xp = &value; + return xp->x; +} +@end diff --git a/test/SemaObjC/interface-scope.m b/test/SemaObjC/interface-scope.m new file mode 100644 index 0000000..b4dfff6 --- /dev/null +++ b/test/SemaObjC/interface-scope.m @@ -0,0 +1,12 @@ +// RUN: clang-cc -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/test/SemaObjC/interface-tu-variable.m b/test/SemaObjC/interface-tu-variable.m new file mode 100644 index 0000000..9bf816a --- /dev/null +++ b/test/SemaObjC/interface-tu-variable.m @@ -0,0 +1,26 @@ +// RUN: clang-cc -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/test/SemaObjC/invalid-code.m b/test/SemaObjC/invalid-code.m new file mode 100644 index 0000000..6eacba0 --- /dev/null +++ b/test/SemaObjC/invalid-code.m @@ -0,0 +1,7 @@ +// RUN: clang-cc %s -fsyntax-only -verify + +// rdar://6124613 +void test1() { + void *p = @1; // expected-error {{unexpected '@' in program}} +} + diff --git a/test/SemaObjC/invalid-objc-decls-1.m b/test/SemaObjC/invalid-objc-decls-1.m new file mode 100644 index 0000000..e3a94f6 --- /dev/null +++ b/test/SemaObjC/invalid-objc-decls-1.m @@ -0,0 +1,34 @@ +// RUN: clang-cc -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 interface type 'Super' cannot be returned by value}} + Super parm1) { // expected-error{{interface interface type 'Super' cannot be passed by value}} + Super p1; // expected-error{{interface type cannot be statically allocated}} + return p1; +} diff --git a/test/SemaObjC/invalid-receiver.m b/test/SemaObjC/invalid-receiver.m new file mode 100644 index 0000000..e79df96 --- /dev/null +++ b/test/SemaObjC/invalid-receiver.m @@ -0,0 +1,9 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +typedef struct NotAClass { + int a, b; +} NotAClass; + +void foo() { + [NotAClass nonexistent_method]; // expected-error {{invalid receiver to message expression}} +} diff --git a/test/SemaObjC/invalid-typename.m b/test/SemaObjC/invalid-typename.m new file mode 100644 index 0000000..4077f91 --- /dev/null +++ b/test/SemaObjC/invalid-typename.m @@ -0,0 +1,12 @@ +// RUN: clang-cc -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/test/SemaObjC/ivar-access-package.m b/test/SemaObjC/ivar-access-package.m new file mode 100644 index 0000000..77a15cc --- /dev/null +++ b/test/SemaObjC/ivar-access-package.m @@ -0,0 +1,45 @@ +// RUN: clang-cc -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 + +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/test/SemaObjC/ivar-access-tests.m b/test/SemaObjC/ivar-access-tests.m new file mode 100644 index 0000000..ca3cc4c --- /dev/null +++ b/test/SemaObjC/ivar-access-tests.m @@ -0,0 +1,122 @@ +// RUN: clang-cc -fsyntax-only -verify %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/test/SemaObjC/ivar-lookup.m b/test/SemaObjC/ivar-lookup.m new file mode 100644 index 0000000..b168976 --- /dev/null +++ b/test/SemaObjC/ivar-lookup.m @@ -0,0 +1,18 @@ +// RUN: clang-cc %s -fsyntax-only -verify + +@interface Test { + int x; +} + +-(void) setX: (int) d; +@end + +extern struct foo x; + +@implementation Test + +-(void) setX: (int) n { + x = n; +} + +@end diff --git a/test/SemaObjC/ivar-ref-misuse.m b/test/SemaObjC/ivar-ref-misuse.m new file mode 100644 index 0000000..85ede57 --- /dev/null +++ b/test/SemaObjC/ivar-ref-misuse.m @@ -0,0 +1,41 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface Sprite { + 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 {{use of undeclared identifier 'sprite'}} + spree = foo; + Xsprite = foo; // expected-error {{use of undeclared identifier 'Xsprite'}} + 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/test/SemaObjC/ivar-sem-check-1.m b/test/SemaObjC/ivar-sem-check-1.m new file mode 100644 index 0000000..957abc3 --- /dev/null +++ b/test/SemaObjC/ivar-sem-check-1.m @@ -0,0 +1,19 @@ +// RUN: clang-cc -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/test/SemaObjC/ivar-sem-check-2.m b/test/SemaObjC/ivar-sem-check-2.m new file mode 100644 index 0000000..ba6b389 --- /dev/null +++ b/test/SemaObjC/ivar-sem-check-2.m @@ -0,0 +1,23 @@ +// RUN: clang-cc -fsyntax-only -triple x86_64-apple-darwin10 -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/test/SemaObjC/legacy-implementation-1.m b/test/SemaObjC/legacy-implementation-1.m new file mode 100644 index 0000000..63768ff --- /dev/null +++ b/test/SemaObjC/legacy-implementation-1.m @@ -0,0 +1,11 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@implementation INTF // expected-warning {{cannot find interface declaration for 'INTF'}} +@end + +INTF* pi; + +INTF* FUNC() +{ + return pi; +} diff --git a/test/SemaObjC/message.m b/test/SemaObjC/message.m new file mode 100644 index 0000000..7b6a4ee --- /dev/null +++ b/test/SemaObjC/message.m @@ -0,0 +1,100 @@ +// RUN: clang-cc -fsyntax-only -verify %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 'id', expected 'int'}} + int b = [S somemsg]; // expected-error {{bad receiver type 'struct S'}} +} + +// PR4021 +void foo4() { + struct objc_object X[10]; + + [X rect]; +} + diff --git a/test/SemaObjC/method-arg-decay.m b/test/SemaObjC/method-arg-decay.m new file mode 100644 index 0000000..4b04591 --- /dev/null +++ b/test/SemaObjC/method-arg-decay.m @@ -0,0 +1,95 @@ +// RUN: clang-cc -checker-cfref -verify %s +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 extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); +@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value; +@end @class NSString, NSData, NSMutableData, NSMutableDictionary, NSMutableArray; +typedef struct { +} + NSFastEnumerationState; +@protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; +@end @class NSString; +typedef struct _NSRange { +} + NSRange; +@interface NSValue (NSValueRangeExtensions) + (NSValue *)valueWithRange:(NSRange)range; +- (id)objectAtIndex:(NSUInteger)index; +@end typedef unsigned short unichar; +@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; +@end @class NSArray, NSDictionary, NSString, NSError; +@interface NSSet : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count; +@end extern NSString *NSAccessibilityRoleDescription(NSString *role, NSString *subrole) ; +@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; +@interface NSWindowController : NSResponder <NSCoding> { +} +@end @class NSArray, NSFont, NSTabViewItem; +@interface NSTabView : NSView { +} +- (NSArray *)tabViewItems; +- (NSString *)label; +@end typedef enum { +PBXNoItemChanged = 0x00, PBXProjectItemChanged = 0x01, PBXReferenceChanged = 0x02, PBXGroupChanged = 0x04, PBXTargetChanged = 0x08, PBXBuildPhaseChanged = 0x10, PBXBuildFileChanged = 0x20, PBXBreakpointChanged = 0x40, } + PBXArchiveMask; +@interface PBXModule : NSWindowController { +} +@end typedef enum { +PBXFindMatchContains, PBXFindMatchStartsWith, PBXFindMatchWholeWords, PBXFindMatchEndsWith } + PBXFindMatchStyle; +@protocol PBXSelectableText - (NSString *)selectedString; +@end @protocol PBXFindableText <PBXSelectableText> - (BOOL)findText:(NSString *)string ignoreCase:(BOOL)ignoreCase matchStyle:(PBXFindMatchStyle)matchStyle backwards:(BOOL)backwards wrap:(BOOL)wrap; +@end @class PBXProjectDocument, PBXProject, PBXAttributedStatusView; +@interface PBXProjectModule : PBXModule <PBXFindableText> { +} +@end @class PBXBookmark; +@protocol PBXSelectionTarget - (NSObject <PBXSelectionTarget> *) performAction:(id)action withSelection:(NSArray *)selection; +@end @class XCPropertyDictionary, XCPropertyCondition, XCPropertyConditionSet, XCMutablePropertyConditionSet; +extern NSMutableArray *XCFindPossibleKeyModules(PBXModule *module, BOOL useExposedModulesOnly); +@interface NSString (StringUtilities) - (NSString *) trimToLength:(NSInteger)length preserveRange:(NSRange)range; +- (id) objectOfType:(Class)type matchingFunction:(BOOL (void *, void *))comparator usingData:(void *)data; +@end @class XCControlView; +@protocol XCDockViewHeader - (NSImage *) headerImage; +@end @class XCDockableTabModule; +@interface XCExtendedTabView : NSTabView <XCDockViewHeader> { +} +@end @class PBXProjectDocument, PBXFileReference, PBXModule, XCWindowTool; +@interface XCPerspectiveModule : PBXProjectModule <PBXSelectionTarget> { + XCExtendedTabView *_perspectivesTabView; +} +- (PBXModule *) moduleForTab:(NSTabViewItem *)item; +@end +@implementation XCPerspectiveModule ++ (void) openForProjectDocument:(PBXProjectDocument *)projectDocument { +} +- (PBXModule *) type:(Class)type inPerspective:(id)perspectiveIdentifer matchingFunction:(BOOL (void *, void *))comparator usingData:(void *)data { + NSArray *allItems = [_perspectivesTabView tabViewItems]; + NSInteger i, c = [allItems count]; + for (i = 0; + i < c; + i++) { + NSTabViewItem *item = [allItems objectAtIndex:i]; + if ([[item label] isEqual:perspectiveIdentifer]) { + PBXProjectModule *pModule = (PBXProjectModule *)[self moduleForTab:item]; + PBXModule *obj = [XCFindPossibleKeyModules(pModule, (BOOL)0) objectOfType:type matchingFunction:comparator usingData:data]; + } + } +} +- (BOOL)buffer:(char *)buf containsAnyPrompts:(char *[])prompts +{ + prompts++; + return (BOOL)0; +} diff --git a/test/SemaObjC/method-attributes.m b/test/SemaObjC/method-attributes.m new file mode 100644 index 0000000..c4d4fba --- /dev/null +++ b/test/SemaObjC/method-attributes.m @@ -0,0 +1,32 @@ +// RUN: clang-cc -verify -fsyntax-only %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; + +- (int) foo2: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)); +@end + +@implementation INTF +- (int) foo: (int)arg1 __attribute__((deprecated)){ // expected-warning {{method attribute can only be specified}} + return 10; +} +- (int) foo1: (int)arg1 { + return 10; +} +- (int) foo2: (int)arg1 __attribute__((deprecated)) { // expected-warning {{method attribute can only be specified}} + return 10; +} +@end + diff --git a/test/SemaObjC/method-bad-param.m b/test/SemaObjC/method-bad-param.m new file mode 100644 index 0000000..f797188 --- /dev/null +++ b/test/SemaObjC/method-bad-param.m @@ -0,0 +1,30 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface foo +@end + +@implementation foo +@end + +@interface bar +-(void) my_method:(foo) my_param; // expected-error {{Objective-C interface type 'foo' cannot be passed by value}} +- (foo)cccccc:(long)ddddd; // expected-error {{Objective-C interface type 'foo' cannot be returned by value}} +@end + +@implementation bar +-(void) my_method:(foo) my_param // expected-error {{Objective-C interface type 'foo' cannot be passed by value}} +{ +} +- (foo)cccccc:(long)ddddd // expected-error {{Objective-C interface type 'foo' cannot be returned by value}} +{ +} +@end + +void somefunc(foo x) {} // expected-error {{Objective-C interface type 'foo' cannot be passed by value}} +foo somefunc2() {} // expected-error {{Objective-C interface type 'foo' cannot be returned by value}} + +// rdar://6780761 +void f0(foo *a0) { + extern void g0(int x, ...); + g0(1, *(foo*)0); // expected-error {{cannot pass object with interface type 'foo' by-value through variadic function}} +} diff --git a/test/SemaObjC/method-conflict.m b/test/SemaObjC/method-conflict.m new file mode 100644 index 0000000..7a9b9f0 --- /dev/null +++ b/test/SemaObjC/method-conflict.m @@ -0,0 +1,53 @@ +// RUN: clang-cc -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); +@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; +@end +@class NSString; +@implementation XDSCClassFormatter + ++ appendVisibility: (id <XDUMLNamedElement>) element withSpecification: (XDSCDisplaySpecification *) displaySpec to: (NSMutableAttributedString *) attributedString +{ +} ++ (NSUInteger) compartmentsForClassifier: (id <XDSCClassifier>) classifier withSpecification: (XDSCDisplaySpecification *) displaySpec { +} +@end diff --git a/test/SemaObjC/method-def-1.m b/test/SemaObjC/method-def-1.m new file mode 100644 index 0000000..3eb94b9 --- /dev/null +++ b/test/SemaObjC/method-def-1.m @@ -0,0 +1,40 @@ +// RUN: clang-cc -fsyntax-only -verify %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/test/SemaObjC/method-def-2.m b/test/SemaObjC/method-def-2.m new file mode 100644 index 0000000..84cdd70 --- /dev/null +++ b/test/SemaObjC/method-def-2.m @@ -0,0 +1,19 @@ +// RUN: clang-cc -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/test/SemaObjC/method-encoding-2.m b/test/SemaObjC/method-encoding-2.m new file mode 100644 index 0000000..64a0bc4 --- /dev/null +++ b/test/SemaObjC/method-encoding-2.m @@ -0,0 +1,12 @@ +// RUN: clang-cc %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{} +- (id) another:(void *)location with:(unsigned **)arg2 {} +@end diff --git a/test/SemaObjC/method-lookup-2.m b/test/SemaObjC/method-lookup-2.m new file mode 100644 index 0000000..dd0bca9 --- /dev/null +++ b/test/SemaObjC/method-lookup-2.m @@ -0,0 +1,62 @@ +// RUN: clang-cc -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 {} +-(int) run {} ++(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]; +} + +@end diff --git a/test/SemaObjC/method-lookup-3.m b/test/SemaObjC/method-lookup-3.m new file mode 100644 index 0000000..8ed583f --- /dev/null +++ b/test/SemaObjC/method-lookup-3.m @@ -0,0 +1,52 @@ +// RUN: clang-cc -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]; +} diff --git a/test/SemaObjC/method-lookup-4.m b/test/SemaObjC/method-lookup-4.m new file mode 100644 index 0000000..3b2548b --- /dev/null +++ b/test/SemaObjC/method-lookup-4.m @@ -0,0 +1,62 @@ +// RUN: clang-cc -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/test/SemaObjC/method-lookup.m b/test/SemaObjC/method-lookup.m new file mode 100644 index 0000000..917ad6b --- /dev/null +++ b/test/SemaObjC/method-lookup.m @@ -0,0 +1,34 @@ +// RUN: clang-cc -fsyntax-only -verify %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]]]; + } + } +} +@end + diff --git a/test/SemaObjC/method-no-context.m b/test/SemaObjC/method-no-context.m new file mode 100644 index 0000000..9351cb9 --- /dev/null +++ b/test/SemaObjC/method-no-context.m @@ -0,0 +1,4 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +- im0 { int a; return 0; // expected-error{{missing context for method declaration}} +// expected-error{{expected '}'}} diff --git a/test/SemaObjC/method-not-defined.m b/test/SemaObjC/method-not-defined.m new file mode 100644 index 0000000..3848fa2 --- /dev/null +++ b/test/SemaObjC/method-not-defined.m @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface Foo +@end + +void test() { + Foo *fooObj; + id obj; + + [[Foo alloc] init]; // expected-warning {{method '+alloc' not found (return type defaults to 'id')}} expected-warning {{method '-init' not found (return type defaults to 'id')}} + [fooObj notdefined]; // expected-warning {{method '-notdefined' not found (return type defaults to 'id')}} + [obj whatever:1 :2 :3]; // expected-warning {{method '-whatever:::' not found (return type defaults to 'id'))}} +} diff --git a/test/SemaObjC/method-sentinel-attr.m b/test/SemaObjC/method-sentinel-attr.m new file mode 100644 index 0000000..8f31e9a --- /dev/null +++ b/test/SemaObjC/method-sentinel-attr.m @@ -0,0 +1,37 @@ +// RUN: clang-cc -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 requires 0, 1 or 2 argument(s)}} +- (void) foo12 : (int)x, ... ATTR; // expected-note {{method has been explicitly marked sentinel here}} +@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}} +} + diff --git a/test/SemaObjC/method-typecheck-1.m b/test/SemaObjC/method-typecheck-1.m new file mode 100644 index 0000000..d110c85 --- /dev/null +++ b/test/SemaObjC/method-typecheck-1.m @@ -0,0 +1,37 @@ +// RUN: clang-cc -fsyntax-only -verify %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 {} // expected-warning {{conflicting return type in implementation of 'setMoo1:': 'int' vs 'char'}} +- (int) setOk : (int) x : (double) d {} +@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 {} // 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 {} // expected-warning {{conflicting parameter types in implementation of 'setCat:': 'int' vs 'float'}} ++ (int) cCat: (int) x {} // expected-warning {{conflicting return type in implementation of 'cCat:': 'void' vs 'int'}} +@end + diff --git a/test/SemaObjC/method-typecheck-2.m b/test/SemaObjC/method-typecheck-2.m new file mode 100644 index 0000000..d0a091d --- /dev/null +++ b/test/SemaObjC/method-typecheck-2.m @@ -0,0 +1,25 @@ +// RUN: clang-cc -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/test/SemaObjC/method-undef-category-warn-1.m b/test/SemaObjC/method-undef-category-warn-1.m new file mode 100644 index 0000000..82fd3c8 --- /dev/null +++ b/test/SemaObjC/method-undef-category-warn-1.m @@ -0,0 +1,32 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface MyClass1 +@end + +@protocol P +- (void) Pmeth; +- (void) Pmeth1; +@end + +@interface MyClass1(CAT) <P> +- (void) meth2; +@end + +@implementation MyClass1(CAT) // expected-warning {{incomplete implementation}} \ + expected-warning {{method definition for 'meth2' not found}} \ + expected-warning {{method definition for 'Pmeth' not found}} +- (void) Pmeth1{} +@end + +@interface MyClass1(DOG) <P> +- (void)ppp; +@end + +@implementation MyClass1(DOG) // expected-warning {{incomplete implementation}} \ + expected-warning {{method definition for 'ppp' not found}} \ + expected-warning {{method definition for 'Pmeth1' not found}} +- (void) Pmeth {} +@end + +@implementation MyClass1(CAT1) +@end diff --git a/test/SemaObjC/method-undef-extension-warn-1.m b/test/SemaObjC/method-undef-extension-warn-1.m new file mode 100644 index 0000000..7ce015f --- /dev/null +++ b/test/SemaObjC/method-undef-extension-warn-1.m @@ -0,0 +1,25 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface MyClass +@end + +@protocol P +- (void)Pmeth; +- (void)Pmeth1; +@end + +// Class extension +@interface MyClass () <P> +- (void)meth2; +@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 definition for 'meth2' not found}} \ + expected-warning {{method definition for 'Pmeth1' not found}} +- (void)Pmeth {} +@end diff --git a/test/SemaObjC/method-undefined-warn-1.m b/test/SemaObjC/method-undefined-warn-1.m new file mode 100644 index 0000000..fbb01df --- /dev/null +++ b/test/SemaObjC/method-undefined-warn-1.m @@ -0,0 +1,42 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface INTF +- (void) meth; +- (void) meth : (int) arg1; +- (int) int_meth; ++ (int) cls_meth; ++ (void) cls_meth1 : (int) arg1; +@end + +@implementation INTF // expected-warning {{incomplete implementation}} expected-warning {{method definition for 'int_meth' not found}} expected-warning {{method definition for 'cls_meth' not found}} expected-warning {{method definition for 'cls_meth1:' not found}} +- (void) meth {} +- (void) meth : (int) arg2{} +- (void) cls_meth1 : (int) arg2{} +@end + +@interface INTF1 +- (void) meth; +- (void) meth : (int) arg1; +- (int) int_meth; ++ (int) cls_meth; ++ (void) cls_meth1 : (int) arg1; +@end + +@implementation INTF1 // expected-warning {{incomplete implementation}} expected-warning {{method definition for 'int_meth' not found}} expected-warning {{method definition for 'cls_meth' not found}} expected-warning {{method definition for 'cls_meth1:' not found}} +- (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 + diff --git a/test/SemaObjC/missing-method-context.m b/test/SemaObjC/missing-method-context.m new file mode 100644 index 0000000..2d0758b --- /dev/null +++ b/test/SemaObjC/missing-method-context.m @@ -0,0 +1,4 @@ +// RUN: clang-cc %s -verify -fsyntax-only +- (void)compilerTestAgainst; // expected-error {{missing context for method declaration}} + +void xx(); // expected-error {{expected method body}} diff --git a/test/SemaObjC/newproperty-class-method-1.m b/test/SemaObjC/newproperty-class-method-1.m new file mode 100644 index 0000000..4946210 --- /dev/null +++ b/test/SemaObjC/newproperty-class-method-1.m @@ -0,0 +1,60 @@ +// RUN: clang-cc %s -verify -fsyntax-only + +@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/test/SemaObjC/no-gc-weak-test.m b/test/SemaObjC/no-gc-weak-test.m new file mode 100644 index 0000000..f494929 --- /dev/null +++ b/test/SemaObjC/no-gc-weak-test.m @@ -0,0 +1,28 @@ +// RUN: clang-cc -triple i386-apple-darwin9 -fsyntax-only -verify %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/test/SemaObjC/no-warn-synth-protocol-meth.m b/test/SemaObjC/no-warn-synth-protocol-meth.m new file mode 100644 index 0000000..860a0ca --- /dev/null +++ b/test/SemaObjC/no-warn-synth-protocol-meth.m @@ -0,0 +1,17 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@protocol CYCdef +- (int)name; +@end + +@interface JSCdef <CYCdef> { + int name; +} + +@property (assign) int name; +@end + +@implementation JSCdef +@synthesize name; +@end + diff --git a/test/SemaObjC/no-warn-unimpl-method.m b/test/SemaObjC/no-warn-unimpl-method.m new file mode 100644 index 0000000..756c47b --- /dev/null +++ b/test/SemaObjC/no-warn-unimpl-method.m @@ -0,0 +1,42 @@ +// RUN: clang-cc -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 {} +@end diff --git a/test/SemaObjC/nsobject-attribute-1.m b/test/SemaObjC/nsobject-attribute-1.m new file mode 100644 index 0000000..d1f673a --- /dev/null +++ b/test/SemaObjC/nsobject-attribute-1.m @@ -0,0 +1,48 @@ +// RUN: clang-cc -fblocks -fsyntax-only -verify %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/test/SemaObjC/nsobject-attribute.m b/test/SemaObjC/nsobject-attribute.m new file mode 100644 index 0000000..3544cb1 --- /dev/null +++ b/test/SemaObjC/nsobject-attribute.m @@ -0,0 +1,36 @@ +// RUN: clang-cc -fsyntax-only -verify %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; +@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; +@end + +int main(char *argc, char *argv[]) { + HandTested *to; + to.x = tmp; // setter + if (tmp != to.x) + to.x = tmp; + return 0; +} + diff --git a/test/SemaObjC/objc-string-constant.m b/test/SemaObjC/objc-string-constant.m new file mode 100644 index 0000000..9823922 --- /dev/null +++ b/test/SemaObjC/objc-string-constant.m @@ -0,0 +1,39 @@ +// RUN: clang-cc %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; +{ + NSMutableString *result = nil; + + return (result != nil) ? result : @""; +} +@end + diff --git a/test/SemaObjC/objc2-merge-gc-attribue-decl.m b/test/SemaObjC/objc2-merge-gc-attribue-decl.m new file mode 100644 index 0000000..4e3b3ec --- /dev/null +++ b/test/SemaObjC/objc2-merge-gc-attribue-decl.m @@ -0,0 +1,12 @@ +// RUN: clang-cc -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(); + diff --git a/test/SemaObjC/objc2-warn-weak-decl.m b/test/SemaObjC/objc2-warn-weak-decl.m new file mode 100644 index 0000000..5de52ba --- /dev/null +++ b/test/SemaObjC/objc2-warn-weak-decl.m @@ -0,0 +1,10 @@ +// RUN: clang-cc -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 {{__weak attribute cannot be specified on an automatic variable}} +} + diff --git a/test/SemaObjC/property-10.m b/test/SemaObjC/property-10.m new file mode 100644 index 0000000..81b8ee1 --- /dev/null +++ b/test/SemaObjC/property-10.m @@ -0,0 +1,22 @@ +// RUN: clang-cc -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' 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(copy, retain) id p3_2; // expected-error {{property attributes 'copy' and 'retain' 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 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 diff --git a/test/SemaObjC/property-11.m b/test/SemaObjC/property-11.m new file mode 100644 index 0000000..e8e6091 --- /dev/null +++ b/test/SemaObjC/property-11.m @@ -0,0 +1,35 @@ +// RUN: clang-cc -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; +} + +@end + diff --git a/test/SemaObjC/property-12.m b/test/SemaObjC/property-12.m new file mode 100644 index 0000000..50fb63b --- /dev/null +++ b/test/SemaObjC/property-12.m @@ -0,0 +1,32 @@ +// RUN: clang-cc -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/test/SemaObjC/property-13.m b/test/SemaObjC/property-13.m new file mode 100644 index 0000000..d0e40dc --- /dev/null +++ b/test/SemaObjC/property-13.m @@ -0,0 +1,77 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@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 + +int main () +{ + Test *x = [[Test alloc] init]; + /* 1. Test of a requred 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/test/SemaObjC/property-2.m b/test/SemaObjC/property-2.m new file mode 100644 index 0000000..159e06b --- /dev/null +++ b/test/SemaObjC/property-2.m @@ -0,0 +1,63 @@ +// RUN: clang-cc -fsyntax-only -verify %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/test/SemaObjC/property-3.m b/test/SemaObjC/property-3.m new file mode 100644 index 0000000..a66b3d5 --- /dev/null +++ b/test/SemaObjC/property-3.m @@ -0,0 +1,14 @@ +// RUN: clang-cc -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/test/SemaObjC/property-4.m b/test/SemaObjC/property-4.m new file mode 100644 index 0000000..56db282 --- /dev/null +++ b/test/SemaObjC/property-4.m @@ -0,0 +1,29 @@ +// RUN: clang-cc -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/test/SemaObjC/property-5.m b/test/SemaObjC/property-5.m new file mode 100644 index 0000000..f463aae --- /dev/null +++ b/test/SemaObjC/property-5.m @@ -0,0 +1,34 @@ +// RUN: clang-cc -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/test/SemaObjC/property-6.m b/test/SemaObjC/property-6.m new file mode 100644 index 0000000..8f77cf1 --- /dev/null +++ b/test/SemaObjC/property-6.m @@ -0,0 +1,69 @@ +// RUN: clang-cc -fsyntax-only -verify %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/test/SemaObjC/property-7.m b/test/SemaObjC/property-7.m new file mode 100644 index 0000000..99c16ce --- /dev/null +++ b/test/SemaObjC/property-7.m @@ -0,0 +1,34 @@ +// RUN: clang-cc -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/test/SemaObjC/property-8.m b/test/SemaObjC/property-8.m new file mode 100644 index 0000000..49bd409 --- /dev/null +++ b/test/SemaObjC/property-8.m @@ -0,0 +1,74 @@ +// RUN: clang-cc -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/test/SemaObjC/property-9-impl-method.m b/test/SemaObjC/property-9-impl-method.m new file mode 100644 index 0000000..c97f388 --- /dev/null +++ b/test/SemaObjC/property-9-impl-method.m @@ -0,0 +1,94 @@ +// RUN: clang-cc %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 {} +-(NSRectEdge) rectEdgeForTabs { + NSRect dummy, result = {}; + NSDivideRect(self.bounds, &result, &dummy, self.tabAreaThickness, self.rectEdgeForTabs); +} +@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/test/SemaObjC/property-9.m b/test/SemaObjC/property-9.m new file mode 100644 index 0000000..752f9c0 --- /dev/null +++ b/test/SemaObjC/property-9.m @@ -0,0 +1,86 @@ +// RUN: clang-cc -fsyntax-only -verify %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-error {{declaration does not declare anything}} +@property (readonly) ; // expected-error {{type name requires a specifier or qualifier}} \ + expected-error {{declaration does not declare anything}} +@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 {{error: expected ')'}} + + int _awesome; +@property (readonlyx) // expected-error {{unknown property attribute 'readonlyx'}} + int _awesome2; + +@property ( // expected-note {{to match this '('}} + +) // expected-error {{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 diff --git a/test/SemaObjC/property-category-1.m b/test/SemaObjC/property-category-1.m new file mode 100644 index 0000000..6695239 --- /dev/null +++ b/test/SemaObjC/property-category-1.m @@ -0,0 +1,52 @@ +// RUN: clang-cc -fsyntax-only -verify %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; +} +@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-warning {{property 'p0' requires method 'p0' to be defined}} +@end + +@interface I0 (Cat0) +@end + +@interface I0 (Cat1) +@end + +@implementation I0 // expected-note {{implementation is here}} +- (void) foo { + self.p0 = 0; // expected-error {{assigning to property with 'readonly' attribute not allowed}} +} +@end diff --git a/test/SemaObjC/property-category-2.m b/test/SemaObjC/property-category-2.m new file mode 100644 index 0000000..c245e36 --- /dev/null +++ b/test/SemaObjC/property-category-2.m @@ -0,0 +1,19 @@ +// RUN: clang-cc -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; +@end + +@interface MyObject { float anotherFloat; } +@end + +@interface MyObject (CAT) <MyProtocol> +@end + +@implementation MyObject (CAT) +@dynamic myFloat; // OK +@synthesize anotherFloat; // expected-error {{@synthesize not allowed in a category's implementation}} +@end diff --git a/test/SemaObjC/property-category-3.m b/test/SemaObjC/property-category-3.m new file mode 100644 index 0000000..bf9e8cbd --- /dev/null +++ b/test/SemaObjC/property-category-3.m @@ -0,0 +1,31 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@protocol P + @property(readonly) int X; +@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/test/SemaObjC/property-error-readonly-assign.m b/test/SemaObjC/property-error-readonly-assign.m new file mode 100644 index 0000000..edeff09 --- /dev/null +++ b/test/SemaObjC/property-error-readonly-assign.m @@ -0,0 +1,21 @@ +// RUN: clang-cc -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 {{assigning to property with 'readonly' attribute not allowed}} + a.ok = 20; + b.x = 10; // expected-error {{setter method is needed to assign to object using property assignment syntax}} + b.ok = 20; +} + diff --git a/test/SemaObjC/property-impl-misuse.m b/test/SemaObjC/property-impl-misuse.m new file mode 100644 index 0000000..7b956b5 --- /dev/null +++ b/test/SemaObjC/property-impl-misuse.m @@ -0,0 +1,16 @@ +// RUN: clang-cc -fsyntax-only -verify %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 diff --git a/test/SemaObjC/property-inherited.m b/test/SemaObjC/property-inherited.m new file mode 100644 index 0000000..6c06b90 --- /dev/null +++ b/test/SemaObjC/property-inherited.m @@ -0,0 +1,44 @@ +// RUN: clang-cc %s -fsyntax-only -verify + +// <rdar://problem/6497242> Inherited overridden protocol declared objects don't work + +@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; +@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; +@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/test/SemaObjC/property-ivar-mismatch.m b/test/SemaObjC/property-ivar-mismatch.m new file mode 100644 index 0000000..75c1e97 --- /dev/null +++ b/test/SemaObjC/property-ivar-mismatch.m @@ -0,0 +1,14 @@ +// RUN: clang-cc -fsyntax-only -verify %s +// Test that arithmatic types on property and its ivar have exact match. + +@interface Test4 +{ + char ivar; +} +@property int prop; +@end + +@implementation Test4 +@synthesize prop = ivar; // expected-error {{type of property 'prop' does not match type of ivar 'ivar'}} +@end + diff --git a/test/SemaObjC/property-method-lookup-impl.m b/test/SemaObjC/property-method-lookup-impl.m new file mode 100644 index 0000000..ed7e9bc --- /dev/null +++ b/test/SemaObjC/property-method-lookup-impl.m @@ -0,0 +1,26 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface SSyncCEList +{ + id _list; +} +@end + +@implementation SSyncCEList + +- (id) list +{ +} +@end + +@interface SSyncConflictList : SSyncCEList +@end + +@implementation SSyncConflictList + +- (id)Meth : (SSyncConflictList*)other + { + return other.list; + } +@end + diff --git a/test/SemaObjC/property-missing.m b/test/SemaObjC/property-missing.m new file mode 100644 index 0000000..1aa94ce --- /dev/null +++ b/test/SemaObjC/property-missing.m @@ -0,0 +1,22 @@ +// RUN: clang-cc -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{{member reference base type 'id' is not a structure or union}} +} + diff --git a/test/SemaObjC/property-nonfragile-abi.m b/test/SemaObjC/property-nonfragile-abi.m new file mode 100644 index 0000000..e2de77d --- /dev/null +++ b/test/SemaObjC/property-nonfragile-abi.m @@ -0,0 +1,21 @@ +// RUN: clang-cc -fsyntax-only -triple x86_64-apple-darwin9 -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/test/SemaObjC/property-noprotocol-warning.m b/test/SemaObjC/property-noprotocol-warning.m new file mode 100644 index 0000000..95ec15a --- /dev/null +++ b/test/SemaObjC/property-noprotocol-warning.m @@ -0,0 +1,36 @@ +// RUN: clang-cc -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/test/SemaObjC/property-redundant-decl-accessor.m b/test/SemaObjC/property-redundant-decl-accessor.m new file mode 100644 index 0000000..ffd5129 --- /dev/null +++ b/test/SemaObjC/property-redundant-decl-accessor.m @@ -0,0 +1,18 @@ +// RUN: clang-cc -fsyntax-only -Werror -verify %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/test/SemaObjC/property-typecheck-1.m b/test/SemaObjC/property-typecheck-1.m new file mode 100644 index 0000000..ca8a139 --- /dev/null +++ b/test/SemaObjC/property-typecheck-1.m @@ -0,0 +1,101 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface A +-(float) x; // expected-note {{declared at}} +@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 at}} +@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 at}} // expected-note {{declared at}} +- (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/test/SemaObjC/property-user-setter.m b/test/SemaObjC/property-user-setter.m new file mode 100644 index 0000000..9b0380e --- /dev/null +++ b/test/SemaObjC/property-user-setter.m @@ -0,0 +1,90 @@ +// RUN: clang-cc -fsyntax-only -verify %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 {{assigning to property with 'readonly' attribute not allowed}} +} +@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 + +int main (void) { + Subclass *x = [[Subclass alloc] init]; + + x.setterOnly = 4; + if (g_val != 4) + abort (); + return 0; +} diff --git a/test/SemaObjC/property-weak.m b/test/SemaObjC/property-weak.m new file mode 100644 index 0000000..293432fc8 --- /dev/null +++ b/test/SemaObjC/property-weak.m @@ -0,0 +1,5 @@ +// RUN: clang-cc -triple i386-apple-darwin9 -fsyntax-only -verify %s + +@interface foo +@property(nonatomic) int foo __attribute__((weak_import)); +@end diff --git a/test/SemaObjC/property.m b/test/SemaObjC/property.m new file mode 100644 index 0000000..cf2624f --- /dev/null +++ b/test/SemaObjC/property.m @@ -0,0 +1,55 @@ +// RUN: clang-cc -triple i386-apple-darwin9 -fsyntax-only -verify %s + +@interface I +{ + int IVAR; + 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; +@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' does not match type of ivar 'IVAR'}} // 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) +@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 + diff --git a/test/SemaObjC/props-on-prots.m b/test/SemaObjC/props-on-prots.m new file mode 100644 index 0000000..7bee8a0 --- /dev/null +++ b/test/SemaObjC/props-on-prots.m @@ -0,0 +1,65 @@ +// RUN: clang-cc -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/test/SemaObjC/protocol-archane.m b/test/SemaObjC/protocol-archane.m new file mode 100644 index 0000000..3e70c05 --- /dev/null +++ b/test/SemaObjC/protocol-archane.m @@ -0,0 +1,35 @@ +// RUN: clang-cc -fsyntax-only -verify %s +// rdar://5986251 + +@protocol SomeProtocol +- (void) bar; +@end + +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}} + +// Decided not to support the following GCC extension. Found while researching rdar://6497631 +typedef struct objc_class *Class; + +Class <SomeProtocol> UnfortunateGCCExtension; // expected-error {{protocol qualified 'Class' is unsupported}} + diff --git a/test/SemaObjC/protocol-attribute.m b/test/SemaObjC/protocol-attribute.m new file mode 100644 index 0000000..ae84411 --- /dev/null +++ b/test/SemaObjC/protocol-attribute.m @@ -0,0 +1,49 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +__attribute ((unavailable)) +@protocol FwProto; // expected-note{{marked unavailable}} + +Class <FwProto> cFw = 0; // expected-warning {{'FwProto' is unavailable}} expected-error{{protocol qualified 'Class' is unsupported}} + + +__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}} expected-error{{protocol qualified 'Class' is unsupported}} + +@protocol FwProto @end // expected-note{{marked unavailable}} + +@interface MyClass2 <FwProto> // expected-warning {{'FwProto' is unavailable}} +@end + +__attribute ((unavailable)) __attribute ((deprecated)) @protocol XProto; // expected-note{{marked unavailable}} + +id <XProto> idX = 0; // expected-warning {{'XProto' is unavailable}} expected-warning {{'XProto' is deprecated}} + +int main () +{ + MyClass1 <MyProto1> *p1; // expected-warning {{'MyProto1' is deprecated}} +} + diff --git a/test/SemaObjC/protocol-expr-1.m b/test/SemaObjC/protocol-expr-1.m new file mode 100644 index 0000000..cc1c323 --- /dev/null +++ b/test/SemaObjC/protocol-expr-1.m @@ -0,0 +1,15 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@protocol fproto; + +@protocol p1 +@end + +@class cl; + +int main() +{ + Protocol *proto = @protocol(p1); + Protocol *fproto = @protocol(fproto); +} + diff --git a/test/SemaObjC/protocol-expr-neg-1.m b/test/SemaObjC/protocol-expr-neg-1.m new file mode 100644 index 0000000..9393fde --- /dev/null +++ b/test/SemaObjC/protocol-expr-neg-1.m @@ -0,0 +1,19 @@ +// RUN: clang-cc -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/test/SemaObjC/protocol-id-test-1.m b/test/SemaObjC/protocol-id-test-1.m new file mode 100644 index 0000000..5e737a8 --- /dev/null +++ b/test/SemaObjC/protocol-id-test-1.m @@ -0,0 +1,16 @@ +// RUN: clang-cc -verify %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/test/SemaObjC/protocol-id-test-2.m b/test/SemaObjC/protocol-id-test-2.m new file mode 100644 index 0000000..a55923c --- /dev/null +++ b/test/SemaObjC/protocol-id-test-2.m @@ -0,0 +1,12 @@ +// RUN: clang-cc -verify %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/test/SemaObjC/protocol-id-test-3.m b/test/SemaObjC/protocol-id-test-3.m new file mode 100644 index 0000000..3c7f84a --- /dev/null +++ b/test/SemaObjC/protocol-id-test-3.m @@ -0,0 +1,94 @@ +// RUN: clang-cc -pedantic -fsyntax-only -verify %s + +@protocol MyProto1 +@end + +@protocol MyProto2 +@end + +@interface INTF @end + +id<MyProto1> Func(INTF <MyProto1, MyProto2> *p2) +{ + 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 {{incompatible type passing 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}} + return p2; // expected-warning {{incompatible type returning 'id<MyProto1>', expected 'id<MyProto1,MyProto2>'}} +} + + + +id<MyProto1> Gunc3(id <MyProto2>p2) +{ + return p2; // expected-warning {{incompatible type returning 'id<MyProto2>', expected '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 {{incompatible type passing 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}} + return p2; // expected-warning {{incompatible type returning 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}} +} + +INTF<MyProto1> * Hunc3(id <MyProto2>p2) +{ + return p2; // expected-warning {{incompatible type returning 'id<MyProto2>', expected '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/test/SemaObjC/protocol-implementation-inherited.m b/test/SemaObjC/protocol-implementation-inherited.m new file mode 100644 index 0000000..1aace21 --- /dev/null +++ b/test/SemaObjC/protocol-implementation-inherited.m @@ -0,0 +1,56 @@ +// RUN: clang-cc -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 {}; +@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/test/SemaObjC/protocol-lookup-2.m b/test/SemaObjC/protocol-lookup-2.m new file mode 100644 index 0000000..64d0c3a --- /dev/null +++ b/test/SemaObjC/protocol-lookup-2.m @@ -0,0 +1,33 @@ +// RUN: clang-cc -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/test/SemaObjC/protocol-lookup.m b/test/SemaObjC/protocol-lookup.m new file mode 100644 index 0000000..0f1860d --- /dev/null +++ b/test/SemaObjC/protocol-lookup.m @@ -0,0 +1,50 @@ +// RUN: clang-cc -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]; +} + +@end + diff --git a/test/SemaObjC/protocol-qualified-class-unsupported.m b/test/SemaObjC/protocol-qualified-class-unsupported.m new file mode 100644 index 0000000..ad1ed5d --- /dev/null +++ b/test/SemaObjC/protocol-qualified-class-unsupported.m @@ -0,0 +1,40 @@ +// RUN: clang-cc -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) { // expected-error {{protocol qualified 'Class' is unsupported}} + [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/test/SemaObjC/protocol-typecheck.m b/test/SemaObjC/protocol-typecheck.m new file mode 100644 index 0000000..de66ded --- /dev/null +++ b/test/SemaObjC/protocol-typecheck.m @@ -0,0 +1,25 @@ +// RUN: clang-cc -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; + +@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> *', expected 'NSObject<PWhatever,XCElementSpacerP> *'}} +} + diff --git a/test/SemaObjC/protocols.m b/test/SemaObjC/protocols.m new file mode 100644 index 0000000..9fbdc16 --- /dev/null +++ b/test/SemaObjC/protocols.m @@ -0,0 +1,63 @@ +// RUN: clang-cc -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 + diff --git a/test/SemaObjC/rdr-6211479-array-property.m b/test/SemaObjC/rdr-6211479-array-property.m new file mode 100644 index 0000000..f8e4a07 --- /dev/null +++ b/test/SemaObjC/rdr-6211479-array-property.m @@ -0,0 +1,9 @@ +// RUN: clang-cc -fsyntax-only -verify %s +// XFAIL +// <rdar://problem/6211479> + +typedef int T[2]; + +@interface A +@property(assign) T p2; // expected-error {{FIXME: property has invalid type}} +@end diff --git a/test/SemaObjC/scope-check.m b/test/SemaObjC/scope-check.m new file mode 100644 index 0000000..0835373 --- /dev/null +++ b/test/SemaObjC/scope-check.m @@ -0,0 +1,103 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@class A, B, C; + +void test1() { + goto L; // expected-error{{illegal goto into protected scope}} + goto L2; // expected-error{{illegal goto into protected scope}} + goto L3; // expected-error{{illegal 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{{illegal goto into protected scope}} + goto L5; // expected-error{{illegal goto into protected scope}} + } @catch (C *c) { // expected-note {{jump bypasses initialization of @catch block}} + L5: ; + goto L6; // expected-error{{illegal 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{{illegal goto into protected scope}} + } @finally { + goto L7; // expected-error{{illegal goto into protected scope}} + } + + goto L8; // expected-error{{illegal 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{{illegal 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 {{illegal goto into protected scope}} + } @catch (...) { // expected-note {{jump bypasses initialization of @catch block}} + blargh: ; + } +} + ++ (void)meth2 { + int n; void *P; + goto L0; // expected-error {{illegal goto into protected scope}} + typedef int A[n]; // expected-note {{jump bypasses initialization of VLA typedef}} + L0: + + goto L1; // expected-error {{illegal goto into protected scope}} + A b, c[10]; // expected-note 2 {{jump bypasses initialization of variable length array}} + L1: + goto L2; // expected-error {{illegal goto into protected scope}} + A d[n]; // expected-note {{jump bypasses initialization of variable length array}} + L2: + return; +} + +@end diff --git a/test/SemaObjC/selector-1.m b/test/SemaObjC/selector-1.m new file mode 100644 index 0000000..ee77015 --- /dev/null +++ b/test/SemaObjC/selector-1.m @@ -0,0 +1,22 @@ +// RUN: clang-cc -verify %s + +@interface Lancelot @end +@implementation Lancelot + +- (void):(int)x {} +- (void)xx:(int)x :(int)y { } + +@end + +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/test/SemaObjC/selector-error.m b/test/SemaObjC/selector-error.m new file mode 100644 index 0000000..cc2a404 --- /dev/null +++ b/test/SemaObjC/selector-error.m @@ -0,0 +1,20 @@ +// RUN: clang-cc -fsyntax-only -verify %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/test/SemaObjC/selector-overload.m b/test/SemaObjC/selector-overload.m new file mode 100644 index 0000000..7c30f79 --- /dev/null +++ b/test/SemaObjC/selector-overload.m @@ -0,0 +1,47 @@ +// RUN: clang-cc %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/test/SemaObjC/sizeof-interface.m b/test/SemaObjC/sizeof-interface.m new file mode 100644 index 0000000..75d7daa --- /dev/null +++ b/test/SemaObjC/sizeof-interface.m @@ -0,0 +1,79 @@ +// RUN: clang-cc -triple x86_64-apple-darwin9 -verify -fsyntax-only %s + +@class I0; + +// 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 pointer to incomplete type 'I0 *'}} + + return &P[4]; // expected-error{{subscript of pointer to incomplete 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 {{subscript requires size of interface 'I0', which is not constant in non-fragile ABI}} +} + + +@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 + diff --git a/test/SemaObjC/static-ivar-ref-1.m b/test/SemaObjC/static-ivar-ref-1.m new file mode 100644 index 0000000..3c37e9e --- /dev/null +++ b/test/SemaObjC/static-ivar-ref-1.m @@ -0,0 +1,17 @@ +// RUN: clang-cc -ast-print %s + +@interface current +{ +@public + int ivar; + int ivar1; + int ivar2; +} +@end + +current *pc; + +int foo() +{ + return pc->ivar2 + (*pc).ivar + pc->ivar1; +} diff --git a/test/SemaObjC/stmts.m b/test/SemaObjC/stmts.m new file mode 100644 index 0000000..1d4ea0a --- /dev/null +++ b/test/SemaObjC/stmts.m @@ -0,0 +1,14 @@ +// RUN: clang-cc %s -verify -fsyntax-only + +struct some_struct; + +// 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 (...) { + } +} + diff --git a/test/SemaObjC/string.m b/test/SemaObjC/string.m new file mode 100644 index 0000000..3f078f6 --- /dev/null +++ b/test/SemaObjC/string.m @@ -0,0 +1,15 @@ +// RUN: clang-cc %s -verify -fsyntax-only && +// RUN: clang-cc %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/test/SemaObjC/super-cat-prot.m b/test/SemaObjC/super-cat-prot.m new file mode 100644 index 0000000..1ab0752 --- /dev/null +++ b/test/SemaObjC/super-cat-prot.m @@ -0,0 +1,48 @@ +// RUN: clang-cc -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 {} +-(IBInset)ibShadowInset { + if ([self boxType] == NSBoxSeparator) { + return [super ibShadowInset]; + } +} +-(NSSize)minimumFrameSizeFromKnobPosition:(IBKnobPosition)knobPosition { + if ([self boxType] != NSBoxSeparator) + return [super minimumFrameSizeFromKnobPosition:knobPosition]; +} +@end diff --git a/test/SemaObjC/super-property-message-expr.m b/test/SemaObjC/super-property-message-expr.m new file mode 100644 index 0000000..082d8bd --- /dev/null +++ b/test/SemaObjC/super-property-message-expr.m @@ -0,0 +1,21 @@ +// RUN: clang-cc -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/test/SemaObjC/super-property-notation.m b/test/SemaObjC/super-property-notation.m new file mode 100644 index 0000000..3b0887f --- /dev/null +++ b/test/SemaObjC/super-property-notation.m @@ -0,0 +1,30 @@ +// RUN: clang-cc -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/test/SemaObjC/super.m b/test/SemaObjC/super.m new file mode 100644 index 0000000..9afd4eb --- /dev/null +++ b/test/SemaObjC/super.m @@ -0,0 +1,40 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface Foo +- iMethod; ++ cMethod; +@end + +@interface A +@end + +@interface B : A +- (void)instanceMethod; ++ classMethod; +@end + +@implementation B + +- (void)instanceMethod { + [super iMethod]; // expected-warning{{method '-iMethod' not found (return type defaults to 'id')}} +} + ++ classMethod { + [super cMethod]; // expected-warning{{method '+cMethod' not found (return type defaults to 'id')}} +} +@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(int puper) { + [super m]; // expected-error{{use of undeclared identifier 'super'}} +} diff --git a/test/SemaObjC/synchronized.m b/test/SemaObjC/synchronized.m new file mode 100644 index 0000000..7131265 --- /dev/null +++ b/test/SemaObjC/synchronized.m @@ -0,0 +1,23 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface PBXTrackableTaskManager @end + +@implementation PBXTrackableTaskManager +- (id) init {} +- (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/test/SemaObjC/synthesize-setter-contclass.m b/test/SemaObjC/synthesize-setter-contclass.m new file mode 100644 index 0000000..78490c8 --- /dev/null +++ b/test/SemaObjC/synthesize-setter-contclass.m @@ -0,0 +1,24 @@ +// RUN: clang-cc -fsyntax-only -verify %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/test/SemaObjC/synthesized-ivar.m b/test/SemaObjC/synthesized-ivar.m new file mode 100644 index 0000000..de44857 --- /dev/null +++ b/test/SemaObjC/synthesized-ivar.m @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -triple x86_64-apple-darwin9 -verify %s +@interface I +{ +} +@property int IP; +@end + +@implementation I +@synthesize IP; +- (int) Meth { + return IP; +} +@end diff --git a/test/SemaObjC/try-catch.m b/test/SemaObjC/try-catch.m new file mode 100644 index 0000000..076eff5 --- /dev/null +++ b/test/SemaObjC/try-catch.m @@ -0,0 +1,47 @@ +// RUN: clang-cc -fsyntax-only -verify %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/test/SemaObjC/typedef-class.m b/test/SemaObjC/typedef-class.m new file mode 100644 index 0000000..1288156 --- /dev/null +++ b/test/SemaObjC/typedef-class.m @@ -0,0 +1,78 @@ +// RUN: clang-cc -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 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; + +@interface XCElementRootFace:NSObject {} @end + +@interface XCElementFace:XCElementRootFace {} @end + +@class XCElementToggler; + +@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/test/SemaObjC/ucn-objc-string.m b/test/SemaObjC/ucn-objc-string.m new file mode 100644 index 0000000..1d94ea2 --- /dev/null +++ b/test/SemaObjC/ucn-objc-string.m @@ -0,0 +1,13 @@ +// RUN: clang %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/test/SemaObjC/undef-class-messagin-error.m b/test/SemaObjC/undef-class-messagin-error.m new file mode 100644 index 0000000..114b6ca --- /dev/null +++ b/test/SemaObjC/undef-class-messagin-error.m @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface _Child ++ (int) flashCache; +@end + +@interface Child (Categ) // expected-error {{cannot find interface declaration for 'Child'}} ++ (int) flushCache2; +@end + +@implementation Child (Categ) // expected-error {{cannot find interface declaration for 'Child'}} ++ (int) flushCache2 { [super flashCache]; } // expected-error {{no @interface declaration found in class messaging of 'flushCache2'}} +@end diff --git a/test/SemaObjC/undef-protocol-methods-1.m b/test/SemaObjC/undef-protocol-methods-1.m new file mode 100644 index 0000000..0524552 --- /dev/null +++ b/test/SemaObjC/undef-protocol-methods-1.m @@ -0,0 +1,42 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@protocol P1 +- (void) P1proto; ++ (void) ClsP1Proto; +- (void) DefP1proto; +@end +@protocol P2 +- (void) P2proto; ++ (void) ClsP2Proto; +@end + +@protocol P3<P2> +- (void) P3proto; ++ (void) ClsP3Proto; ++ (void) DefClsP3Proto; +@end + +@protocol PROTO<P1, P3> +- (void) meth; +- (void) meth : (int) arg1; ++ (void) cls_meth : (int) arg1; +@end + +@interface INTF <PROTO> +@end + +@implementation INTF // expected-warning {{incomplete implementation}} \ + expected-warning {{method definition for 'meth' not found}} \ + expected-warning {{method definition for 'meth:' not found}} \ + expected-warning {{method definition for 'cls_meth:' not found}} \ + expected-warning {{method definition for 'P3proto' not found}} \ + expected-warning {{method definition for 'ClsP3Proto' not found}} \ + expected-warning {{method definition for 'P2proto' not found}} \ + expected-warning {{method definition for 'ClsP2Proto' not found}} \ + expected-warning {{method definition for 'ClsP1Proto' not found}} \ + expected-warning {{method definition for 'P1proto' not found}} +- (void) DefP1proto{} + ++ (void) DefClsP3Proto{} + +@end diff --git a/test/SemaObjC/undef-superclass-1.m b/test/SemaObjC/undef-superclass-1.m new file mode 100644 index 0000000..0d670f8 --- /dev/null +++ b/test/SemaObjC/undef-superclass-1.m @@ -0,0 +1,26 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@class SUPER, Y; + +@interface INTF :SUPER // expected-error {{cannot find interface declaration for 'SUPER', 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 {{cannot find interface declaration for 'Y', superclass of 'INTF3'}} +@end + +@interface INTF1 // expected-error {{duplicate interface definition for class 'INTF1'}} +@end + +@implementation SUPER +- (void)dealloc { + [super dealloc]; // expected-error {{no super class declared in @interface for 'SUPER'}} +} +@end diff --git a/test/SemaObjC/undefined-protocol-type-1.m b/test/SemaObjC/undefined-protocol-type-1.m new file mode 100644 index 0000000..572d55f --- /dev/null +++ b/test/SemaObjC/undefined-protocol-type-1.m @@ -0,0 +1,9 @@ +// RUN: clang-cc -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>*) meth; // expected-error {{cannot find protocol declaration for 'p3'}} +@end diff --git a/test/SemaObjC/unused.m b/test/SemaObjC/unused.m new file mode 100644 index 0000000..88c6f10 --- /dev/null +++ b/test/SemaObjC/unused.m @@ -0,0 +1,18 @@ +// RUN: clang-cc %s -verify -fsyntax-only +#include <stdio.h> + +@interface Greeter ++ (void) hello; +@end + +@implementation Greeter ++ (void) hello { + fprintf(stdout, "Hello, World!\n"); +} +@end + +int main (void) { + [Greeter hello]; + return 0; +} + diff --git a/test/SemaObjC/va-method-1.m b/test/SemaObjC/va-method-1.m new file mode 100644 index 0000000..3c8998f --- /dev/null +++ b/test/SemaObjC/va-method-1.m @@ -0,0 +1,17 @@ +// RUN: clang-cc -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/test/SemaObjC/warn-selector-selection.m b/test/SemaObjC/warn-selector-selection.m new file mode 100644 index 0000000..4ab89b7 --- /dev/null +++ b/test/SemaObjC/warn-selector-selection.m @@ -0,0 +1,14 @@ +// RUN: clang-cc -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/test/SemaObjC/warn-weak-field.m b/test/SemaObjC/warn-weak-field.m new file mode 100644 index 0000000..3850f21 --- /dev/null +++ b/test/SemaObjC/warn-weak-field.m @@ -0,0 +1,24 @@ +// RUN: clang-cc -triple i386-apple-darwin9 -fsyntax-only -fobjc-gc -verify %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/test/SemaObjC/weak-attr-ivar.m b/test/SemaObjC/weak-attr-ivar.m new file mode 100644 index 0000000..9e0e8cb --- /dev/null +++ b/test/SemaObjC/weak-attr-ivar.m @@ -0,0 +1,73 @@ +// RUN: clang-cc -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) { +} +@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; + } + } + } +} +- (FooHUHCode) HUH { + if (_HUH == Foo_HUH_NONE) { + if (_mostInterestingChild) + return [_mostInterestingChild HUH]; + } +} +@end + diff --git a/test/SemaObjC/writable-property-in-superclass.m b/test/SemaObjC/writable-property-in-superclass.m new file mode 100644 index 0000000..182b1c4 --- /dev/null +++ b/test/SemaObjC/writable-property-in-superclass.m @@ -0,0 +1,17 @@ +// RUN: clang-cc -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 + |