add ObjC* @property - tests
authorIain Sandoe <iains@gcc.gnu.org>
Thu, 14 Oct 2010 20:11:03 +0000 (20:11 +0000)
committerIain Sandoe <iains@gcc.gnu.org>
Thu, 14 Oct 2010 20:11:03 +0000 (20:11 +0000)
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

29 files changed:
gcc/testsuite/ChangeLog
gcc/testsuite/obj-c++.dg/property/fsf-property-basic.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/fsf-property-method-access.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/fsf-property-named-ivar.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/property-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/property-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/property-3.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/property-neg-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/property-neg-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/property-neg-3.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/property-neg-4.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/property-neg-5.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/property-neg-6.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/property-neg-7.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/property.exp [new file with mode: 0644]
gcc/testsuite/objc.dg/property/fsf-property-basic.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/fsf-property-method-access.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/fsf-property-named-ivar.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/property-1.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/property-2.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/property-3.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/property-neg-1.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/property-neg-2.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/property-neg-3.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/property-neg-4.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/property-neg-5.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/property-neg-6.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/property-neg-7.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/property.exp [new file with mode: 0644]

index 3f98ce9..f722e37 100644 (file)
@@ -1,3 +1,41 @@
+2010-10-14  Iain Sandoe  <iains@gcc.gnu.org>
+
+       * 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 <fjahanian@apple.com>
+       
+       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  <hongjiu.lu@intel.com>
 
        * 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 (file)
index 0000000..502ac0d
--- /dev/null
@@ -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 (file)
index 0000000..4052d16
--- /dev/null
@@ -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 (file)
index 0000000..4b29c92
--- /dev/null
@@ -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 (file)
index 0000000..c9b9c46
--- /dev/null
@@ -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 (file)
index 0000000..5d55b40
--- /dev/null
@@ -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 <objc/objc-api.h>
+#include <Foundation/Foundation.h>
+
+@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 (file)
index 0000000..5a83263
--- /dev/null
@@ -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 <objc/objc-api.h>
+#include <Foundation/Foundation.h>
+
+@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 (file)
index 0000000..2989c3b
--- /dev/null
@@ -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 (file)
index 0000000..7046da8
--- /dev/null
@@ -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 (file)
index 0000000..07438a6
--- /dev/null
@@ -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 (file)
index 0000000..b3dbb60
--- /dev/null
@@ -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 (file)
index 0000000..53fada2
--- /dev/null
@@ -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 (file)
index 0000000..86bb664
--- /dev/null
@@ -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 (file)
index 0000000..506f097
--- /dev/null
@@ -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 (file)
index 0000000..bff972b
--- /dev/null
@@ -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
+# <http://www.gnu.org/licenses/>.
+
+# 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 (file)
index 0000000..13a00a2
--- /dev/null
@@ -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 (file)
index 0000000..fae4969
--- /dev/null
@@ -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 (file)
index 0000000..837d303
--- /dev/null
@@ -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 (file)
index 0000000..89537ca
--- /dev/null
@@ -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 (file)
index 0000000..2a923e0
--- /dev/null
@@ -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 <objc/objc-api.h>
+#include <Foundation/Foundation.h>
+
+@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 (file)
index 0000000..5a83263
--- /dev/null
@@ -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 <objc/objc-api.h>
+#include <Foundation/Foundation.h>
+
+@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 (file)
index 0000000..ffb8253
--- /dev/null
@@ -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 (file)
index 0000000..7046da8
--- /dev/null
@@ -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 (file)
index 0000000..5b48044
--- /dev/null
@@ -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 (file)
index 0000000..960c6d6
--- /dev/null
@@ -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 (file)
index 0000000..53fada2
--- /dev/null
@@ -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 (file)
index 0000000..335fe1d
--- /dev/null
@@ -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 (file)
index 0000000..506f097
--- /dev/null
@@ -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 (file)
index 0000000..52433a4
--- /dev/null
@@ -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
+# <http://www.gnu.org/licenses/>.
+
+# 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