diff options
Diffstat (limited to 'gcc/testsuite/objc.dg')
37 files changed, 1050 insertions, 31 deletions
diff --git a/gcc/testsuite/objc.dg/bitfield-5.m b/gcc/testsuite/objc.dg/bitfield-5.m new file mode 100644 index 00000000000..ddd3b03a309 --- /dev/null +++ b/gcc/testsuite/objc.dg/bitfield-5.m @@ -0,0 +1,113 @@ +/* Check ObjC class layout follows the ABI (informally) + set in the past. ObjC structs must be laid out as if + all ivars, including those inherited from superclasses, + were defined at once (i.e., any padding introduced for + superclasses should be removed). */ +/* Contributed by Ziemowit Laski <zlaski@apple.com>. */ +/* { dg-options "-Wpadded" } */ +/* { dg-do run } */ + +#include <objc/objc.h> +#include <objc/Object.h> +#include <stdlib.h> + +#define CHECK_IF(expr) if(!(expr)) abort() + +enum Enum { zero, one, two, three, four }; + +@interface Base: Object { +@public + unsigned a: 2; + int b: 3; + enum Enum c: 4; + unsigned d: 5; +} /* { dg-warning "padding struct size to alignment boundary" } */ +@end + +struct Base_0 { + Class isa; + unsigned a: 2; + int b: 3; + enum Enum c: 4; + unsigned d: 5; +}; /* { dg-warning "padding struct size to alignment boundary" } */ + +@interface Derived: Base { +@public + signed e: 5; + unsigned f: 4; + enum Enum g: 3; +} /* { dg-warning "padding struct size to alignment boundary" } */ +@end + +struct Derived_0 { + Class isa; + unsigned a: 2; + int b: 3; + enum Enum c: 4; + unsigned d: 5; + signed e: 5; + int f: 4; + enum Enum g: 3; +}; /* { dg-warning "padding struct size to alignment boundary" } */ + +@interface Leaf: Derived { +@public + signed h: 2; +} /* { dg-warning "padding struct size to alignment boundary" } */ +@end + +struct Leaf_0 { + Class isa; + unsigned a: 2; + int b: 3; + enum Enum c: 4; + unsigned d: 5; + signed e: 5; + unsigned f: 4; + enum Enum g: 3; + signed h: 2; +}; /* { dg-warning "padding struct size to alignment boundary" } */ + +/* Note that the semicolon after @defs(...) is optional. */ + +typedef struct { @defs(Base) } Base_t; /* { dg-warning "padding struct size to alignment boundary" } */ +typedef struct { @defs(Derived); } Derived_t; /* { dg-warning "padding struct size to alignment boundary" } */ +typedef struct { @defs(Leaf); } Leaf_t; /* { dg-warning "padding struct size to alignment boundary" } */ + +int main(void) +{ + struct Leaf_0 l_0; + Leaf *l = (Leaf *)&l_0; + Leaf_t *l_t = (Leaf_t *)&l_0; + + CHECK_IF(sizeof(Base_t) == sizeof(Base)); + CHECK_IF(sizeof(Derived_t) == sizeof(Derived)); + CHECK_IF(sizeof(Leaf_t) == sizeof(Leaf)); + + CHECK_IF(sizeof(struct Base_0) == sizeof(Base)); + CHECK_IF(sizeof(struct Derived_0) == sizeof(Derived)); + CHECK_IF(sizeof(struct Leaf_0) == sizeof(Leaf)); + + l_0.isa = (Class)0; + l_0.a = 3; + l_0.b = 0; + l_0.c = three; + l_0.d = 31; + l_0.e = 0; + l_0.f = 15; + l_0.g = zero; + l_0.h = -2; + + CHECK_IF(!l_t->isa); + CHECK_IF(l->a == 3 && l_t->a == 3); + CHECK_IF(!l->b && !l_t->b); + CHECK_IF(l->c == three && l_t->c == three); + CHECK_IF(l->d == 31 && l_t->d == 31); + CHECK_IF(!l->e && !l_t->e); + CHECK_IF(l->f == 15 && l_t->f == 15); + CHECK_IF(l->g == zero && l_t->g == zero); + CHECK_IF(l->h == -2 && l_t->h == -2); + + return 0; +} diff --git a/gcc/testsuite/objc.dg/class-protocol-1.m b/gcc/testsuite/objc.dg/class-protocol-1.m index ffa2435f5c0..f97f2317962 100644 --- a/gcc/testsuite/objc.dg/class-protocol-1.m +++ b/gcc/testsuite/objc.dg/class-protocol-1.m @@ -313,9 +313,9 @@ testComptypes(void) { /* id <protocol>, SomeClass * */ mc1 == objP1; objP1 == mc1; - - mc1 == objP2; /* { dg-warning "does not implement" } */ - objP2 == mc1; /* { dg-warning "does not implement" } */ + + mc1 == objP2; /* { dg-warning "lacks a cast" } */ + objP2 == mc1; /* { dg-warning "lacks a cast" } */ } { /* id <protocol>, id */ obj == objP1; @@ -371,10 +371,10 @@ testComptypes(void) objP5 = objP1; /* { dg-warning "does not conform" } */ } { /* id <protocol>, SomeClass * */ - mc1 = objP1; /* { dg-warning "incompatible" } */ /* FIXME: should be "" */ + mc1 = objP1; objP1 = mc1; - - mc1 = objP2; /* { dg-warning "incompatible" } */ /* FIXME: should be "does not implement" */ + + mc1 = objP2; /* { dg-warning "does not conform" } */ objP2 = mc1; /* { dg-warning "does not implement" } */ } { /* id <protocol>, id */ @@ -382,8 +382,8 @@ testComptypes(void) objP1 = obj; } { /* id <protocol>, Class */ - cls = objP1; /* { dg-warning "incompatible" } */ - objP1 = cls; /* { dg-warning "incompatible" } */ + cls = objP1; /* { dg-warning "distinct Objective\\-C type" } */ + objP1 = cls; /* { dg-warning "distinct Objective\\-C type" } */ } { /* id <protocol>, non-ObjC */ num = objP1; /* { dg-warning "makes integer" } */ @@ -401,11 +401,11 @@ testComptypes(void) } { /* Class <protocol>, SomeClass * */ /* These combinations should always elicit a warning. */ - mc1 = clsP1; /* { dg-warning "incompatible" } */ - clsP1 = mc1; /* { dg-warning "incompatible" } */ + mc1 = clsP1; /* { dg-warning "distinct Objective\\-C type" } */ + clsP1 = mc1; /* { dg-warning "distinct Objective\\-C type" } */ - mc1 = clsP2; /* { dg-warning "incompatible" } */ - clsP2 = mc1; /* { dg-warning "incompatible" } */ + mc1 = clsP2; /* { dg-warning "distinct Objective\\-C type" } */ + clsP2 = mc1; /* { dg-warning "distinct Objective\\-C type" } */ } { /* Class <protocol>, id */ obj = clsP1; @@ -423,8 +423,8 @@ testComptypes(void) clsP1 = ptr; } { /* Class <protocol>, id <protocol> */ - clsP1 = objP1; /* { dg-warning "incompatible" } */ - objP1 = clsP1; /* { dg-warning "incompatible" } */ + clsP1 = objP1; /* { dg-warning "distinct Objective\\-C type" } */ + objP1 = clsP1; /* { dg-warning "distinct Objective\\-C type" } */ } } diff --git a/gcc/testsuite/objc.dg/comp-types-1.m b/gcc/testsuite/objc.dg/comp-types-1.m index 310b22634c0..5bf59a73cba 100644 --- a/gcc/testsuite/objc.dg/comp-types-1.m +++ b/gcc/testsuite/objc.dg/comp-types-1.m @@ -32,9 +32,9 @@ int main() /* Assigning to a 'MyClass *' variable should always generate a warning, unless done from an 'id'. */ obj_c = obj; /* Ok */ - obj_c = obj_p; /* { dg-warning "incompatible pointer type" } */ - obj_c = obj_cp; /* { dg-warning "incompatible pointer type" } */ - obj_c = obj_C; /* { dg-warning "incompatible pointer type" } */ + obj_c = obj_p; /* { dg-warning "distinct Objective\\-C type" } */ + obj_c = obj_cp; /* { dg-warning "distinct Objective\\-C type" } */ + obj_c = obj_C; /* { dg-warning "distinct Objective\\-C type" } */ /* Assigning to an 'id<MyProtocol>' variable should generate a warning if done from a 'MyClass *' (which doesn't implement @@ -43,14 +43,15 @@ int main() obj_p = obj; /* Ok */ obj_p = obj_c; /* { dg-warning "does not implement" } */ obj_p = obj_cp; /* Ok */ - obj_p = obj_C; /* { dg-warning "incompatible pointer type" } */ + obj_p = obj_C; /* { dg-warning "distinct Objective\\-C type" } */ /* Assigning to a 'MyOtherClass *' variable should always generate - a warning, unless done from an 'id' */ + a warning, unless done from an 'id' or an 'id<MyProtocol>' (since + MyOtherClass implements MyProtocol). */ obj_cp = obj; /* Ok */ - obj_cp = obj_c; /* { dg-warning "incompatible pointer type" } */ - obj_cp = obj_p; /* { dg-warning "incompatible pointer type" } */ - obj_cp = obj_C; /* { dg-warning "incompatible pointer type" } */ + obj_cp = obj_c; /* { dg-warning "distinct Objective\\-C type" } */ + obj_cp = obj_p; /* Ok */ + obj_cp = obj_C; /* { dg-warning "distinct Objective\\-C type" } */ /* Any comparison involving an 'id' must be without warnings. */ if (obj == obj_p) ; /* Ok */ /*Bogus warning here in 2.95.4*/ @@ -64,8 +65,8 @@ int main() /* Any comparison between 'MyClass *' and anything which is not an 'id' must generate a warning. */ - if (obj_c == obj_p) ; /* { dg-warning "does not implement" } */ - if (obj_p == obj_c) ; /* { dg-warning "does not implement" } */ + if (obj_c == obj_p) ; /* { dg-warning "lacks a cast" } */ + if (obj_p == obj_c) ; /* { dg-warning "lacks a cast" } */ if (obj_c == obj_cp) ; /* { dg-warning "lacks a cast" } */ if (obj_cp == obj_c) ; /* { dg-warning "lacks a cast" } */ if (obj_c == obj_C) ; /* { dg-warning "lacks a cast" } */ diff --git a/gcc/testsuite/objc.dg/comp-types-10.m b/gcc/testsuite/objc.dg/comp-types-10.m new file mode 100644 index 00000000000..8cd53404f52 --- /dev/null +++ b/gcc/testsuite/objc.dg/comp-types-10.m @@ -0,0 +1,28 @@ +/* { dg-do compile } */ + +#include <objc/Object.h> + +@protocol Foo +- (id)meth1; +- (id)meth2:(int)arg; +@end + +@interface Derived1: Object +@end + +@interface Derived2: Object ++ (Derived1 *)new; +@end + +id<Foo> func(void) { + Object *o = [Object new]; + return o; /* { dg-warning "class .Object. does not implement the .Foo. protocol" } */ +} + +@implementation Derived2 ++ (Derived1 *)new { + Derived2 *o = [super new]; + return o; /* { dg-warning "distinct Objective\\-C type in return" } */ +} +@end + diff --git a/gcc/testsuite/objc.dg/comp-types-11.m b/gcc/testsuite/objc.dg/comp-types-11.m new file mode 100644 index 00000000000..b041759ca65 --- /dev/null +++ b/gcc/testsuite/objc.dg/comp-types-11.m @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +#include <objc/Object.h> + +@interface Derived: Object +@end + +extern Object* foo(void); +static Derived *test(void) +{ + Derived *m = foo(); /* { dg-warning "initialization from distinct Objective\\-C type" } */ + + return m; +} + diff --git a/gcc/testsuite/objc.dg/comp-types-5.m b/gcc/testsuite/objc.dg/comp-types-5.m index f4d3dfc94e9..c112ecbe54d 100644 --- a/gcc/testsuite/objc.dg/comp-types-5.m +++ b/gcc/testsuite/objc.dg/comp-types-5.m @@ -19,8 +19,8 @@ int main() obj_cp = obj; /* Ok */ obj = obj_cp; /* Ok */ - obj_cp = obj_p; /* { dg-warning "incompatible pointer type" } */ - obj_p = obj_cp; /* Ok */ /* Spurious 2.95.4 warning here. */ + obj_cp = obj_p; /* Ok */ + obj_p = obj_cp; /* Ok */ if (obj_cp == obj) ; /* Ok */ if (obj == obj_cp) ; /* Ok */ diff --git a/gcc/testsuite/objc.dg/comp-types-6.m b/gcc/testsuite/objc.dg/comp-types-6.m index 9403b532fd3..e23558114bc 100644 --- a/gcc/testsuite/objc.dg/comp-types-6.m +++ b/gcc/testsuite/objc.dg/comp-types-6.m @@ -1,6 +1,7 @@ /* Test assignments and comparisons involving category protocols. */ /* Author: Nicola Pero <nicola@brainstorm.co.uk>. */ /* { dg-do compile } */ + #include <objc/objc.h> @protocol MyProtocol @@ -23,8 +24,8 @@ int main() MyClass *obj_cp = nil; MyOtherClass *obj_cp2 = nil; - obj_cp = obj_p; /* { dg-warning "incompatible pointer type" } */ - obj_cp2 = obj_p; /* { dg-warning "incompatible pointer type" } */ + obj_cp = obj_p; /* { dg-warning "distinct Objective\\-C type" } */ + obj_cp2 = obj_p; /* { dg-warning "distinct Objective\\-C type" } */ obj_p = obj_cp; /* Ok */ obj_p = obj_cp2; /* Ok */ diff --git a/gcc/testsuite/objc.dg/comp-types-8.m b/gcc/testsuite/objc.dg/comp-types-8.m new file mode 100644 index 00000000000..7f9c64a6f2e --- /dev/null +++ b/gcc/testsuite/objc.dg/comp-types-8.m @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* Another gimplifier ICE... */ + +#include <objc/Object.h> + +@interface MyView: Object { + int _frame; +} +- (void)_finalize; +@end + +@interface MyViewTemplate: MyView { + void *_className; +} +- (id)createRealObject; +@end + +@implementation MyViewTemplate +- (id)createRealObject { + id realObj; + *(MyView *)realObj = *(MyView *)self; + return realObj; +} +@end diff --git a/gcc/testsuite/objc.dg/comp-types-9.m b/gcc/testsuite/objc.dg/comp-types-9.m new file mode 100644 index 00000000000..3abcde5bec6 --- /dev/null +++ b/gcc/testsuite/objc.dg/comp-types-9.m @@ -0,0 +1,19 @@ +/* Yet another mysterious gimplifier crasher. */ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +@class NSString; +@protocol NSObject +@end +@interface NSObject <NSObject> { +} +@end +void __setRetained(id *ivar, id value) { + *ivar = value; +} +static NSString *_logProcessPrefix = 0; +@implementation NSObject (ScopeAdditions) ++ (void)setObjectLogProcessPrefix:(NSString *)processPrefix { + __setRetained(&_logProcessPrefix, processPrefix); +} +@end diff --git a/gcc/testsuite/objc.dg/encode-6.m b/gcc/testsuite/objc.dg/encode-6.m new file mode 100644 index 00000000000..263b02ad0f3 --- /dev/null +++ b/gcc/testsuite/objc.dg/encode-6.m @@ -0,0 +1,22 @@ +/* Test for graceful encoding of const-qualified fields and parameters. */ +/* Author: Ziemowit Laski <zlaski@apple.com> */ +/* { dg-do compile } */ + +struct Cxx { + const struct Cxx *next; +}; + +@interface ObjC { + const struct Cxx *obj; +} +- (ObjC *)initWithCxx: (struct Cxx *const)c and: (const struct Cxx *)d; +@end + +@implementation ObjC +- (ObjC *)initWithCxx: (struct Cxx *const)c and: (const struct Cxx *)d { + obj = d; + return self; +} +@end + +/* { dg-final { scan-assembler "@\[0-9\]+@0:\[0-9\]+r\\^{Cxx=\\^r{Cxx}}\[0-9\]+\\^r{Cxx}" } } */ diff --git a/gcc/testsuite/objc.dg/extra-semi.m b/gcc/testsuite/objc.dg/extra-semi.m new file mode 100644 index 00000000000..ad555962dbb --- /dev/null +++ b/gcc/testsuite/objc.dg/extra-semi.m @@ -0,0 +1,10 @@ +/* Allow extra semicolons in between method declarations, + for old times' sake. */ + +/* { dg-do compile } */ + +@interface Foo + -(Foo *) expiration; + -(void) setExpiration:(Foo *) date;; + -(int) getVersion; +@end diff --git a/gcc/testsuite/objc.dg/fix-and-continue-2.m b/gcc/testsuite/objc.dg/fix-and-continue-2.m new file mode 100644 index 00000000000..33cb8467dcd --- /dev/null +++ b/gcc/testsuite/objc.dg/fix-and-continue-2.m @@ -0,0 +1,24 @@ +/* Static variables, even if local, require indirect access through a stub + if -mfix-and-continue is enabled. */ + +/* Author: Ziemowit Laski <zlaski@apple.com> */ + +/* { dg-do assemble { target *-*-darwin* } } */ +/* { dg-options "-mfix-and-continue" } */ + +#include <objc/Object.h> + +@interface Foo: Object ++ (Object *)indexableFileTypes; +@end + +@implementation Foo ++ (Object *)indexableFileTypes +{ + static Object *fileTypes = 0; + if(!fileTypes) { + fileTypes = [Object new]; + } + return fileTypes; +} +@end diff --git a/gcc/testsuite/objc.dg/isa-field-1.m b/gcc/testsuite/objc.dg/isa-field-1.m new file mode 100644 index 00000000000..6398b608d82 --- /dev/null +++ b/gcc/testsuite/objc.dg/isa-field-1.m @@ -0,0 +1,43 @@ +/* Ensure there are no bizarre difficulties with accessing the 'isa' field of objects. */ +/* { dg-do compile { target *-*-darwin* } } */ + +#include <objc/Object.h> + +@interface Object (Test) +- (Class) test1: (id)object; +@end + +@interface Derived: Object +- (Class) test2: (id)object; +@end + +@implementation Object (Test) + +Class test1(id object) { + Class cls = object->isa; + return cls; +} +- (Class) test1: (id)object { + Class cls = object->isa; + return cls; +} + +@end + +@implementation Derived + +Class test2(id object) { + Class cls = object->isa; + return cls; +} +- (Class) test2: (id)object { + Class cls = object->isa; + return cls; +} + +@end + +Class test3(id object) { + Class cls = object->isa; + return cls; +} diff --git a/gcc/testsuite/objc.dg/layout-1.m b/gcc/testsuite/objc.dg/layout-1.m new file mode 100644 index 00000000000..6fb114217ab --- /dev/null +++ b/gcc/testsuite/objc.dg/layout-1.m @@ -0,0 +1,15 @@ +/* Ensure that we do not get bizarre warnings referring to + __attribute__((packed)) or some such. */ +/* { dg-do compile } */ +/* { dg-options "-Wpadded -Wpacked" } */ + +#include <objc/Object.h> + +@interface Derived1: Object +{ } +@end + +@interface Derived2: Object +- (id) foo; +@end + diff --git a/gcc/testsuite/objc.dg/lookup-1.m b/gcc/testsuite/objc.dg/lookup-1.m new file mode 100644 index 00000000000..71fc61ea04e --- /dev/null +++ b/gcc/testsuite/objc.dg/lookup-1.m @@ -0,0 +1,54 @@ +/* { dg-do run { target *-*-darwin* } } */ + +#include <objc/Object.h> +#include <stdlib.h> + +typedef struct MyWidget { + int a; +} MyWidget; + +MyWidget gWidget = { 17 }; + +@protocol MyProto +- (MyWidget *)widget; +@end + +@interface Foo: Object +@end + +@interface Bar: Foo <MyProto> +@end + +@interface Container: Object ++ (MyWidget *)elementForView:(Foo *)view; +@end + +@implementation Foo +@end + +@implementation Bar +- (MyWidget *)widget { + return &gWidget; +} +@end + +@implementation Container ++ (MyWidget *)elementForView:(Foo *)view +{ + MyWidget *widget = nil; + if ([view conformsTo:@protocol(MyProto)]) { + widget = [(Foo <MyProto> *)view widget]; + } + return widget; +} +@end + +int main(void) { + id view = [Bar new]; + MyWidget *w = [Container elementForView: view]; + + if (!w || w->a != 17) + abort (); + + return 0; +} diff --git a/gcc/testsuite/objc.dg/method-15.m b/gcc/testsuite/objc.dg/method-15.m new file mode 100644 index 00000000000..0ba3625a817 --- /dev/null +++ b/gcc/testsuite/objc.dg/method-15.m @@ -0,0 +1,56 @@ +/* Test if prior method lookup at method @implementation time is not + overly aggressive, leading to methods being found in other classes. */ +/* Author: Ziemowit Laski <zlaski@apple.com>. */ + +/* { dg-do compile } */ + +#include <objc/Object.h> + +@class NSString; + +@protocol NSMenuItem ++ (void)setUsesUserKeyEquivalents:(BOOL)flag; ++ (BOOL)usesUserKeyEquivalents; +@end + +@interface NSMenuItem : Object <NSMenuItem> { + @private + id _menu; +} +@end + +@interface NSResponder : Object <NSMenuItem> +{ + id _nextResponder; +} +@end + +@interface Object(NSMenuValidation) +- (BOOL)validateMenuItem:(id <NSMenuItem>)menuItem; +@end + +@interface NSResponder (NSStandardKeyBindingMethods) +- (void)insertText:(id)insertString; +- (void)doCommandBySelector:(SEL)aSelector; +@end + +@interface NSView : NSResponder +{ + id _superview; + id _subviews; +} +@end + +@interface SKTGraphicView : NSView { + @private + float _gridSpacing; +} +@end + +@implementation SKTGraphicView +- (BOOL)validateMenuItem:(NSMenuItem *)item { + return (BOOL)1; +} +- (void)insertText:(NSString *)str { +} +@end diff --git a/gcc/testsuite/objc.dg/method-16.m b/gcc/testsuite/objc.dg/method-16.m new file mode 100644 index 00000000000..c8394ffbb88 --- /dev/null +++ b/gcc/testsuite/objc.dg/method-16.m @@ -0,0 +1,24 @@ +/* Do not warn about "slightly" mismatched method signatures if + -Wstrict-selector-match is off. */ + +/* { dg-do compile } */ +/* { dg-options "-Wno-strict-selector-match" } */ + +#include <objc/objc.h> + +@interface Base +- (id) meth1: (Base *)arg1; +- (id) window; +@end + +@interface Derived: Base +- (id) meth1: (Derived *)arg1; +- (Base *)window; +@end + +void foo(void) { + id r; + + [r meth1:r]; + [r window]; +} diff --git a/gcc/testsuite/objc.dg/method-17.m b/gcc/testsuite/objc.dg/method-17.m new file mode 100644 index 00000000000..5e28ddc1bb7 --- /dev/null +++ b/gcc/testsuite/objc.dg/method-17.m @@ -0,0 +1,26 @@ +/* Test for spurious "may or may not return a value" warnings. */ + +/* { dg-do compile } */ +/* { dg-options "-Wextra" } */ + +#include <objc/Object.h> + +@interface Foo: Object +- (id) meth1; +- (void) meth2; +@end + +extern int bar; + +@implementation Foo +- (id) meth1 { + if (bar) + return [Object new]; + return; +} /* { dg-warning "this function may return with or without a value" } */ +- (void) meth2 { + if (!bar) + return; + bar = 0; +} /* { dg-bogus "this function may return with or without a value" } */ +@end diff --git a/gcc/testsuite/objc.dg/method-18.m b/gcc/testsuite/objc.dg/method-18.m new file mode 100644 index 00000000000..77fd3ef1b7f --- /dev/null +++ b/gcc/testsuite/objc.dg/method-18.m @@ -0,0 +1,29 @@ +/* Do not warn about "slightly" mismatched method signatures if + -Wstrict-selector-match is off. */ +/* { dg-do compile } */ +/* { dg-options "-Wno-strict-selector-match" } */ + +#include <objc/objc.h> + +typedef enum { en1_1, en1_2 } En1; +typedef enum { en2_1, en2_2 } En2; +typedef struct { int a, b; } St1; +typedef struct { unsigned a, b; } St2; + +@interface Base +- (id) meth1: (En1)arg1; +- (St1) window; +@end + +@interface Derived: Base +- (id) meth1: (En2)arg1; +- (St2)window; +@end + +void foo(void) { + id r; + En1 en; + + [r meth1:en]; + [r window]; +} diff --git a/gcc/testsuite/objc.dg/method-19.m b/gcc/testsuite/objc.dg/method-19.m new file mode 100644 index 00000000000..47163711b3d --- /dev/null +++ b/gcc/testsuite/objc.dg/method-19.m @@ -0,0 +1,17 @@ +/* The following should NOT generate "may not respond to" warnings, since a forward-declared + @class (instance) should be treated like a 'Class') ('id'). */ + +/* { dg-do compile } */ + +#include <objc/Object.h> + +@class NotKnown; + +void foo(NotKnown *n) { + [NotKnown new]; + [n nonexistent_method]; /* { dg-warning "no .\\-nonexistent_method. method found" } */ +} + +/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */ +/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */ +/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/objc.dg/method-9.m b/gcc/testsuite/objc.dg/method-9.m index 28f6a1be621..ade5d64e71a 100644 --- a/gcc/testsuite/objc.dg/method-9.m +++ b/gcc/testsuite/objc.dg/method-9.m @@ -39,7 +39,7 @@ /* { dg-warning "also found .\\-\\(id\\)initWithData:\\(int\\)data." "" { target *-*-* } 15 } */ /* The following warning is a consequence of picking the "wrong" method signature. */ - /* { dg-warning "passing argument 1 of .initWithData:. from incompatible pointer type" "" { target *-*-* } 35 } */ + /* { dg-warning "passing argument 1 of .initWithData:. from distinct Objective\\-C type" "" { target *-*-* } 35 } */ return result; } @end diff --git a/gcc/testsuite/objc.dg/next-runtime-1.m b/gcc/testsuite/objc.dg/next-runtime-1.m new file mode 100644 index 00000000000..db14897fe8d --- /dev/null +++ b/gcc/testsuite/objc.dg/next-runtime-1.m @@ -0,0 +1,18 @@ +/* Test that the correct version number (6) is set in the module descriptor + when compiling for the NeXT runtime. */ +/* Author: Ziemowit Laski <zlaski@apple.com> */ + +/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-options "-fnext-runtime" } */ + +#include <objc/Object.h> + +@interface FooBar: Object +- (void)boo; +@end + +@implementation FooBar +- (void)boo { } +@end + +/* { dg-final { scan-assembler "L_OBJC_MODULES:\n\[ \t\]*\.long\t6\n" } } */ diff --git a/gcc/testsuite/objc.dg/no-extra-load.m b/gcc/testsuite/objc.dg/no-extra-load.m new file mode 100644 index 00000000000..9b50e8358ba --- /dev/null +++ b/gcc/testsuite/objc.dg/no-extra-load.m @@ -0,0 +1,6 @@ +/* { dg-do compile { target *-*-darwin* } } */ + +#import <Foundation/Foundation.h> +main() { [NSObject new]; } + +/* { dg-final { scan-assembler-not "L_objc_msgSend\\\$non_lazy_ptr" } } */ diff --git a/gcc/testsuite/objc.dg/objc-gc-4.m b/gcc/testsuite/objc.dg/objc-gc-4.m new file mode 100644 index 00000000000..df0a44cd8dd --- /dev/null +++ b/gcc/testsuite/objc.dg/objc-gc-4.m @@ -0,0 +1,63 @@ +/* Test looking up fields in superclasses in the context of write-barriers + (where component references get rewritten). */ +/* Contributed by Ziemowit Laski <zlaski@apple.com> */ + +/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-options "-fobjc-gc" } */ + +#include <objc/Object.h> + +@class MyWindow; + +@interface MyDocument : Object { + MyWindow *_window; +} +@end + +@interface MyFileDocument : MyDocument { + struct { + unsigned int autoClose:1; + unsigned int openForUI:1; + unsigned int isClosing:1; + unsigned int needsDiskCheck:1; + unsigned int isWritable:1; + unsigned int representsFileOnDisk:1; + unsigned int RESERVED:26; + } _fdFlags; +} +@end + +@interface MyTextFileDocument : MyFileDocument { + Object *_textStorage; + struct __tfdFlags { + unsigned int immutable:1; + unsigned int lineEnding:2; + unsigned int isClosing:1; + unsigned int settingsAreSet:1; + unsigned int usesTabs:1; + unsigned int isUTF8WithBOM:1; + unsigned int wrapsLines:1; + unsigned int usingDefaultLanguage:1; + unsigned int RESERVED:23; + } _tfdFlags; + int _tabWidth; + int _indentWidth; +} +@end + +@interface MyRTFFileDocument : MyTextFileDocument +- (BOOL)readFromFile:(const char *)fileName ofType:(const char *)type; +@end + +@implementation MyRTFFileDocument +- (BOOL)readFromFile:(const char *)fileName ofType:(const char *)type { + if (_textStorage && fileName) { + [_textStorage free]; + return YES; + } else if (type) { + _textStorage = [MyRTFFileDocument new]; + return NO; + } + return (fileName && type); +} +@end diff --git a/gcc/testsuite/objc.dg/pragma-1.m b/gcc/testsuite/objc.dg/pragma-1.m new file mode 100644 index 00000000000..14c4d7928a2 --- /dev/null +++ b/gcc/testsuite/objc.dg/pragma-1.m @@ -0,0 +1,23 @@ +/* It is OK to use #pragma inside @implementation body. This test checks that. */ +/* Ziemowit Laski <zlaski@apple.com>. */ + +@interface A +{ + int p; +} ++(int) foo; +-(int) bar; +@end + +@implementation A +#pragma mark - +#pragma mark init / dealloc ++ (int)foo { + return 1; +} +#pragma mark - +#pragma mark Private Functions +- (int)bar { + return 2; +} +@end diff --git a/gcc/testsuite/objc.dg/selector-2.m b/gcc/testsuite/objc.dg/selector-2.m index 5584f1511b6..09fbc252836 100644 --- a/gcc/testsuite/objc.dg/selector-2.m +++ b/gcc/testsuite/objc.dg/selector-2.m @@ -1,5 +1,5 @@ /* Test that we don't ICE when issuing a -Wselector warning. */ -/* { dg-options "-Wselector -fgnu-runtime" } */ +/* { dg-options "-Wselector" } */ /* { dg-do compile } */ #include <objc/Object.h> @@ -12,5 +12,6 @@ SEL a; a = @selector(b1ar); } -@end /* { dg-warning "creating selector for nonexistent method .b1ar." } */ +@end +/* { dg-warning "creating selector for nonexistent method .b1ar." "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/objc.dg/selector-3.m b/gcc/testsuite/objc.dg/selector-3.m new file mode 100644 index 00000000000..49f7e417208 --- /dev/null +++ b/gcc/testsuite/objc.dg/selector-3.m @@ -0,0 +1,26 @@ +/* Test warning for non-existent selectors. */ +/* This is the "-fgnu-runtime" variant of objc.dg/selector-1.m. */ +/* { dg-options "-Wselector -fgnu-runtime" } */ +/* { dg-do compile } */ + +typedef struct objc_object { struct objc_class *class_pointer; } *id; +typedef const struct objc_selector *SEL; + +@interface Foo +- (void) foo; +- (void) bar; +@end + +@implementation Foo +- (void) bar +{ +} + +- (void) foo +{ + SEL a,b,c; + a = @selector(b1ar); + b = @selector(bar); +} +@end /* { dg-warning "creating selector for nonexistent method .b1ar." } */ + diff --git a/gcc/testsuite/objc.dg/selector-4.m b/gcc/testsuite/objc.dg/selector-4.m new file mode 100644 index 00000000000..d34f8c89cd6 --- /dev/null +++ b/gcc/testsuite/objc.dg/selector-4.m @@ -0,0 +1,30 @@ +/* Test whether including C++ keywords such as 'and', 'or', + 'not', etc., is allowed inside ObjC selectors (as it must be). */ +/* Author: Ziemowit Laski <zlaski@apple.com>. */ + +/* { dg-do compile } */ + +@interface Int1 ++ (int)and_eq:(int)arg1 and:(int)arg2; +- (int)or_eq:(int)arg1 or:(int)arg3; +- (int)not:(int)arg1 xor:(int)arg2; +- (void)bitand:(char)c1 bitor:(char)c2; +- (void)compl:(float)f1 xor_eq:(double)d1; +- (void)not_eq; +@end + +@implementation Int1 ++ (int)and_eq:(int)arg1 and:(int)arg2 { return arg1 + arg2; } +- (int)or_eq:(int)arg1 or:(int)arg3 { return arg1 + arg3; } +- (int)not:(int)arg1 xor:(int)arg2 { return arg1 + arg2; } +- (void)bitand:(char)c1 bitor:(char)c2 { } +- (void)compl:(float)f1 xor_eq:(double)d1 { } +- (void)not_eq { } +@end + +/* { dg-final { scan-assembler "\\+\\\[Int1 and_eq:and:\\]|c_Int1__and_eq_and" } } */ +/* { dg-final { scan-assembler "\\-\\\[Int1 or_eq:or:\\]|i_Int1__or_eq_or" } } */ +/* { dg-final { scan-assembler "\\-\\\[Int1 not:xor:\\]|i_Int1__not_xor" } } */ +/* { dg-final { scan-assembler "\\-\\\[Int1 bitand:bitor:\\]|i_Int1__bitand_bitor" } } */ +/* { dg-final { scan-assembler "\\-\\\[Int1 compl:xor_eq:\\]|i_Int1__compl_xor_eq" } } */ +/* { dg-final { scan-assembler "\\-\\\[Int1 not_eq\\]|i_Int1__not_eq" } } */ diff --git a/gcc/testsuite/objc.dg/stubify-1.m b/gcc/testsuite/objc.dg/stubify-1.m new file mode 100644 index 00000000000..2b1aa61cf59 --- /dev/null +++ b/gcc/testsuite/objc.dg/stubify-1.m @@ -0,0 +1,33 @@ +/* All calls must be properly stubified. Complain about any "call + _objc_msgSend<end-of-line>" without the $stub suffix. */ + +/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-options "-Os -mdynamic-no-pic" } */ + +typedef struct objc_object { } *id ; +int x = 41 ; +extern id objc_msgSend(id self, char * op, ...); +extern int bogonic (int, int, int) ; +@interface Document {} +- (Document *) window; +- (Document *) class; +- (Document *) close; +@end +@implementation Document +- (Document *) class { } +- (Document *) close { } +- (Document *) window { } +- (void)willEndCloseSheet:(void *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { + [[self window] close]; + ((void (*)(id, char *, int))objc_msgSend)([self class], (char *)contextInfo, 1); + ((void (*)(id, char *, int))bogonic)([self class], (char *)contextInfo, 1); + bogonic (3, 4, 5); + x++; +} +@end + +/* { dg-final { scan-assembler-not "\(bl|call\)\[ \t\]+_objc_msgSend\n" } } */ +/* { dg-final { scan-assembler "\(bl|call\)\[ \t\]+L_objc_msgSend\\\$stub\n" } } */ +/* { dg-final { scan-assembler-not "\(bl|call\)\[ \t\]+_bogonic\n" } } */ +/* { dg-final { scan-assembler "\(bl|call\)\[ \t\]+L_bogonic\\\$stub\n" } } */ +/* { dg-final { scan-assembler-not "\\\$non_lazy_ptr" } } */ diff --git a/gcc/testsuite/objc.dg/stubify-2.m b/gcc/testsuite/objc.dg/stubify-2.m new file mode 100644 index 00000000000..6e9b3a019fd --- /dev/null +++ b/gcc/testsuite/objc.dg/stubify-2.m @@ -0,0 +1,31 @@ +/* All calls must be properly stubified. */ +/* Testcase extracted from TextEdit:Document.m. */ + +/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-options "-mdynamic-no-pic -fdump-rtl-jump" } */ + +typedef struct objc_object { } *id ; +int x = 41 ; +extern id objc_msgSend(id self, char * op, ...); +extern int bogonic (int, int, int) ; +@interface Document {} +- (Document *) window; +- (Document *) class; +- (Document *) close; +@end +@implementation Document +- (Document *) class { } +- (Document *) close { } +- (Document *) window { } +- (void)willEndCloseSheet:(void *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { + [[self window] close]; + ((void (*)(id, char *, int))objc_msgSend)([self class], (char *)contextInfo, 1); + ((void (*)(id, char *, int))bogonic)([self class], (char *)contextInfo, 1); + bogonic (3, 4, 5); + x++; +} +@end + +/* Any symbol_ref of an un-stubified objc_msgSend is an error; look + for "objc_msgSend" in quotes, without the $stub suffix. */ +/* { dg-final { scan-file-not stubify-2.m.03.jump "symbol_ref.*\"objc_msgSend\"" } } */ diff --git a/gcc/testsuite/objc.dg/super-class-4.m b/gcc/testsuite/objc.dg/super-class-4.m new file mode 100644 index 00000000000..5248123e79a --- /dev/null +++ b/gcc/testsuite/objc.dg/super-class-4.m @@ -0,0 +1,34 @@ +/* Bail out gracefully if attempting to derive from a class that has only been + forward-declared (via @class). Conversely, @compatibility_alias declarations + should be traversed to find the @interface. */ +/* { dg-do compile } */ + +#include <objc/Object.h> + +@class MyWpModule; + +@compatibility_alias MyObject Object; +@compatibility_alias FictitiousModule MyWpModule; + +@protocol MySelTarget +- (id) meth1; +@end + +@protocol Img +- (id) meth2; +@end + +@interface FunnyModule: FictitiousModule <Img> /* { dg-error ".MyWpModule., superclass of .FunnyModule." } */ +- (id) meth2; +@end + +@interface MyProjWpModule : MyWpModule <MySelTarget, Img> /* { dg-error ".MyWpModule., superclass of .MyProjWpModule." } */ { + id i1, i2; +} +- (id) meth1; +- (id) meth2; +@end + +@interface AnotherModule: MyObject <MySelTarget> +- (id) meth1; +@end diff --git a/gcc/testsuite/objc.dg/super-dealloc-1.m b/gcc/testsuite/objc.dg/super-dealloc-1.m new file mode 100644 index 00000000000..0ab177bb73c --- /dev/null +++ b/gcc/testsuite/objc.dg/super-dealloc-1.m @@ -0,0 +1,46 @@ +/* Check for warnings about missing [super dealloc] calls. */ +/* Author: Ziemowit Laski <zlaski@apple.com> */ + +/* { dg-do compile } */ + +@interface Foo { + void *isa; +} +- (void) dealloc; +- (void) some_other; +@end + +@interface Bar: Foo { + void *casa; +} +- (void) dealloc; +@end + +@interface Baz: Bar { + void *usa; +} +- (void) dealloc; +@end + +@implementation Foo +- (void) dealloc { + isa = 0; /* Should not warn here. */ +} +- (void) some_other { + isa = (void *)-1; +} +@end + +@implementation Bar +- (void) dealloc { + casa = 0; + [super some_other]; +} /* { dg-warning "method possibly missing a .super dealloc. call" } */ +@end + +@implementation Baz +- (void) dealloc { + usa = 0; + [super dealloc]; /* Should not warn here. */ +} +@end diff --git a/gcc/testsuite/objc.dg/super-dealloc-2.m b/gcc/testsuite/objc.dg/super-dealloc-2.m new file mode 100644 index 00000000000..80dcf495062 --- /dev/null +++ b/gcc/testsuite/objc.dg/super-dealloc-2.m @@ -0,0 +1,46 @@ +/* Check for warnings about missing [super dealloc] calls. */ +/* Author: Ziemowit Laski <zlaski@apple.com> */ + +/* { dg-do compile } */ + +@interface Foo { + void *isa; +} +- (void) dealloc; +- (void) some_other; +@end + +@interface Bar: Foo { + void *casa; +} +- (void) dealloc0; +@end + +@interface Baz: Bar { + void *usa; +} +- (void) dealloc; +@end + +@implementation Foo +- (void) dealloc { + isa = 0; /* Should not warn here. */ +} +- (void) some_other { + isa = (void *)-1; +} +@end + +@implementation Bar +- (void) dealloc0 { + casa = 0; + [super some_other]; /* Should not warn here. */ +} +@end + +@implementation Baz +- (void) dealloc { + usa = 0; + [super dealloc0]; +} /* { dg-warning "method possibly missing a .super dealloc. call" } */ +@end diff --git a/gcc/testsuite/objc.dg/try-catch-6.m b/gcc/testsuite/objc.dg/try-catch-6.m new file mode 100644 index 00000000000..5276f0f68d1 --- /dev/null +++ b/gcc/testsuite/objc.dg/try-catch-6.m @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-fobjc-exceptions" } */ + +#include <objc/Object.h> + +int main (int argc, const char * argv[]) { + Object * pool = [Object new]; + int a; + + if ( 1 ) { + + @try { + a = 1; + } + @catch (Object *e) { + a = 2; + } + @finally { + a = 3; + } + } + + [pool free]; + return 0; +} diff --git a/gcc/testsuite/objc.dg/try-catch-7.m b/gcc/testsuite/objc.dg/try-catch-7.m new file mode 100644 index 00000000000..b1e1cd191c6 --- /dev/null +++ b/gcc/testsuite/objc.dg/try-catch-7.m @@ -0,0 +1,27 @@ +/* Test for graceful compilation of @synchronized statements. */ + +/* { dg-do compile } */ +/* { dg-options "-fobjc-exceptions" } */ + +#include <objc/Object.h> + +@interface Derived: Object +- (id) meth; +@end + +@implementation Derived +- (id) meth { + return self; +} + +static Derived* rewriteDict(void) { + static Derived *sDict = 0; + if (sDict == 0) { + @synchronized ([Derived class]) { + if (sDict == 0) + sDict = [Derived new]; + } + } + return sDict; +} +@end diff --git a/gcc/testsuite/objc.dg/try-catch-8.m b/gcc/testsuite/objc.dg/try-catch-8.m new file mode 100644 index 00000000000..1e5230edffe --- /dev/null +++ b/gcc/testsuite/objc.dg/try-catch-8.m @@ -0,0 +1,65 @@ +/* Check that local variables that get modified inside the @try + block survive until the @catch block is reached. */ +/* Developed by Ziemowit Laski <zlaski@apple.com>. */ + +/* { dg-options "-fobjc-exceptions -O2" } */ +/* { dg-do run { target *-*-darwin* } } */ + +#include <objc/Object.h> +#include <stdlib.h> +#include <stdio.h> + +int gi1 = 9, gi2 = 19; +float gf1 = 9.0, gf2 = 19.0; +id obj2 = nil; + +void foo (int arg1, float *arg2) +{ + int *pi = &gi1; + float *pf = &gf1; + id obj1 = nil; + int local1 = 45, local2 = 47; + float local3 = 3.0, local4 = 4.0; + register int local5 = 15; + static float local6 = 16.0; + + @try { + local1 = 123; + local2 = 345; + local3 = 5.0; + local4 = 6.0; + local5 = 17; + local6 = 18.0; + pi = &gi2; + pf = &gf2; + obj2 = obj1 = [Object new]; + arg1 = 17; + arg2 = &gf2; + + @throw [Object new]; + } + @catch (Object *obj) { + if (local1 != 123 || local2 != 345 || local3 != 5.0 || local4 != 6.0 + || local5 != 17 || local6 != 18.0) { + printf("Abort 1\n"); + abort(); + } + if(pi != &gi2 || pf != &gf2) { + printf("Abort 2\n"); + abort(); + } + if(!obj1 || obj1 != obj2) { + printf("Abort 3\n"); + abort(); + } + if(arg1 != 17 || arg2 != &gf2) { + printf("Abort 4\n"); + abort(); + } + } +} + +int main(void) { + foo(15, &gf1); + return 0; +} diff --git a/gcc/testsuite/objc.dg/try-catch-9.m b/gcc/testsuite/objc.dg/try-catch-9.m new file mode 100644 index 00000000000..5f6daa42bf3 --- /dev/null +++ b/gcc/testsuite/objc.dg/try-catch-9.m @@ -0,0 +1,25 @@ +/* Check that taking the address of a local variable marked 'volatile' + by the compiler does not generate untoward errors. */ +/* Developed by Ziemowit Laski <zlaski@apple.com>. */ + +/* { dg-options "-fobjc-exceptions" } */ +/* { dg-do compile } */ + + +void foo (int *arg1, int *arg2) +{ + *arg1 = *arg2; +} + +void bar (int arg) { + int rcvr; + + @try { + rcvr = arg; + } + @finally { + int *rcvr0 = &rcvr; + foo (rcvr0, &arg); + } +} + |