From e2673f71ca5027f30b0bfadc7181b88df0581a18 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Thu, 14 Oct 2010 20:11:03 +0000 Subject: [PATCH] add ObjC* @property - tests add ObjC* @property - tests gcc/testsuite: * objc.dg/property: New. * objc.dg/property/fsf-property-basic.m: New. * objc.dg/property/fsf-property-method-access.m: New. * objc.dg/property/fsf-property-named-ivar.m: New. * objc.dg/property/property-1.m: New. * objc.dg/property/property-2.m: New. * objc.dg/property/property-3.m: New. * objc.dg/property/property-neg-1.m: New. * objc.dg/property/property-neg-2.m: New. * objc.dg/property/property-neg-3.m: New. * objc.dg/property/property-neg-4.m: New. * objc.dg/property/property-neg-5.m: New. * objc.dg/property/property-neg-6.m: New. * objc.dg/property/property-neg-7.m: New. * objc.dg/property/property.exp: New. * obj-c++.dg/property * obj-c++.dg/property/fsf-property-basic.mm * obj-c++.dg/property/fsf-property-method-access.mm * obj-c++.dg/property/fsf-property-named-ivar.mm * obj-c++.dg/property/property-0.mm * obj-c++.dg/property/property-1.mm * obj-c++.dg/property/property-2.mm * obj-c++.dg/property/property-3.mm * obj-c++.dg/property/property-neg-1.mm * obj-c++.dg/property/property-neg-2.mm * obj-c++.dg/property/property-neg-3.mm * obj-c++.dg/property/property-neg-4.mm * obj-c++.dg/property/property-neg-5.mm * obj-c++.dg/property/property-neg-6.mm * obj-c++.dg/property/property-neg-7.mm * obj-c++.dg/property/property.exp From-SVN: r165480 --- gcc/testsuite/ChangeLog | 38 ++++++++ .../obj-c++.dg/property/fsf-property-basic.mm | 80 +++++++++++++++++ .../property/fsf-property-method-access.mm | 86 +++++++++++++++++++ .../property/fsf-property-named-ivar.mm | 81 +++++++++++++++++ .../obj-c++.dg/property/property-1.mm | 31 +++++++ .../obj-c++.dg/property/property-2.mm | 62 +++++++++++++ .../obj-c++.dg/property/property-3.mm | 75 ++++++++++++++++ .../obj-c++.dg/property/property-neg-1.mm | 14 +++ .../obj-c++.dg/property/property-neg-2.mm | 9 ++ .../obj-c++.dg/property/property-neg-3.mm | 14 +++ .../obj-c++.dg/property/property-neg-4.mm | 18 ++++ .../obj-c++.dg/property/property-neg-5.mm | 7 ++ .../obj-c++.dg/property/property-neg-6.mm | 9 ++ .../obj-c++.dg/property/property-neg-7.mm | 19 ++++ .../obj-c++.dg/property/property.exp | 42 +++++++++ .../objc.dg/property/fsf-property-basic.m | 74 ++++++++++++++++ .../property/fsf-property-method-access.m | 80 +++++++++++++++++ .../property/fsf-property-named-ivar.m | 75 ++++++++++++++++ gcc/testsuite/objc.dg/property/property-1.m | 32 +++++++ gcc/testsuite/objc.dg/property/property-2.m | 63 ++++++++++++++ gcc/testsuite/objc.dg/property/property-3.m | 75 ++++++++++++++++ .../objc.dg/property/property-neg-1.m | 14 +++ .../objc.dg/property/property-neg-2.m | 9 ++ .../objc.dg/property/property-neg-3.m | 14 +++ .../objc.dg/property/property-neg-4.m | 17 ++++ .../objc.dg/property/property-neg-5.m | 7 ++ .../objc.dg/property/property-neg-6.m | 8 ++ .../objc.dg/property/property-neg-7.m | 19 ++++ gcc/testsuite/objc.dg/property/property.exp | 42 +++++++++ 29 files changed, 1114 insertions(+) create mode 100644 gcc/testsuite/obj-c++.dg/property/fsf-property-basic.mm create mode 100644 gcc/testsuite/obj-c++.dg/property/fsf-property-method-access.mm create mode 100644 gcc/testsuite/obj-c++.dg/property/fsf-property-named-ivar.mm create mode 100644 gcc/testsuite/obj-c++.dg/property/property-1.mm create mode 100644 gcc/testsuite/obj-c++.dg/property/property-2.mm create mode 100644 gcc/testsuite/obj-c++.dg/property/property-3.mm create mode 100644 gcc/testsuite/obj-c++.dg/property/property-neg-1.mm create mode 100644 gcc/testsuite/obj-c++.dg/property/property-neg-2.mm create mode 100644 gcc/testsuite/obj-c++.dg/property/property-neg-3.mm create mode 100644 gcc/testsuite/obj-c++.dg/property/property-neg-4.mm create mode 100644 gcc/testsuite/obj-c++.dg/property/property-neg-5.mm create mode 100644 gcc/testsuite/obj-c++.dg/property/property-neg-6.mm create mode 100644 gcc/testsuite/obj-c++.dg/property/property-neg-7.mm create mode 100644 gcc/testsuite/obj-c++.dg/property/property.exp create mode 100644 gcc/testsuite/objc.dg/property/fsf-property-basic.m create mode 100644 gcc/testsuite/objc.dg/property/fsf-property-method-access.m create mode 100644 gcc/testsuite/objc.dg/property/fsf-property-named-ivar.m create mode 100644 gcc/testsuite/objc.dg/property/property-1.m create mode 100644 gcc/testsuite/objc.dg/property/property-2.m create mode 100644 gcc/testsuite/objc.dg/property/property-3.m create mode 100644 gcc/testsuite/objc.dg/property/property-neg-1.m create mode 100644 gcc/testsuite/objc.dg/property/property-neg-2.m create mode 100644 gcc/testsuite/objc.dg/property/property-neg-3.m create mode 100644 gcc/testsuite/objc.dg/property/property-neg-4.m create mode 100644 gcc/testsuite/objc.dg/property/property-neg-5.m create mode 100644 gcc/testsuite/objc.dg/property/property-neg-6.m create mode 100644 gcc/testsuite/objc.dg/property/property-neg-7.m create mode 100644 gcc/testsuite/objc.dg/property/property.exp diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3f98ce98217f..f722e3747dc5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,41 @@ +2010-10-14 Iain Sandoe + + * objc.dg/property: New. + * objc.dg/property/fsf-property-basic.m: New. + * objc.dg/property/fsf-property-method-access.m: New. + * objc.dg/property/fsf-property-named-ivar.m: New. + * obj-c++.dg/property: New. + * obj-c++.dg/property/fsf-property-basic.mm: New. + * obj-c++.dg/property/fsf-property-method-access.mm: New. + * obj-c++.dg/property/fsf-property-named-ivar.mm: New. + + merge from FSF apple 'trunk' branch. + 2006 Fariborz Jahanian + + Radars 4436866, 4505126, 4506903, 4517826 + * objc.dg/property/property-1.m: New. + * objc.dg/property/property-2.m: New. + * objc.dg/property/property-3.m: New. + * objc.dg/property/property-neg-1.m: New. + * objc.dg/property/property-neg-2.m: New. + * objc.dg/property/property-neg-3.m: New. + * objc.dg/property/property-neg-4.m: New. + * objc.dg/property/property-neg-5.m: New. + * objc.dg/property/property-neg-6.m: New. + * objc.dg/property/property-neg-7.m: New. + * objc.dg/property/property.exp: New. + * obj-c++.dg/property/property-1.mm: New. + * obj-c++.dg/property/property-2.mm: New. + * obj-c++.dg/property/property-3.mm: New. + * obj-c++.dg/property/property-neg-1.mm: New. + * obj-c++.dg/property/property-neg-2.mm: New. + * obj-c++.dg/property/property-neg-3.mm: New. + * obj-c++.dg/property/property-neg-4.mm: New. + * obj-c++.dg/property/property-neg-5.mm: New. + * obj-c++.dg/property/property-neg-6.mm: New. + * obj-c++.dg/property/property-neg-7.mm: New. + * obj-c++.dg/property/property.exp: New. + 2010-10-14 H.J. Lu * gcc.dg/pr45570.c: Fix typos. Also run for i?86-*-*. diff --git a/gcc/testsuite/obj-c++.dg/property/fsf-property-basic.mm b/gcc/testsuite/obj-c++.dg/property/fsf-property-basic.mm new file mode 100644 index 000000000000..502ac0d806e3 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/fsf-property-basic.mm @@ -0,0 +1,80 @@ +/* Basic test, auto-generated getter/setter based on property name. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int printf (const char *fmt,...) ; +extern void abort (void); + +typedef struct objc_class *Class; + +#ifdef __NEXT_RUNTIME__ + +extern id class_createInstance(Class, long); +#define class_create_instance(C) class_createInstance(C, 0) + +#else + +extern id class_create_instance(Class); + +#endif +#ifdef __cplusplus +} +#endif + +@interface Bar +{ +@public +#ifdef __NEXT_RUNTIME__ + Class isa; +#else + Class class_pointer; +#endif + int var; +} ++ (id) initialize; ++ (id) alloc ; + - (id) init; + +@property int FooBar; +@end + +@implementation Bar + ++initialize { return self;} ++ (id) alloc { return class_create_instance(self);} + +- (id) init {return self;} + +@property int FooBar ; +@end + +int main(int argc, char *argv[]) { + int res; + Bar *f = [[Bar alloc] init]; + + /* First, establish that the property getter & setter have been synthesized + and operate correctly. */ + [f setFooBar:1]; + + if (f->_FooBar != 1) + { printf ("setFooBar did not set _FooBar\n"); abort ();} + + res = [f FooBar]; + + if (res != 1 ) + { printf ("[f FooBar] = %d\n", res); abort ();} + + /* Now check the short-cut CLASS.property syntax. */ + res = f.FooBar; + if (res != 1 ) + { printf ("f,FooBar = %d\n", res); abort ();} + + f.FooBar = 0; + printf ("seems OK\n", res); + return f.FooBar; +} + diff --git a/gcc/testsuite/obj-c++.dg/property/fsf-property-method-access.mm b/gcc/testsuite/obj-c++.dg/property/fsf-property-method-access.mm new file mode 100644 index 000000000000..4052d1600d3c --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/fsf-property-method-access.mm @@ -0,0 +1,86 @@ +/* test access in methods, auto-generated getter/setter based on property name. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +#ifdef __cplusplus +extern "C" { +#endif +extern int printf (const char *fmt,...) ; +extern void abort (void); + +typedef struct objc_class *Class; + +#ifdef __NEXT_RUNTIME__ + +extern id class_createInstance(Class, long); +#define class_create_instance(C) class_createInstance(C, 0) + +#else + +extern id class_create_instance(Class); + +#endif +#ifdef __cplusplus +} +#endif + +@interface Bar +{ +@public +#ifdef __NEXT_RUNTIME__ + Class isa; +#else + Class class_pointer; +#endif +} ++ (id) initialize; ++ (id) alloc ; +- (id) init; + +- (int) lookAtProperty; +- (void) setProperty: (int) v; + +@property int FooBar; +@end + +@implementation Bar + ++initialize { return self;} ++ (id) alloc { return class_create_instance(self);} + +- (id) init {return self;} + +@property int FooBar; + +- (int) lookAtProperty { return FooBar; } +- (void) setProperty: (int) v { FooBar = v; } + +@end + +int main(int argc, char *argv[]) { + int res; + Bar *f = [[Bar alloc] init]; + + /* First, establish that the property getter & setter have been synthesized + and operate correctly. */ + [f setProperty:11]; + + if (f->_FooBar != 11) + { printf ("setProperty did not set _FooBar\n"); abort ();} + + res = [f lookAtProperty]; + if (res != 11 ) + { printf ("[f lookAtProperty] = %d\n", res); abort ();} + + /* Make sure we haven't messed up the shortcut form. */ + /* read ... */ + res = f.FooBar; + if (res != 11 ) + { printf ("f.FooBar = %d\n", res); abort ();} + + /* ... write. */ + f.FooBar = 0; + /* printf ("seems OK\n", res); */ + return f.FooBar; +} + diff --git a/gcc/testsuite/obj-c++.dg/property/fsf-property-named-ivar.mm b/gcc/testsuite/obj-c++.dg/property/fsf-property-named-ivar.mm new file mode 100644 index 000000000000..4b29c92c7b1e --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/fsf-property-named-ivar.mm @@ -0,0 +1,81 @@ +/* Basic test, auto-generated getter/setter based on named ivar */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +#ifdef __cplusplus +extern "C" { +#endif +extern int printf (const char *fmt,...) ; +extern void abort (void); + +typedef struct objc_class *Class; + +#ifdef __NEXT_RUNTIME__ + +extern id class_createInstance(Class, long); +#define class_create_instance(C) class_createInstance(C, 0) + +#else + +extern id class_create_instance(Class); + +#endif +#ifdef __cplusplus +} +#endif + +@interface Bar +{ +@public +#ifdef __NEXT_RUNTIME__ + Class isa; +#else + Class class_pointer; +#endif + int var; +} ++ (id) initialize; ++ (id) alloc ; +- (id) init; + +@property int FooBar; +@end + +@implementation Bar + ++initialize { return self;} ++ (id) alloc { return class_create_instance(self);} + +- (id) init {return self;} + +@property (ivar = var) int FooBar ; +@end + +int main(int argc, char *argv[]) { + int res; + Bar *f = [[Bar alloc] init]; + + /* First, establish that the property getter & setter have been synthesized + and operate correctly. */ + [f setFooBar:1234]; + + if (f->var != 1234) + { printf ("setFooBar did not set var correctly\n"); abort ();} + + res = [f FooBar]; + + if (res != 1234 ) + { printf ("[f FooBar] = %d\n", res); abort ();} + + /* Now check the short-cut CLASS.property syntax. */ + /* Read .... */ + res = f.FooBar; + if (res != 1234 ) + { printf ("f.FooBar = %d\n", res); abort ();} + + /* ... and write. */ + f.FooBar = 0; + /* printf ("seems OK\n", res); */ + return f.FooBar; +} + diff --git a/gcc/testsuite/obj-c++.dg/property/property-1.mm b/gcc/testsuite/obj-c++.dg/property/property-1.mm new file mode 100644 index 000000000000..c9b9c46423a2 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/property-1.mm @@ -0,0 +1,31 @@ +/* This program tests use of property provided setter/getter functions. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ +/* { dg-additional-sources "../../objc-obj-c++-shared/Object1.mm" } */ + +#import "../../objc-obj-c++-shared/Object1.h" + +@interface Bar : Object +{ + int iVar; +} +@property int FooBar; +@end + +@implementation Bar +@property (ivar = iVar, setter = MySetter:) int FooBar; + +- (void) MySetter : (int) value { iVar = value; } + +@end + +int main(int argc, char *argv[]) { + Bar *f = [Bar new]; + f.FooBar = 1; + + f.FooBar += 3; + + f.FooBar -= 4; + return f.FooBar; +} + diff --git a/gcc/testsuite/obj-c++.dg/property/property-2.mm b/gcc/testsuite/obj-c++.dg/property/property-2.mm new file mode 100644 index 000000000000..5d55b407cd63 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/property-2.mm @@ -0,0 +1,62 @@ +/* { dg-do run { target *-*-darwin* } } */ +/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ +/* We can't do this yet on m64, since we have not got the NSConstantString implementation + built-in to the compiler, and therefore we get missing implementation warnings. */ +/* { dg-require-effective-target ilp32 } */ +/* Force ABI = 0 in the NeXT headers, also suppress deprecation warnings. */ +/* { dg-options "-framework Foundation -fobjc-exceptions -mmacosx-version-min=10.4 -Wno-deprecated-declarations" } */ + +#include +#include + +@interface Person : NSObject +@property NSString *firstName, *lastName; +@property(readonly) NSString *fullName; +@end + +@interface Group : NSObject +@property Person *techLead, *runtimeGuru, *propertiesMaven; +@end + +@implementation Group +@property Person *techLead, *runtimeGuru, *propertiesMaven; +- init { + techLead = [[Person alloc] init]; + runtimeGuru = [[Person alloc] init]; + propertiesMaven = [[Person alloc] init]; + return self; +} +@end + +@implementation Person +@property NSString *firstName, *lastName; +@property(readonly) NSString *fullName; +- (NSString*)fullName { // computed getter + return [NSString stringWithFormat:@"%@ %@", firstName, lastName]; +} +@end + +NSString *playWithProperties() +{ + Group *g = [[Group alloc] init] ; + + g.techLead.firstName = @"Blaine"; + g.techLead.lastName = @"Garst"; + g.runtimeGuru.firstName = @"Greg"; + g.runtimeGuru.lastName = @"Parker"; + g.propertiesMaven.firstName = @"Patrick"; + g.propertiesMaven.lastName = @"Beard"; + + return [NSString stringWithFormat:@"techlead %@ runtimeGuru %@ propertiesMaven %@", + g.techLead.fullName, g.runtimeGuru.fullName, g.propertiesMaven.fullName]; +} + +main() +{ + char buf [256]; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + sprintf(buf, "%s", [playWithProperties() cString]); + [pool release]; + return strcmp (buf, "techlead Blaine Garst runtimeGuru Greg Parker propertiesMaven Patrick Beard"); +} + diff --git a/gcc/testsuite/obj-c++.dg/property/property-3.mm b/gcc/testsuite/obj-c++.dg/property/property-3.mm new file mode 100644 index 000000000000..5a83263e8dc1 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/property-3.mm @@ -0,0 +1,75 @@ +/* This program tests use of properties . */ +/* { dg-do run { target *-*-darwin* } } */ +/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ +/* We can't do this yet on m64, since we have not got the NSConstantString implementation + built-in to the compiler, and therefore we get missing implementation warnings. */ +/* { dg-require-effective-target ilp32 } */ +/* Force ABI = 0 in the NeXT headers, also suppress deprecation warnings. */ +/* { dg-options "-framework Foundation -fobjc-exceptions -mmacosx-version-min=10.4 -Wno-deprecated-declarations" } */ + +#include +#include + +@interface Person : NSObject +{ +} +@property NSString *firstName, *lastName; +@property(readonly) NSString *fullName; + +@end + +@interface Group : NSObject +{ +} + +@property Person *techLead, *runtimeGuru, *propertiesMaven; + +@end + +@implementation Group + +@property Person *techLead, *runtimeGuru, *propertiesMaven; +- init { + techLead = [[Person alloc] init]; + runtimeGuru = [[Person alloc] init]; + propertiesMaven = [[Person alloc] init]; + return self; +} + +@end + +@implementation Person + +@property NSString *firstName, *lastName; +@property(readonly, getter = fullName) NSString *fullName; + +- (NSString*)fullName { // computed getter + return [NSString stringWithFormat:@"%@ %@", firstName, lastName]; +} + +@end + +NSString *playWithProperties() +{ + Group *g = [[Group alloc] init] ; + + g.techLead.firstName = @"Blaine"; + g.techLead.lastName = @"Garst"; + g.runtimeGuru.firstName = @"Greg"; + g.runtimeGuru.lastName = @"Parker"; + g.propertiesMaven.firstName = @"Patrick"; + g.propertiesMaven.lastName = @"Beard"; + + return [NSString stringWithFormat:@"techlead %@ runtimeGuru %@ propertiesMaven %@", + g.techLead.fullName, g.runtimeGuru.fullName, g.propertiesMaven.fullName]; +} + +main() +{ + char buf [256]; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + sprintf(buf, "%s", [playWithProperties() cString]); + [pool release]; + return strcmp (buf, "techlead Blaine Garst runtimeGuru Greg Parker propertiesMaven Patrick Beard"); +} + diff --git a/gcc/testsuite/obj-c++.dg/property/property-neg-1.mm b/gcc/testsuite/obj-c++.dg/property/property-neg-1.mm new file mode 100644 index 000000000000..2989c3b9295d --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/property-neg-1.mm @@ -0,0 +1,14 @@ +/* This program checks for proper use of 'readonly' attribute. */ +/* { dg-do compile } */ + +@interface Bar +{ + int iVar; +} +@property (readonly) int FooBar; +@end + +@implementation Bar +@property int FooBar; /* { dg-error " property 'FooBar' 'readonly' attribute conflicts with its interface version" } */ + +@end diff --git a/gcc/testsuite/obj-c++.dg/property/property-neg-2.mm b/gcc/testsuite/obj-c++.dg/property/property-neg-2.mm new file mode 100644 index 000000000000..7046da84732a --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/property-neg-2.mm @@ -0,0 +1,9 @@ +/* This program checks for proper declaration of property. */ +/* { dg-do compile } */ + +@interface Bar +@end + +@implementation Bar +@property int foo; /* { dg-error "no declaration of property 'foo' found in the interface" } */ +@end diff --git a/gcc/testsuite/obj-c++.dg/property/property-neg-3.mm b/gcc/testsuite/obj-c++.dg/property/property-neg-3.mm new file mode 100644 index 000000000000..07438a6f375f --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/property-neg-3.mm @@ -0,0 +1,14 @@ +/* Property name cannot match the ivar name. */ +/* { dg-do compile } */ +/* Suppress warnings for incomplete class definition etc. */ +/* { dg-options "-w" } */ + +@interface Person +{ + char *firstName; +} +@property char *firstName; /* { dg-error "property 'firstName' may not have the same name as an ivar in the class" } */ +@end + +@implementation Person +@end diff --git a/gcc/testsuite/obj-c++.dg/property/property-neg-4.mm b/gcc/testsuite/obj-c++.dg/property/property-neg-4.mm new file mode 100644 index 000000000000..b3dbb6052780 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/property-neg-4.mm @@ -0,0 +1,18 @@ +/* Property cannot be accessed in class method. */ +/* { dg-do compile } */ + +@interface Person +{ +} +@property char *fullName; ++ (void) testClass; +@end + +@implementation Person +@property char *fullName; ++ (void) testClass { + fullName = "MyName"; /* { dg-error "property 'fullName' accessed in class method" } */ + /* { dg-error "'fullName' was not declared in this scope" "" { target *-*-* } 14 } */ +} +@end + diff --git a/gcc/testsuite/obj-c++.dg/property/property-neg-5.mm b/gcc/testsuite/obj-c++.dg/property/property-neg-5.mm new file mode 100644 index 000000000000..53fada261987 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/property-neg-5.mm @@ -0,0 +1,7 @@ +/* getter/setter cannot be specified in an interface. */ +/* { dg-do compile } */ + +@interface Foo +@property ( readonly, getter = HELLO, setter = THERE : ) int value; +@end /* { dg-warning "getter = \\'HELLO\\' may not be specified in an interface" } */ + /* { dg-warning "setter = \\'THERE\\:\\' may not be specified in an interface" "" { target *-*-* } 6 } */ diff --git a/gcc/testsuite/obj-c++.dg/property/property-neg-6.mm b/gcc/testsuite/obj-c++.dg/property/property-neg-6.mm new file mode 100644 index 000000000000..86bb664851c8 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/property-neg-6.mm @@ -0,0 +1,9 @@ +/* Check for proper declaration of @property. */ +/* { dg-do compile } */ + +@interface Bar +{ + int iVar; +} +@property int FooBar /* { dg-error "expected ';' at end of input" } */ + /* { dg-error "expected '@end' at end of input" "" { target *-*-* } 8 } */ diff --git a/gcc/testsuite/obj-c++.dg/property/property-neg-7.mm b/gcc/testsuite/obj-c++.dg/property/property-neg-7.mm new file mode 100644 index 000000000000..506f097eb2a0 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/property-neg-7.mm @@ -0,0 +1,19 @@ +/* Cannot write into a read-only property. */ +/* { dg-do compile } */ +/* Suppress warnings for incomplete class definition etc. */ +/* { dg-options "-w" } */ + +@interface NSArray +@property(readonly) int count; +@end + +@implementation NSArray +@end + +void foo (NSArray *ans[], id pid, id apid[], int i) { + NSArray *test; + test.count = 1; /* { dg-error "readonly property can not be set" } */ + ((NSArray *)pid).count = 1; /* { dg-error "readonly property can not be set" } */ + ((NSArray *)apid[i]).count = 1; /* { dg-error "readonly property can not be set" } */ + ans[i].count = 3; /* { dg-error "readonly property can not be set" } */ +} diff --git a/gcc/testsuite/obj-c++.dg/property/property.exp b/gcc/testsuite/obj-c++.dg/property/property.exp new file mode 100644 index 000000000000..bff972ba57c6 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/property.exp @@ -0,0 +1,42 @@ +# GCC Objective-C++ testsuite that uses the `dg.exp' driver. +# Copyright (C) 2004, 2007 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# Load support procs. +load_lib obj-c++-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_OBJCXXFLAGS +if ![info exists DEFAULT_OBJCXXFLAGS] then { + set DEFAULT_OBJCXXFLAGS " -ansi -pedantic-errors -Wno-long-long" +} + +# Initialize `dg'. +dg-init + +# Gather a list of all tests. +set tests [lsort [glob -nocomplain $srcdir/$subdir/*.mm]] + +# Main loop. +dg-runtest $tests "-fgnu-runtime" $DEFAULT_OBJCXXFLAGS + +# darwin targets can also run code with the NeXT runtime. +if [istarget "*-*-darwin*" ] { +dg-runtest $tests "-fnext-runtime" $DEFAULT_OBJCXXFLAGS +} + +# All done. +dg-finish diff --git a/gcc/testsuite/objc.dg/property/fsf-property-basic.m b/gcc/testsuite/objc.dg/property/fsf-property-basic.m new file mode 100644 index 000000000000..13a00a2b3812 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/fsf-property-basic.m @@ -0,0 +1,74 @@ +/* Basic test, auto-generated getter/setter based on property name. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +extern int printf (char *fmt,...) ; +extern void abort (void); + +typedef struct objc_class *Class; + +#ifdef __NEXT_RUNTIME__ + +extern id class_createInstance(Class, long); +#define class_create_instance(C) class_createInstance(C, 0) + +#else + +extern id class_create_instance(Class); + +#endif + +@interface Bar +{ +@public +#ifdef __NEXT_RUNTIME__ + Class isa; +#else + Class class_pointer; +#endif +} ++ (id) initialize; ++ (id) alloc ; +- (id) init; + +@property int FooBar; +@end + +@implementation Bar + ++initialize { return self;} ++ (id) alloc { return class_create_instance(self);} + +- (id) init {return self;} + +@property int FooBar ; +@end + +int main(int argc, char *argv[]) { + int res; + Bar *f = [[Bar alloc] init]; + + /* First, establish that the property getter & setter have been synthesized + and operate correctly. */ + [f setFooBar:1]; + + if (f->_FooBar != 1) + { printf ("setFooBar did not set _FooBar\n"); abort ();} + + res = [f FooBar]; + + if (res != 1 ) + { printf ("[f FooBar] = %d\n", res); abort ();} + + /* Now check the short-cut CLASS.property syntax. */ + /* Read... */ + res = f.FooBar; + if (res != 1 ) + { printf ("f.FooBar = %d\n", res); abort ();} + + /* .... write. */ + f.FooBar = 0; + /* printf ("seems OK\n", res); */ + return f.FooBar; +} + diff --git a/gcc/testsuite/objc.dg/property/fsf-property-method-access.m b/gcc/testsuite/objc.dg/property/fsf-property-method-access.m new file mode 100644 index 000000000000..fae49690c733 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/fsf-property-method-access.m @@ -0,0 +1,80 @@ +/* test access in methods, auto-generated getter/setter based on property name. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +extern int printf (char *fmt,...) ; +extern void abort (void); + +typedef struct objc_class *Class; + +#ifdef __NEXT_RUNTIME__ + +extern id class_createInstance(Class, long); +#define class_create_instance(C) class_createInstance(C, 0) + +#else + +extern id class_create_instance(Class); + +#endif + +@interface Bar +{ +@public +#ifdef __NEXT_RUNTIME__ + Class isa; +#else + Class class_pointer; +#endif +} ++ (id) initialize; ++ (id) alloc ; +- (id) init; + +- (int) lookAtProperty; +- (void) setProperty: (int) v; + +@property int FooBar; +@end + +@implementation Bar + ++initialize { return self;} ++ (id) alloc { return class_create_instance(self);} + +- (id) init {return self;} + +@property int FooBar; + +- (int) lookAtProperty { return FooBar; } +- (void) setProperty: (int) v { FooBar = v; } + +@end + +int main(int argc, char *argv[]) { + int res; + Bar *f = [[Bar alloc] init]; + + /* First, establish that the property getter & setter have been synthesized + and operate correctly. */ + [f setProperty:11]; + + if (f->_FooBar != 11) + { printf ("setProperty did not set _FooBar\n"); abort ();} + + res = [f lookAtProperty]; + if (res != 11 ) + { printf ("[f lookAtProperty] = %d\n", res); abort ();} + + /* Make sure we haven't messed up the shortcut form. */ + /* read ... */ + res = f.FooBar; + if (res != 11 ) + { printf ("f.FooBar = %d\n", res); abort ();} + + /* ... write. */ + f.FooBar = 0; + /* printf ("seems OK\n", res); */ + return f.FooBar; +} + diff --git a/gcc/testsuite/objc.dg/property/fsf-property-named-ivar.m b/gcc/testsuite/objc.dg/property/fsf-property-named-ivar.m new file mode 100644 index 000000000000..837d303f317d --- /dev/null +++ b/gcc/testsuite/objc.dg/property/fsf-property-named-ivar.m @@ -0,0 +1,75 @@ +/* Basic test, auto-generated getter/setter based on named ivar */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +extern int printf (char *fmt,...) ; +extern void abort (void); + +typedef struct objc_class *Class; + +#ifdef __NEXT_RUNTIME__ + +extern id class_createInstance(Class, long); +#define class_create_instance(C) class_createInstance(C, 0) + +#else + +extern id class_create_instance(Class); + +#endif + +@interface Bar +{ +@public +#ifdef __NEXT_RUNTIME__ + Class isa; +#else + Class class_pointer; +#endif + int var; +} ++ (id) initialize; ++ (id) alloc ; +- (id) init; + +@property int FooBar; +@end + +@implementation Bar + ++initialize { return self;} ++ (id) alloc { return class_create_instance(self);} + +- (id) init {return self;} + +@property (ivar = var) int FooBar ; +@end + +int main(int argc, char *argv[]) { + int res; + Bar *f = [[Bar alloc] init]; + + /* First, establish that the property getter & setter have been synthesized + and operate correctly. */ + [f setFooBar:1234]; + + if (f->var != 1234) + { printf ("setFooBar did not set var correctly\n"); abort ();} + + res = [f FooBar]; + + if (res != 1234 ) + { printf ("[f FooBar] = %d\n", res); abort ();} + + /* Now check the short-cut CLASS.property syntax. */ + /* Read .... */ + res = f.FooBar; + if (res != 1234 ) + { printf ("f.FooBar = %d\n", res); abort ();} + + /* ... and write. */ + f.FooBar = 0; + /* printf ("seems OK\n", res); */ + return f.FooBar; +} + diff --git a/gcc/testsuite/objc.dg/property/property-1.m b/gcc/testsuite/objc.dg/property/property-1.m new file mode 100644 index 000000000000..89537ca925cc --- /dev/null +++ b/gcc/testsuite/objc.dg/property/property-1.m @@ -0,0 +1,32 @@ +/* This program tests use of property provided setter/getter functions. */ +/* { dg-options "-std=c99" } */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ +/* { dg-additional-sources "../../objc-obj-c++-shared/Object1.m" } */ + +#import "../../objc-obj-c++-shared/Object1.h" + +@interface Bar : Object +{ + int iVar; +} +@property int FooBar; +@end + +@implementation Bar +@property (ivar = iVar, setter = MySetter:) int FooBar; + +- (void) MySetter : (int) value { iVar = value; } + +@end + +int main(int argc, char *argv[]) { + Bar *f = [Bar new]; + f.FooBar = 1; + + f.FooBar += 3; + + f.FooBar -= 4; + return f.FooBar; +} + diff --git a/gcc/testsuite/objc.dg/property/property-2.m b/gcc/testsuite/objc.dg/property/property-2.m new file mode 100644 index 000000000000..2a923e060eff --- /dev/null +++ b/gcc/testsuite/objc.dg/property/property-2.m @@ -0,0 +1,63 @@ +/* This program tests use of properties . */ +/* { dg-do run { target *-*-darwin* } } */ +/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ +/* We can't do this yet on m64, since we have not got the NSConstantString implementation + built-in to the compiler, and therefore we get missing implementation warnings. */ +/* { dg-require-effective-target ilp32 } */ +/* Force ABI = 0 in the NeXT headers, also suppress deprecation warnings. */ +/* { dg-options "-framework Foundation -fobjc-exceptions -mmacosx-version-min=10.4 -Wno-deprecated-declarations" } */ + +#include +#include + +@interface Person : NSObject +@property NSString *firstName, *lastName; +@property(readonly) NSString *fullName; +@end + +@interface Group : NSObject +@property Person *techLead, *runtimeGuru, *propertiesMaven; +@end + +@implementation Group +@property Person *techLead, *runtimeGuru, *propertiesMaven; +- init { + techLead = [[Person alloc] init]; + runtimeGuru = [[Person alloc] init]; + propertiesMaven = [[Person alloc] init]; + return self; +} +@end + +@implementation Person +@property NSString *firstName, *lastName; +@property(readonly) NSString *fullName; +- (NSString*)fullName { // computed getter + return [NSString stringWithFormat:@"%@ %@", firstName, lastName]; +} +@end + +NSString *playWithProperties() +{ + Group *g = [[Group alloc] init] ; + + g.techLead.firstName = @"Blaine"; + g.techLead.lastName = @"Garst"; + g.runtimeGuru.firstName = @"Greg"; + g.runtimeGuru.lastName = @"Parker"; + g.propertiesMaven.firstName = @"Patrick"; + g.propertiesMaven.lastName = @"Beard"; + + return [NSString stringWithFormat:@"techlead %@ runtimeGuru %@ propertiesMaven %@", + g.techLead.fullName, g.runtimeGuru.fullName, g.propertiesMaven.fullName]; +} + +main() +{ + char buf [256]; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + sprintf(buf, "%s", [playWithProperties() cString]); + [pool release]; + return strcmp (buf, "techlead Blaine Garst runtimeGuru Greg Parker propertiesMaven Patrick Beard"); +} + diff --git a/gcc/testsuite/objc.dg/property/property-3.m b/gcc/testsuite/objc.dg/property/property-3.m new file mode 100644 index 000000000000..5a83263e8dc1 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/property-3.m @@ -0,0 +1,75 @@ +/* This program tests use of properties . */ +/* { dg-do run { target *-*-darwin* } } */ +/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ +/* We can't do this yet on m64, since we have not got the NSConstantString implementation + built-in to the compiler, and therefore we get missing implementation warnings. */ +/* { dg-require-effective-target ilp32 } */ +/* Force ABI = 0 in the NeXT headers, also suppress deprecation warnings. */ +/* { dg-options "-framework Foundation -fobjc-exceptions -mmacosx-version-min=10.4 -Wno-deprecated-declarations" } */ + +#include +#include + +@interface Person : NSObject +{ +} +@property NSString *firstName, *lastName; +@property(readonly) NSString *fullName; + +@end + +@interface Group : NSObject +{ +} + +@property Person *techLead, *runtimeGuru, *propertiesMaven; + +@end + +@implementation Group + +@property Person *techLead, *runtimeGuru, *propertiesMaven; +- init { + techLead = [[Person alloc] init]; + runtimeGuru = [[Person alloc] init]; + propertiesMaven = [[Person alloc] init]; + return self; +} + +@end + +@implementation Person + +@property NSString *firstName, *lastName; +@property(readonly, getter = fullName) NSString *fullName; + +- (NSString*)fullName { // computed getter + return [NSString stringWithFormat:@"%@ %@", firstName, lastName]; +} + +@end + +NSString *playWithProperties() +{ + Group *g = [[Group alloc] init] ; + + g.techLead.firstName = @"Blaine"; + g.techLead.lastName = @"Garst"; + g.runtimeGuru.firstName = @"Greg"; + g.runtimeGuru.lastName = @"Parker"; + g.propertiesMaven.firstName = @"Patrick"; + g.propertiesMaven.lastName = @"Beard"; + + return [NSString stringWithFormat:@"techlead %@ runtimeGuru %@ propertiesMaven %@", + g.techLead.fullName, g.runtimeGuru.fullName, g.propertiesMaven.fullName]; +} + +main() +{ + char buf [256]; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + sprintf(buf, "%s", [playWithProperties() cString]); + [pool release]; + return strcmp (buf, "techlead Blaine Garst runtimeGuru Greg Parker propertiesMaven Patrick Beard"); +} + diff --git a/gcc/testsuite/objc.dg/property/property-neg-1.m b/gcc/testsuite/objc.dg/property/property-neg-1.m new file mode 100644 index 000000000000..ffb825363e18 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/property-neg-1.m @@ -0,0 +1,14 @@ +/* This program checks for proper use of 'readonly' attribute. */ +/* { dg-do compile } */ + +@interface Bar +{ + int iVar; +} +@property (readonly) int FooBar; +@end + +@implementation Bar +@property int FooBar; /* { dg-error "property 'FooBar' 'readonly' attribute conflicts with its interface version" } */ + +@end diff --git a/gcc/testsuite/objc.dg/property/property-neg-2.m b/gcc/testsuite/objc.dg/property/property-neg-2.m new file mode 100644 index 000000000000..7046da84732a --- /dev/null +++ b/gcc/testsuite/objc.dg/property/property-neg-2.m @@ -0,0 +1,9 @@ +/* This program checks for proper declaration of property. */ +/* { dg-do compile } */ + +@interface Bar +@end + +@implementation Bar +@property int foo; /* { dg-error "no declaration of property 'foo' found in the interface" } */ +@end diff --git a/gcc/testsuite/objc.dg/property/property-neg-3.m b/gcc/testsuite/objc.dg/property/property-neg-3.m new file mode 100644 index 000000000000..5b4804433f14 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/property-neg-3.m @@ -0,0 +1,14 @@ +/* Property name cannot match the ivar name. */ +/* { dg-do compile } */ +/* Suppress warnings for incomplete class definition etc. */ +/* { dg-options "-w" } */ + +@interface Person +{ + char *firstName; +} +@property char *firstName; /* { dg-error "property 'firstName' may not have the same name as an ivar in the class" } */ +@end + +@implementation Person +@end diff --git a/gcc/testsuite/objc.dg/property/property-neg-4.m b/gcc/testsuite/objc.dg/property/property-neg-4.m new file mode 100644 index 000000000000..960c6d633720 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/property-neg-4.m @@ -0,0 +1,17 @@ +/* Property cannot be accessed in class method. */ +/* { dg-do compile } */ + +@interface Person +{ +} +@property char *fullName; ++ (void) testClass; +@end + +@implementation Person +@property char *fullName; ++ (void) testClass { + fullName = "MyName"; /* { dg-error "property 'fullName' accessed in class method" } */ +} +@end + diff --git a/gcc/testsuite/objc.dg/property/property-neg-5.m b/gcc/testsuite/objc.dg/property/property-neg-5.m new file mode 100644 index 000000000000..53fada261987 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/property-neg-5.m @@ -0,0 +1,7 @@ +/* getter/setter cannot be specified in an interface. */ +/* { dg-do compile } */ + +@interface Foo +@property ( readonly, getter = HELLO, setter = THERE : ) int value; +@end /* { dg-warning "getter = \\'HELLO\\' may not be specified in an interface" } */ + /* { dg-warning "setter = \\'THERE\\:\\' may not be specified in an interface" "" { target *-*-* } 6 } */ diff --git a/gcc/testsuite/objc.dg/property/property-neg-6.m b/gcc/testsuite/objc.dg/property/property-neg-6.m new file mode 100644 index 000000000000..335fe1dee3f0 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/property-neg-6.m @@ -0,0 +1,8 @@ +/* Check for proper declaration of @property. */ +/* { dg-do compile } */ + +@interface Bar +{ + int iVar; +} +@property int FooBar /* { dg-error "expected ':', ',', ';', '\}' or '__attribute__' at end of input" } */ diff --git a/gcc/testsuite/objc.dg/property/property-neg-7.m b/gcc/testsuite/objc.dg/property/property-neg-7.m new file mode 100644 index 000000000000..506f097eb2a0 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/property-neg-7.m @@ -0,0 +1,19 @@ +/* Cannot write into a read-only property. */ +/* { dg-do compile } */ +/* Suppress warnings for incomplete class definition etc. */ +/* { dg-options "-w" } */ + +@interface NSArray +@property(readonly) int count; +@end + +@implementation NSArray +@end + +void foo (NSArray *ans[], id pid, id apid[], int i) { + NSArray *test; + test.count = 1; /* { dg-error "readonly property can not be set" } */ + ((NSArray *)pid).count = 1; /* { dg-error "readonly property can not be set" } */ + ((NSArray *)apid[i]).count = 1; /* { dg-error "readonly property can not be set" } */ + ans[i].count = 3; /* { dg-error "readonly property can not be set" } */ +} diff --git a/gcc/testsuite/objc.dg/property/property.exp b/gcc/testsuite/objc.dg/property/property.exp new file mode 100644 index 000000000000..52433a43ee9c --- /dev/null +++ b/gcc/testsuite/objc.dg/property/property.exp @@ -0,0 +1,42 @@ +# GCC Objective-C testsuite that uses the `dg.exp' driver. +# Copyright (C) 1997, 2001, 2007 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# Load support procs. +load_lib objc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS "" +} + +# Initialize `dg'. +dg-init + +# Gather a list of all tests. +set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]] + +# Main loop. +dg-runtest $tests "-fgnu-runtime" $DEFAULT_CFLAGS + +# darwin targets can also run code with the NeXT runtime. +if [istarget "*-*-darwin*" ] { + dg-runtest $tests "-fnext-runtime" $DEFAULT_CFLAGS +} + +# All done. +dg-finish