summaryrefslogtreecommitdiff
path: root/gcc/testsuite/objc.dg/property
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/objc.dg/property
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/objc.dg/property')
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-1.m21
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-10.m100
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-11.m47
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-12.m47
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-13.m72
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-14.m20
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-15.m20
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-16.m55
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-17.m98
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-18.m47
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-19.m74
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-2.m13
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-20.m81
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-21.m23
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-22.m172
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-23.m17
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-24.m118
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-25.m87
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-26.m85
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-27.m66
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-28.m29
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-29.m14
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-3.m15
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-4.m40
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-5.m34
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-6.m61
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-7.m58
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-8.m58
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-9.m53
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-deprecated-1.m37
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-deprecated-2.m25
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-1.m63
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-10.m86
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-11.m61
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-12.m105
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-13.m53
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-14.m77
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-15.m80
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-16.m91
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-17.m67
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-18.m90
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-19.m113
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-2.m72
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-20.m67
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-21.m113
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-22.m19
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-3.m64
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-4.m42
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-5.m78
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-6.m106
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-7.m48
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-8.m62
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-9.m77
-rw-r--r--gcc/testsuite/objc.dg/property/dotsyntax-deprecated-1.m41
-rw-r--r--gcc/testsuite/objc.dg/property/dynamic-1.m34
-rw-r--r--gcc/testsuite/objc.dg/property/dynamic-2.m45
-rw-r--r--gcc/testsuite/objc.dg/property/dynamic-3.m49
-rw-r--r--gcc/testsuite/objc.dg/property/dynamic-4.m45
-rw-r--r--gcc/testsuite/objc.dg/property/dynamic-5.m53
-rw-r--r--gcc/testsuite/objc.dg/property/dynamic-6.m26
-rw-r--r--gcc/testsuite/objc.dg/property/fsf-property-basic.m62
-rw-r--r--gcc/testsuite/objc.dg/property/fsf-property-method-access.m67
-rw-r--r--gcc/testsuite/objc.dg/property/fsf-property-named-ivar.m61
-rw-r--r--gcc/testsuite/objc.dg/property/property-1.m32
-rw-r--r--gcc/testsuite/objc.dg/property/property-encoding-1.m182
-rw-r--r--gcc/testsuite/objc.dg/property/property-neg-1.m13
-rw-r--r--gcc/testsuite/objc.dg/property/property-neg-2.m8
-rw-r--r--gcc/testsuite/objc.dg/property/property-neg-3.m14
-rw-r--r--gcc/testsuite/objc.dg/property/property-neg-4.m17
-rw-r--r--gcc/testsuite/objc.dg/property/property-neg-5.m5
-rw-r--r--gcc/testsuite/objc.dg/property/property-neg-6.m9
-rw-r--r--gcc/testsuite/objc.dg/property/property-neg-7.m20
-rw-r--r--gcc/testsuite/objc.dg/property/property.exp43
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-1.m53
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-10.m53
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-11.m31
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-2.m51
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-3.m66
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-4.m67
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-5.m18
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-6.m32
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-7.m86
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-8.m80
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-9.m80
84 files changed, 4764 insertions, 0 deletions
diff --git a/gcc/testsuite/objc.dg/property/at-property-1.m b/gcc/testsuite/objc.dg/property/at-property-1.m
new file mode 100644
index 000000000..4ff269d0f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-1.m
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@property; /* { dg-error "expected" } */
+@property int; /* { dg-error "expected identifier" } */
+ /* { dg-warning "declaration does not declare anything" "" { target *-*-* } 10 } */
+@property int a;
+@property int b, c;
+@property () int d; /* { dg-error "expected identifier" } */
+@property (readonly) int e;
+@property (readonly,) int f; /* { dg-error "expected identifier" } */
+@property (xxx) int g; /* { dg-error "unknown property attribute" } */
+@property (readonly,xxx) int h; /* { dg-error "unknown property attribute" } */
+@property ( int i; /* { dg-error "unknown property attribute" } */
+/* Because the last syntax error opens a '(' and never closes it, we get to the end of input. */
+@end /* { dg-error "expected ..end. at end of input" } */
diff --git a/gcc/testsuite/objc.dg/property/at-property-10.m b/gcc/testsuite/objc.dg/property/at-property-10.m
new file mode 100644
index 000000000..79d2ecdbb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-10.m
@@ -0,0 +1,100 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test the property syntax in a number of expressions. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
+/* Use the simplest synthesized accessor (assign, nonatomic) as we are
+ not testing the synthesized accessors in this test, just the
+ property syntax. */
+@property (nonatomic) int a;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize a;
+@end
+
+int
+test (int g)
+{
+ return g;
+}
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+ MyRootClass *object2 = [[MyRootClass alloc] init];
+
+ object.a = 14;
+ object.a = object.a + object.a;
+
+ if (object.a != 28)
+ abort ();
+
+ object.a = 99;
+ object.a++;
+
+ if (object.a != 100)
+ abort ();
+
+ object.a = 99;
+ object.a *= 2;
+
+ if (object.a != 198)
+ abort ();
+
+ {
+ int f = object.a;
+
+ if (f != 198)
+ abort ();
+
+ if (f != object.a)
+ abort ();
+
+ if (object.a != f)
+ abort ();
+
+ object.a = object.a;
+
+ if (object.a != 198)
+ abort ();
+ }
+
+ if (test (object.a) != 198)
+ abort ();
+
+ object.a = -object.a;
+
+ if (object.a != -198)
+ abort ();
+
+ for (object.a = 0; object.a < 99; object.a++)
+ object2.a = object.a;
+
+ if (object2.a != object.a - 1)
+ abort ();
+
+ if (object2.a != 98)
+ abort ();
+
+ if (object.a != 99)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-11.m b/gcc/testsuite/objc.dg/property/at-property-11.m
new file mode 100644
index 000000000..33baee9d6
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-11.m
@@ -0,0 +1,47 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test that properties are found even if implemented in superclasses. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
+/* Use the simplest synthesized accessor (assign, nonatomic) as we are
+ not testing the synthesized accessors in this test, just the
+ property syntax. */
+@property (nonatomic) int a;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize a;
+@end
+
+@interface MySubClass : MyRootClass
+@end
+
+@implementation MySubClass
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ object.a = 40;
+ if (object.a != 40)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-12.m b/gcc/testsuite/objc.dg/property/at-property-12.m
new file mode 100644
index 000000000..e36f57aaa
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-12.m
@@ -0,0 +1,47 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test atomic, assign synthesized methods. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+ id b;
+}
+@property int a;
+@property (assign) id b;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize a;
+@synthesize b;
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.a = 40;
+ if (object.a != 40)
+ abort ();
+
+ object.b = object;
+ if (object.b != object)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/at-property-13.m b/gcc/testsuite/objc.dg/property/at-property-13.m
new file mode 100644
index 000000000..89bf748a2
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-13.m
@@ -0,0 +1,72 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test retain and copy synthesized methods. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int copy_count;
+ id a;
+ id b;
+}
+@property (copy) id a;
+@property (retain) id b;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (id) copyWithZone: (void *)zone;
+- (int) copyCount;
+- (id) autorelease;
+- (oneway void) release;
+- (id) retain;
+@end
+
+/* This class implements copyWithZone, which doesn't do anything other
+ than increasing a counter of how many copies were made. */
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (id) copyWithZone: (void *)zone { copy_count++; return self; }
+- (int) copyCount { return copy_count; }
+- (id) autorelease { return self; }
+- (oneway void) release { return; }
+- (id) retain { return self; }
+@synthesize a;
+@synthesize b;
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+ MyRootClass *argument = [[MyRootClass alloc] init];
+
+ /* This should copy argument. */
+ object.a = argument;
+ if (object.a != argument)
+ abort ();
+
+ /* Test that it was copied. */
+ if ([object.a copyCount] != 1)
+ abort ();
+
+ /* We just test that the retain accessors seem to work and that they
+ don't copy. We don't test that retain was actually called,
+ because if garbage collection is enabled, it may never be
+ called! */
+ object.b = argument;
+ if (object.b != argument)
+ abort ();
+
+ /* Test that it was not copied. */
+ if ([object.b copyCount] != 1)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-14.m b/gcc/testsuite/objc.dg/property/at-property-14.m
new file mode 100644
index 000000000..ccf842b7f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-14.m
@@ -0,0 +1,20 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+
+/* Test the warnings on 'assign'. */
+@property id property_a; /* { dg-warning "object property .property.a. has no .assign., .retain. or .copy. attribute" } */
+ /* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 12 } */
+
+@property (readonly) id property_b; /* No 'assign' warning (assign semantics do not matter if the property is readonly). */
+@property id *property_c; /* No 'assign' warning (the type is not an Objective-C object). */
+@property Class property_d; /* No 'assign' warning (Classes are static objects so assign semantics do not matter for them). */
+@property MyRootClass *property_e; /* { dg-warning "object property .property.e. has no .assign., .retain. or .copy. attribute" } */
+ /* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 18 } */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-15.m b/gcc/testsuite/objc.dg/property/at-property-15.m
new file mode 100644
index 000000000..ef5344246
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-15.m
@@ -0,0 +1,20 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+/* { dg-options "-Wno-property-assign-default" } */
+
+#include <objc/objc.h>
+
+/* Test that -Wno-property-assign-default turns off all "object
+ property xxx has no assign, return or copy attribute" warnings. */
+
+@interface MyRootClass
+{
+ Class isa;
+}
+
+@property id property_a; /* Would normally generate a warning. */
+@property (readonly) id property_b;
+@property id *property_c;
+@property Class property_d;
+@property MyRootClass *property_e; /* Would normally generate a warning. */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-16.m b/gcc/testsuite/objc.dg/property/at-property-16.m
new file mode 100644
index 000000000..95f82e41b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-16.m
@@ -0,0 +1,55 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test that if you have a property declared in a class and a
+ sub-class, the attributes match. */
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@property (assign) id a;
+@property (retain) id b;
+@property int c;
+@property (nonatomic) int d;
+@property int e;
+@property int f;
+@property int g;
+@property (readonly) int h;
+@property (readonly,getter=getMe) int i;
+@end
+
+@interface MyClass : MyRootClass
+@property (assign) id a;
+@property (retain) id b;
+@property int c;
+@property (nonatomic) int d;
+@property int e;
+@property int f;
+@property int g;
+@property (readonly) int h;
+@property (readonly,getter=getMe) int i;
+@end
+
+@interface MyClass2 : MyRootClass
+@property (retain) id a; /* { dg-warning "assign semantics attributes of property .a. conflict with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 13 } */
+@property (assign) id b; /* { dg-warning "assign semantics attributes of property .b. conflict with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 14 } */
+@property (nonatomic) int c; /* { dg-warning ".nonatomic. attribute of property .c. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 15 } */
+@property int d; /* { dg-warning ".nonatomic. attribute of property .d. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 16 } */
+@property (setter=setX:) int e; /* { dg-warning ".setter. attribute of property .e. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 17 } */
+@property (getter=x) int f; /* { dg-warning ".getter. attribute of property .f. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 18 } */
+@property (readonly) int g; /* { dg-warning ".readonly. attribute of property .g. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 19 } */
+@property (readwrite) int h; /* Ok */
+@property (readonly) int i; /* { dg-warning ".getter. attribute of property .i. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 21 } */
+@end
+
diff --git a/gcc/testsuite/objc.dg/property/at-property-17.m b/gcc/testsuite/objc.dg/property/at-property-17.m
new file mode 100644
index 000000000..efb62d6f7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-17.m
@@ -0,0 +1,98 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test that if you have a property declared in a class, with
+ getters/setters in the superclass, there are no warnings. */
+
+@interface MyRootClass
+{
+ Class isa;
+ int myCount;
+ int myCount2;
+ int myCount3;
+}
+- (int)count;
+- (void)setCount: (int)number;
+- (int)count2;
+- (void)setCount2: (int)number;
+- (int)count3;
+@end
+
+@implementation MyRootClass
+- (int) count
+{
+ return myCount;
+}
+- (void) setCount: (int)number
+{
+ myCount = number;
+}
+- (int) count2
+{
+ return myCount2;
+}
+- (void) setCount2: (int)number
+{
+ myCount2 = number;
+}
+- (int) count3
+{
+ return myCount3;
+}
+@end
+
+
+
+/* Try with a subclass. */
+@interface MyClass : MyRootClass
+@property int count;
+@end
+
+@implementation MyClass
+@end /* No warnings. */
+
+
+
+/* Try with a category. */
+@interface MyRootClass (count)
+@property int count;
+@end
+
+@implementation MyRootClass (count)
+@end /* No warnings. */
+
+
+
+/* Try with a category of a subclass. */
+@interface MyClass2 : MyClass
+@end
+
+@implementation MyClass2
+@end
+
+@interface MyClass2 (count2)
+@property int count2;
+@end
+
+@implementation MyClass2 (count2)
+@end /* No warnings. */
+
+
+
+/* Now, try with a category of a subclass, but with a missing setter,
+ which should generate a warning. */
+@interface MyClass3 : MyClass
+@end
+
+@implementation MyClass3
+@end
+
+@interface MyClass3 (count3)
+@property int count3;
+@end
+
+@implementation MyClass3 (count3)
+@end /* { dg-warning "incomplete implementation" } */
+/* { dg-warning "method definition for .-setCount3:. not found" "" { target *-*-* } 97 } */
diff --git a/gcc/testsuite/objc.dg/property/at-property-18.m b/gcc/testsuite/objc.dg/property/at-property-18.m
new file mode 100644
index 000000000..e6ffb39cb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-18.m
@@ -0,0 +1,47 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test that if you have a property declared in a class and a
+ category, the attributes match. This is almost the same as
+ at-property-16.m, but for a category. It is a separate file
+ because it is difficult to test multiple messages for the same
+ line. */
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@property (assign) id a;
+@property (retain) id b;
+@property int c;
+@property (nonatomic) int d;
+@property int e;
+@property int f;
+@property int g;
+@property (readonly) int h;
+@property (readonly,getter=getMe) int i;
+@property (nonatomic) float j;
+@end
+
+@interface MyRootClass (Category)
+@property (retain) id a; /* { dg-warning "assign semantics attributes of property .a. conflict with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 16 } */
+@property (assign) id b; /* { dg-warning "assign semantics attributes of property .b. conflict with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 17 } */
+@property (nonatomic) int c; /* { dg-warning ".nonatomic. attribute of property .c. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 18 } */
+@property int d; /* { dg-warning ".nonatomic. attribute of property .d. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 19 } */
+@property (setter=setX:) int e; /* { dg-warning ".setter. attribute of property .e. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 20 } */
+@property (getter=x) int f; /* { dg-warning ".getter. attribute of property .f. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 21 } */
+@property (readonly) int g; /* { dg-warning ".readonly. attribute of property .g. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 22 } */
+@property (readwrite) int h; /* Ok */
+@property (readonly) int i; /* { dg-warning ".getter. attribute of property .i. conflicts with previous declaration" } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 24 } */
+@property (nonatomic) float j; /* Ok */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-19.m b/gcc/testsuite/objc.dg/property/at-property-19.m
new file mode 100644
index 000000000..be898e218
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-19.m
@@ -0,0 +1,74 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test looking up a @property in a protocol of a category of a superclass. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@end
+
+/* Use a different getter/setter, so that the only way to compile
+ object.count is to find the actual @property. */
+@protocol count
+@property (getter=number, setter=setNumber:) int count;
+@end
+
+@interface MySubClass : MyRootClass
+- (int) testMe;
+@end
+
+@interface MySubClass (Category) <count>
+@end
+
+@implementation MySubClass (Category)
+- (int) number
+{
+ return a;
+}
+- (void) setNumber: (int)count
+{
+ a = count;
+}
+@end
+
+@implementation MySubClass
+- (int) testMe
+{
+ self.count = 400;
+ if (self.count != 400)
+ abort ();
+
+ return self.count;
+}
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ object.count = 44;
+ if (object.count != 44)
+ abort ();
+
+ if ([object testMe] != 400)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-2.m b/gcc/testsuite/objc.dg/property/at-property-2.m
new file mode 100644
index 000000000..19d59fdaa
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-2.m
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@property int name __attribute__((deprecated));
+@property int table __attribute__((xxx)); /* { dg-warning ".xxx. attribute directive ignored" } */
+@property void function (void); /* { dg-error "declared as a function" } */
+@property typedef int j; /* { dg-error "expected" } */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-20.m b/gcc/testsuite/objc.dg/property/at-property-20.m
new file mode 100644
index 000000000..1bb49da2b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-20.m
@@ -0,0 +1,81 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+/* Test that if you have a property declared in a class and a
+ sub-class, the types match (unless it's a readonly property, in
+ which case a "specialization" is enough). */
+
+@protocol MyProtocolA
+- (void) doNothingA;
+@end
+
+@protocol MyProtocolB
+- (void) doNothingB;
+@end
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@end
+
+@interface MySubClass1 : MyRootClass
+@end
+
+@interface MySubClass2 : MyRootClass
+@end
+
+@interface MySubClass3 : MyRootClass <MyProtocolA>
+@end
+
+@interface MySubClass4 : MySubClass1
+@end
+
+/* Now, the test. */
+
+@interface MyClass : MyRootClass
+{ }
+@property (assign) id <MyProtocolA> a; /* { dg-message "originally specified here" } */
+@property int b; /* { dg-message "originally specified here" } */
+@property float c; /* { dg-message "originally specified here" } */
+@property (assign) MyRootClass *d; /* { dg-message "originally specified here" } */
+@property (assign) MySubClass1 *e; /* { dg-message "originally specified here" } */
+@property (assign, readonly) MySubClass1 *f; /* { dg-message "originally specified here" } */
+@property (assign) MySubClass3 *g; /* { dg-message "originally specified here" } */
+@property (assign, readonly) MySubClass3 *h; /* { dg-message "originally specified here" } */
+@end
+
+/* The following are all OK because they are identical. */
+@interface MyClass2 : MyClass
+{ }
+@property (assign) id a;
+@property int b;
+@property float c;
+@property (assign) MyRootClass *d;
+@property (assign) MySubClass1 *e;
+@property (assign, readonly) MySubClass1 *f;
+@property (assign) MySubClass3 *g;
+@property (assign, readonly) MySubClass3 *h;
+@end
+
+/* The following are not OK. */
+@interface MyClass3 : MyClass
+{ }
+@property (assign) MySubClass1 *a; /* { dg-warning "type of property .a. conflicts with previous declaration" } */
+@property float b; /* { dg-warning "type of property .b. conflicts with previous declaration" } */
+@property int c; /* { dg-warning "type of property .c. conflicts with previous declaration" } */
+@property (assign) id d; /* { dg-warning "type of property .d. conflicts with previous declaration" } */
+@property (assign) MyRootClass *e; /* { dg-warning "type of property .e. conflicts with previous declaration" } */
+@property (assign, readonly) MyRootClass *f; /* { dg-warning "type of property .f. conflicts with previous declaration" } */
+@property (assign) MySubClass2 *g; /* { dg-warning "type of property .g. conflicts with previous declaration" } */
+@property (assign, readonly) MySubClass2 *h; /* { dg-warning "type of property .h. conflicts with previous declaration" } */
+@end
+
+/* The following are OK. */
+@interface MyClass4 : MyClass
+{ }
+@property (assign, readonly) MySubClass4 *f;
+@property (assign, readonly) MySubClass3 <MyProtocolB> *h;
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-21.m b/gcc/testsuite/objc.dg/property/at-property-21.m
new file mode 100644
index 000000000..d1f54b1cd
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-21.m
@@ -0,0 +1,23 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void) message;
+@end
+
+@interface MyRootClass
+{
+ Class isa;
+}
+
+/* Test the warnings on 'assign' with protocols. */
+@property id <MyProtocol> property_a; /* { dg-warning "object property .property.a. has no .assign., .retain. or .copy. attribute" } */
+ /* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 16 } */
+
+@property MyRootClass <MyProtocol> *property_b; /* { dg-warning "object property .property.b. has no .assign., .retain. or .copy. attribute" } */
+ /* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 19 } */
+
+@property Class <MyProtocol> property_c; /* No 'assign' warning (Classes are static objects so assign semantics do not matter for them). */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-22.m b/gcc/testsuite/objc.dg/property/at-property-22.m
new file mode 100644
index 000000000..03b3d0bb4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-22.m
@@ -0,0 +1,172 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test properties of different types. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+enum colour { Red, Black };
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
++ (Class) class;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
++ (Class) class { return self; }
+@end
+
+
+@interface MyClass : MyRootClass
+{
+ /* A bunch of C types. */
+ char pchar;
+ short pshort;
+ int pint;
+ long plong;
+ float pfloat;
+ double pdouble;
+ enum colour penum;
+
+ /* A bunch of pointers to C types. */
+ char *pcharp;
+ short *pshortp;
+ int *pintp;
+ long *plongp;
+ float *pfloatp;
+ double *pdoublep;
+ enum colour *penump;
+
+ /* A bunch of Objective-C types. */
+ id pid;
+ Class pclass;
+ MyClass *pMyClassp;
+}
+@property (assign) char pchar;
+@property (assign) short pshort;
+@property (assign) int pint;
+@property (assign) long plong;
+@property (assign) float pfloat;
+@property (assign) double pdouble;
+@property (assign) enum colour penum;
+
+@property (assign) char *pcharp;
+@property (assign) short *pshortp;
+@property (assign) int *pintp;
+@property (assign) long *plongp;
+@property (assign) float *pfloatp;
+@property (assign) double *pdoublep;
+@property (assign) enum colour *penump;
+
+@property (assign) id pid;
+@property (assign) Class pclass;
+@property (assign) MyClass *pMyClassp;
+@end
+
+@implementation MyClass
+@synthesize pchar;
+@synthesize pshort;
+@synthesize pint;
+@synthesize plong;
+@synthesize pfloat;
+@synthesize pdouble;
+@synthesize penum;
+
+@synthesize pcharp;
+@synthesize pshortp;
+@synthesize pintp;
+@synthesize plongp;
+@synthesize pfloatp;
+@synthesize pdoublep;
+@synthesize penump;
+
+@synthesize pid;
+@synthesize pclass;
+@synthesize pMyClassp;
+@end
+
+int main (void)
+{
+ MyClass *object = [[MyClass alloc] init];
+
+ object.pchar = 1;
+ if (object.pchar != 1)
+ abort ();
+
+ object.pshort = 2;
+ if (object.pshort != 2)
+ abort ();
+
+ object.pint = 3;
+ if (object.pint != 3)
+ abort ();
+
+ object.plong = 4;
+ if (object.plong != 4)
+ abort ();
+
+ object.pfloat = 0;
+ if (object.pfloat != 0)
+ abort ();
+
+ object.pdouble = 0;
+ if (object.pdouble != 0)
+ abort ();
+
+ object.penum = Black;
+ if (object.penum != Black)
+ abort ();
+
+ object.pcharp = (char *)0;
+ if (object.pcharp != 0)
+ abort ();
+
+ object.pshortp = (short *)0;
+ if (object.pshortp != 0)
+ abort ();
+
+ object.pintp = (int *)0;
+ if (object.pintp != 0)
+ abort ();
+
+ object.plongp = (long *)0;
+ if (object.plongp != 0)
+ abort ();
+
+ object.pfloatp = (float *)0;
+ if (object.pfloatp != 0)
+ abort ();
+
+ object.pdoublep = (double *)0;
+ if (object.pdoublep != 0)
+ abort ();
+
+ object.penump = (enum colour *)0;
+ if (object.penump != 0)
+ abort ();
+
+ object.pid = object;
+ if (object.pid != object)
+ abort ();
+
+ object.pclass = [MyClass class];
+ if (object.pclass != [MyClass class])
+ abort ();
+
+ object.pMyClassp = object;
+ if (object.pMyClassp != object)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-23.m b/gcc/testsuite/objc.dg/property/at-property-23.m
new file mode 100644
index 000000000..c1fd29df4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-23.m
@@ -0,0 +1,17 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test that properties of type arrays or bitfields are rejected. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@property int a[8]; /* { dg-error "property can not be an array" } */
+@property int b:8; /* { dg-error "property can not be a bit-field" } */
+@property int c[]; /* { dg-error "property can not be an array" } */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-24.m b/gcc/testsuite/objc.dg/property/at-property-24.m
new file mode 100644
index 000000000..b4a7699f6
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-24.m
@@ -0,0 +1,118 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test @optional @properties. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@end
+
+/* Use a different getters/setters, so that the only way to compile
+ object.countX is to find the actual @property. */
+@protocol count
+@required
+/* @required + @synthesize. */
+@property (getter=number1, setter=setNumber1:) int count1;
+/* @required + manual setters/getters. */
+@property (getter=number2, setter=setNumber2:) int count2;
+
+@optional
+/* @optional + @synthesize. */
+@property (getter=number3, setter=setNumber3:) int count3;
+/* @optional + manual setters/getters. */
+@property (getter=number4, setter=setNumber4:) int count4;
+
+@optional
+/* @optional + readonly, with a setter added in the class itself. */
+@property (readonly, getter=number5) int count5;
+@end
+
+@interface MySubClass : MyRootClass <count>
+{
+ int count1;
+ int count2;
+ int count3;
+ int count4;
+ int count5;
+}
+- (void) setCount5: (int)value;
+@end
+
+@implementation MySubClass
+@synthesize count1;
+- (int) number2
+{
+ return count2;
+}
+- (void) setNumber2: (int)value
+{
+ count2 = value;
+}
+@synthesize count3;
+- (int) number4
+{
+ return count4;
+}
+- (void) setNumber4: (int)value
+{
+ count4 = value;
+}
+- (int) number5
+{
+ return count5;
+}
+- (void) setCount5: (int)value
+{
+ count5 = value;
+}
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ /* First, test that @required and @optional properties work as
+ expected if implemented either via @synthesize or manually. */
+ object.count1 = 44;
+ if (object.count1 != 44)
+ abort ();
+
+ object.count2 = 88;
+ if (object.count2 != 88)
+ abort ();
+
+ object.count3 = 77;
+ if (object.count3 != 77)
+ abort ();
+
+ object.count4 = 11;
+ if (object.count4 != 11)
+ abort ();
+
+ /* Now, test the complication: @optional @property which is
+ readonly, but which has a setter manually implemented.
+ Apparently it is possible to use the dotsyntax and the @optional
+ @property getter is used when reading, while the manual setter is
+ used when writing. */
+ object.count5 = 99;
+ if (object.count5 != 99)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-25.m b/gcc/testsuite/objc.dg/property/at-property-25.m
new file mode 100644
index 000000000..422a29e55
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-25.m
@@ -0,0 +1,87 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test warnings and non-warnings with @optional @properties. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@end
+
+@protocol count
+@optional
+@property int count1;
+@property (readonly) int count2;
+@end
+
+
+/* A class that implements all the properties. */
+@interface MySubClass1 : MyRootClass <count>
+{
+ int count1;
+ int count2;
+}
+@end
+
+@implementation MySubClass1
+@synthesize count1;
+@synthesize count2;
+@end
+
+
+/* A class that implements nothing; no warnings as the properties are
+ all optional. */
+@interface MySubClass2 : MyRootClass <count>
+@end
+
+@implementation MySubClass2
+@end
+
+
+@protocol count2
+@required
+@property int count1;
+@property (readonly) int count2;
+@end
+
+/* A class that implements all the properties. */
+@interface MySubClass3 : MyRootClass <count2>
+{
+ int count1;
+ int count2;
+}
+@end
+
+@implementation MySubClass3
+@synthesize count1;
+@synthesize count2;
+@end
+
+
+/* A class that implements nothing; warnings as the properties are
+ all required. */
+@interface MySubClass4 : MyRootClass <count2>
+@end
+
+@implementation MySubClass4
+@end
+
+/* { dg-warning "incomplete implementation of class" "" { target *-*-* } 81 } */
+/* { dg-warning "method definition for ..setCount1:. not found" "" { target *-*-* } 81 } */
+/* { dg-warning "method definition for ..count1. not found" "" { target *-*-* } 81 } */
+/* { dg-warning "method definition for ..count2. not found" "" { target *-*-* } 81 } */
+/* { dg-warning "class .MySubClass4. does not fully implement the .count2. protocol" "" { target *-*-* } 81 } */
diff --git a/gcc/testsuite/objc.dg/property/at-property-26.m b/gcc/testsuite/objc.dg/property/at-property-26.m
new file mode 100644
index 000000000..c45757e23
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-26.m
@@ -0,0 +1,85 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test @properties in class extensions. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@end
+
+@protocol count4
+/* Use a different getters/setters, so that the only way to compile
+ object.countX is to find the actual @property. */
+@property (getter=number4, setter=setNumber4:) int count4;
+@end
+
+@interface MySubClass : MyRootClass
+{
+ int count1;
+ int count2;
+ int count3;
+ int count4;
+}
+@property (getter=number1, setter=setNumber1:) int count1;
+@end
+
+@interface MySubClass ()
+@property (getter=number2, setter=setNumber2:) int count2;
+@end
+
+@interface MySubClass () <count4>
+@property (getter=number3, setter=setNumber3:) int count3;
+@end
+
+@implementation MySubClass
+@synthesize count1;
+@synthesize count2;
+- (int) number3
+{
+ return count3;
+}
+- (void) setNumber3: (int)value
+{
+ count3 = value;
+}
+@synthesize count4;
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ object.count1 = 20;
+ if (object.count1 != 20)
+ abort ();
+
+ object.count2 = 11;
+ if (object.count2 != 11)
+ abort ();
+
+ object.count3 = 19;
+ if (object.count3 != 19)
+ abort ();
+
+ object.count4 = 74;
+ if (object.count4 != 74)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-27.m b/gcc/testsuite/objc.dg/property/at-property-27.m
new file mode 100644
index 000000000..727834684
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-27.m
@@ -0,0 +1,66 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test overriding a readonly @property with a readwrite one in a class extension. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@end
+
+@protocol count2
+/* Use a different getters/setters, so that the only way to compile
+ object.countX is to find the actual @property. */
+@property (readonly, getter=number2) int count2;
+@end
+
+@interface MySubClass : MyRootClass
+{
+ int count1;
+ int count2;
+}
+@property (readonly, getter=number1) int count1;
+@end
+
+@interface MySubClass ()
+@property (readwrite, getter=number1, setter=setNumber1:) int count1;
+@end
+
+@interface MySubClass () <count2>
+@property (readwrite, getter=number2, setter=setNumber2:) int count2;
+@end
+
+@implementation MySubClass
+@synthesize count1;
+@synthesize count2;
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ object.count1 = 20;
+ if (object.count1 != 20)
+ abort ();
+
+ object.count2 = 11;
+ if (object.count2 != 11)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-28.m b/gcc/testsuite/objc.dg/property/at-property-28.m
new file mode 100644
index 000000000..de5122443
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-28.m
@@ -0,0 +1,29 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
+/* { dg-do compile } */
+
+/* Test errors when extending a property in a class extension. */
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@property (readonly, retain) id property1; /* { dg-message "originally specified here" } */
+@property (readonly) int property2; /* { dg-message "originally specified here" } */
+@property (readonly, getter=y) int property3; /* { dg-message "originally specified here" } */
+@property (readonly) int property4; /* Ok */
+@property (readonly) int property5; /* { dg-message "originally specified here" } */
+@end
+
+@interface MyRootClass ()
+@property (readwrite, copy) id property1; /* { dg-warning "assign semantics attributes of property .property1. conflict with previous declaration" } */
+@property (readwrite, nonatomic) int property2; /* { dg-warning ".nonatomic. attribute of property .property2. conflicts with previous declaration" } */
+@property (readwrite, getter=x) int property3; /* { dg-warning ".getter. attribute of property .property3. conflicts with previous declaration" } */
+@property (readwrite) int property4; /* Ok */
+@property (readwrite) float property5; /* { dg-warning "type of property .property5. conflicts with previous declaration" } */
+@end
+
+
+
diff --git a/gcc/testsuite/objc.dg/property/at-property-29.m b/gcc/testsuite/objc.dg/property/at-property-29.m
new file mode 100644
index 000000000..0f31617f8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-29.m
@@ -0,0 +1,14 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, January 2011. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+/* Test missing '=' in setter/getter attributes. */
+@property (getter) int property_a; /* { dg-error "missing .=. .after .getter. attribute." } */
+@property (setter) int property_b; /* { dg-error "missing .=. .after .setter. attribute." } */
+@property (assign, getter) int property_c; /* { dg-error "missing .=. .after .getter. attribute." } */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-3.m b/gcc/testsuite/objc.dg/property/at-property-3.m
new file mode 100644
index 000000000..70b522cba
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-3.m
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@property volatile int a; /* This is allowed */
+@property extern int b; /* { dg-error "expected" } */
+@property static int c; /* { dg-error "expected" } */
+@property inline int d; /* { dg-error "expected" } */
+@property typedef int e; /* { dg-error "expected" } */
+@property __thread int f; /* { dg-error "expected" } */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-4.m b/gcc/testsuite/objc.dg/property/at-property-4.m
new file mode 100644
index 000000000..941aab8e3
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-4.m
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+- (int) myGetter;
+- (int) myGetterB;
+- (int) myGetter2;
+- (void) mySetter: (int)property;
+- (void) mySetterB: (int)property;
+- (void) mySetter2: (int)property;
+
+/* Test that all the new property attributes can be parsed. */
+@property (assign) id property_a;
+@property (copy) id property_b;
+@property (nonatomic) int property_c;
+@property (readonly) int property_d;
+@property (readwrite) int property_e;
+@property (retain) id property_f;
+@property (release) int property_g; /* { dg-error "unknown property attribute" } */
+
+@property (getter=myGetter) int property_h;
+@property (setter=mySetter:) int property_i;
+
+/* Now test various problems. */
+
+@property (readonly, readwrite) int a; /* { dg-error ".readonly. attribute conflicts with .readwrite. attribute" } */
+@property (readonly, setter=mySetterB:) int b; /* { dg-error ".readonly. attribute conflicts with .setter. attribute" } */
+
+@property (assign, retain) id c; /* { dg-error ".assign. attribute conflicts with .retain. attribute" } */
+@property (assign, copy) id d; /* { dg-error ".assign. attribute conflicts with .copy. attribute" } */
+@property (copy, retain) id e; /* { dg-error ".retain. attribute conflicts with .copy. attribute" } */
+
+@property (setter=mySetter:,setter=mySetter2:) int f; /* { dg-error ".setter. attribute may only be specified once" } */
+@property (getter=myGetter, getter=myGetter2 ) int g; /* { dg-error ".getter. attribute may only be specified once" } */
+
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-5.m b/gcc/testsuite/objc.dg/property/at-property-5.m
new file mode 100644
index 000000000..bd8949b7f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-5.m
@@ -0,0 +1,34 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ id property_a;
+ int property_b;
+ int property_c;
+ int property_d;
+ id property_e;
+ id property_f;
+ id property_g;
+ id property_h;
+}
+
+/* Test various error messages. */
+@property id property_a; /* { dg-warning "object property .property.a. has no .assign., .retain. or .copy. attribute" } */
+ /* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 20 } */
+@property int property_b = 4; /* { dg-error "expected" } */
+@property (retain) int property_c; /* { dg-error ".retain. attribute is only valid for Objective-C objects" } */
+@property (copy) int property_d; /* { dg-error ".copy. attribute is only valid for Objective-C objects" } */
+
+@property (retain) id property_e;
+@property (retain) id property_f;
+@property (retain) id property_g;
+@property (retain) id property_h;
+@property (retain) id property_e; /* { dg-error "redeclaration of property .property_e." } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 26 } */
+@end
+
+@property id test; /* { dg-error "property declaration not in .interface or .protocol context" } */
diff --git a/gcc/testsuite/objc.dg/property/at-property-6.m b/gcc/testsuite/objc.dg/property/at-property-6.m
new file mode 100644
index 000000000..b3584cc40
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-6.m
@@ -0,0 +1,61 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test the property syntax with non-synthesized setter/getter
+ and with standard names. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
+@property (nonatomic) int a;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+
+- (int) a
+{
+ return a;
+}
+- (void) setA: (int)value
+{
+ a = value;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ if (object.a != 0)
+ abort ();
+
+ object.a = 14;
+
+ if (object.a != 14)
+ abort ();
+
+ object.a = 23;
+
+ if (object.a != 23)
+ abort ();
+
+ object.a = 78;
+
+ if (object.a != 78)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-7.m b/gcc/testsuite/objc.dg/property/at-property-7.m
new file mode 100644
index 000000000..6f5cedaac
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-7.m
@@ -0,0 +1,58 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test the property syntax with non-synthesized setter/getter
+ and with a non-standard name for the getter. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
+@property (getter = getA, nonatomic) int a;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+
+- (int) getA
+{
+ return a;
+}
+- (void) setA: (int)value
+{
+ a = value;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.a = 14;
+
+ if (object.a != 14)
+ abort ();
+
+ object.a = 23;
+
+ if (object.a != 23)
+ abort ();
+
+ object.a = 78;
+
+ if (object.a != 78)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-8.m b/gcc/testsuite/objc.dg/property/at-property-8.m
new file mode 100644
index 000000000..497dedca7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-8.m
@@ -0,0 +1,58 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test the property syntax with non-synthesized setter/getter
+ and with a non-standard name for the setter. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
+@property (setter = writeA:, nonatomic) int a;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+
+- (int) a
+{
+ return a;
+}
+- (void) writeA: (int)value
+{
+ a = value;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.a = 14;
+
+ if (object.a != 14)
+ abort ();
+
+ object.a = 23;
+
+ if (object.a != 23)
+ abort ();
+
+ object.a = 78;
+
+ if (object.a != 78)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-9.m b/gcc/testsuite/objc.dg/property/at-property-9.m
new file mode 100644
index 000000000..0f144fad2
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-9.m
@@ -0,0 +1,53 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test the property syntax with synthesized setter/getter
+ and with a non-standard name for the getter and setter. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
+/* Use the simplest synthesized accessor (assign, nonatomic) as we are
+ not testing the synthesized accessors in this test, just the
+ property syntax. */
+@property (getter = giveMeA, setter = writeA:, nonatomic) int a;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize a;
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.a = 14;
+
+ if (object.a != 14)
+ abort ();
+
+ object.a = 23;
+
+ if (object.a != 23)
+ abort ();
+
+ object.a = 78;
+
+ if (object.a != 78)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-deprecated-1.m b/gcc/testsuite/objc.dg/property/at-property-deprecated-1.m
new file mode 100644
index 000000000..e52047771
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-deprecated-1.m
@@ -0,0 +1,37 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do compile } */
+
+/* Test that properties can be deprecated. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
+@property int a __attribute__((deprecated));
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize a;
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.a = 40; /* { dg-warning "is deprecated" } */
+ if (object.a != 40) /* { dg-warning "is deprecated" } */
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-deprecated-2.m b/gcc/testsuite/objc.dg/property/at-property-deprecated-2.m
new file mode 100644
index 000000000..d2901a55b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/at-property-deprecated-2.m
@@ -0,0 +1,25 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do compile } */
+
+/* Test that deprecation warnings are produced when a setter/getter of
+ a @property is used directly. */
+
+#include <objc/objc.h>
+
+@interface MyClass
+{
+ Class isa;
+ int variable;
+}
+@property (assign, nonatomic) int property __attribute__ ((deprecated));
+@end
+
+void foo (void)
+{
+ MyClass *object = nil;
+
+ if ([object property] > 0) /* { dg-warning "is deprecated" } */
+ {
+ [object setProperty: 43]; /* { dg-warning "is deprecated" } */
+ }
+}
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-1.m b/gcc/testsuite/objc.dg/property/dotsyntax-1.m
new file mode 100644
index 000000000..8922f5f03
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-1.m
@@ -0,0 +1,63 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test the 'dot syntax' without a declarated property. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+ id b;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)value;
+- (id) next;
+- (void) setNext: (id)value;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)value
+{
+ a = value;
+}
+- (id) next
+{
+ return b;
+}
+- (void) setNext: (id)value
+{
+ b = value;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.count = 40;
+ if (object.count != 40)
+ abort ();
+
+ object.next = object;
+ if (object.next != object)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-10.m b/gcc/testsuite/objc.dg/property/dotsyntax-10.m
new file mode 100644
index 000000000..433595f3d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-10.m
@@ -0,0 +1,86 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test dot-syntax with 'super'. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int c;
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)count;
++ (int) classCount;
++ (void) setClassCount: (int)count;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
++ (int) classCount
+{
+ return c;
+}
++ (void) setClassCount: (int)count
+{
+ c = count;
+}
+@end
+
+@interface MySubClass : MyRootClass
++ (int) testMe;
+- (int) testMe;
+@end
+
+@implementation MySubClass
+- (int) testMe
+{
+ super.count = 400;
+ if (super.count != 400)
+ abort ();
+
+ return super.count;
+}
++ (int) testMe
+{
+ super.classCount = 4000;
+ if (super.classCount != 4000)
+ abort ();
+
+ return super.classCount;
+}
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ if ([object testMe] != 400)
+ abort ();
+
+ if ([MySubClass testMe] != 4000)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-11.m b/gcc/testsuite/objc.dg/property/dotsyntax-11.m
new file mode 100644
index 000000000..6c9d924ca
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-11.m
@@ -0,0 +1,61 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test the error reporting for the dot-syntax in the scenario where
+ we have a setter, but not a getter, yet a getter is requested. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int c;
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (void) setCount: (int)count;
++ (void) setClassCount: (int)count;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (void) setCount: (int)count
+{
+ a = count;
+}
++ (void) setClassCount: (int)count
+{
+ c = count;
+}
+@end
+
+@interface MySubClass : MyRootClass
++ (int) testMe;
+- (int) testMe;
+@end
+
+@implementation MySubClass
+- (int) testMe
+{
+ super.count = 400;
+ if (super.count != 400) /* { dg-error "no .count. getter found" } */
+ abort ();
+
+ return super.count; /* { dg-error "no .count. getter found" } */
+}
++ (int) testMe
+{
+ super.classCount = 4000;
+ if (super.classCount != 4000) /* { dg-error "no .classCount. getter found" } */
+ abort ();
+
+ return super.classCount; /* { dg-error "no .classCount. getter found" } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-12.m b/gcc/testsuite/objc.dg/property/dotsyntax-12.m
new file mode 100644
index 000000000..20882f909
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-12.m
@@ -0,0 +1,105 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test looking up a setter or getter which are in a protocol attached
+ to a category of a superclass. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int c;
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@end
+
+@protocol count
+- (int) count;
+- (void) setCount: (int)count;
+@end
+
+@protocol classCount
++ (int) classCount;
++ (void) setClassCount: (int)count;
+@end
+
+@interface MyRootClass (Category) <count, classCount>
+@end
+
+@implementation MyRootClass (Category)
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
++ (int) classCount
+{
+ return c;
+}
++ (void) setClassCount: (int)count
+{
+ c = count;
+}
+@end
+
+@interface MySubClass : MyRootClass
++ (int) testMe;
+- (int) testMe;
+@end
+
+@implementation MySubClass
+- (int) testMe
+{
+ self.count = 400;
+ if (self.count != 400)
+ abort ();
+
+ return self.count;
+}
++ (int) testMe
+{
+ self.classCount = 4000;
+ if (self.classCount != 4000)
+ abort ();
+
+ return self.classCount;
+}
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ object.count = 44;
+ if (object.count != 44)
+ abort ();
+
+ MySubClass.classCount = 40;
+ if (MySubClass.classCount != 40)
+ abort ();
+
+ if ([object testMe] != 400)
+ abort ();
+
+ if ([MySubClass testMe] != 4000)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-13.m b/gcc/testsuite/objc.dg/property/dotsyntax-13.m
new file mode 100644
index 000000000..c5a4b3301
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-13.m
@@ -0,0 +1,53 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test dot-syntax with a local variable. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)count;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+ int i;
+
+ for (i = 0; i < 10; i++)
+ {
+ object.count = i;
+
+ if (object.count != i)
+ abort ();
+ }
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-14.m b/gcc/testsuite/objc.dg/property/dotsyntax-14.m
new file mode 100644
index 000000000..0606ec4a2
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-14.m
@@ -0,0 +1,77 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test dot-syntax with accessors to be looked up in protocol @properties. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@protocol ProtocolA
+@property int countA;
+@end
+
+@protocol ProtocolB
+@property int countB;
+@end
+
+@protocol ProtocolC
+@property int countC;
+@end
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@interface MySubClass <ProtocolA, ProtocolB, ProtocolC>
+@end
+
+int function (MySubClass *object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB;
+
+ return object.countC;
+}
+
+int function2 (MyRootClass <ProtocolA, ProtocolB, ProtocolC> *object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB;
+
+ return object.countC;
+}
+
+int function3 (MyRootClass <ProtocolA, ProtocolB> *object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB; /* { dg-error "request for member .countC. in something not a structure or union" } */
+
+ return object.countC; /* { dg-error "request for member .countC. in something not a structure or union" } */
+}
+
+int function4 (id <ProtocolA, ProtocolB, ProtocolC> object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB;
+
+ return object.countC;
+}
+
+int function5 (id <ProtocolA, ProtocolB> object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB; /* { dg-error "request for member .countC. in something not a structure or union" } */
+
+ return object.countC; /* { dg-error "request for member .countC. in something not a structure or union" } */
+}
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-15.m b/gcc/testsuite/objc.dg/property/dotsyntax-15.m
new file mode 100644
index 000000000..767f6a2b8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-15.m
@@ -0,0 +1,80 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test dot-syntax with accessors to be looked up in protocols. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@protocol ProtocolA
+- (int) countA;
+- (void) setCountA: (int)aNumber;
+@end
+
+@protocol ProtocolB
+- (int) countB;
+- (void) setCountB: (int)aNumber;
+@end
+
+@protocol ProtocolC
+- (int) countC;
+- (void) setCountC: (int)aNumber;
+@end
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@interface MySubClass <ProtocolA, ProtocolB, ProtocolC>
+@end
+
+int function (MySubClass *object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB;
+
+ return object.countC;
+}
+
+int function2 (MyRootClass <ProtocolA, ProtocolB, ProtocolC> *object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB;
+
+ return object.countC;
+}
+
+int function3 (MyRootClass <ProtocolA, ProtocolB> *object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB; /* { dg-error "request for member .countC. in something not a structure or union" } */
+
+ return object.countC; /* { dg-error "request for member .countC. in something not a structure or union" } */
+}
+
+int function4 (id <ProtocolA, ProtocolB, ProtocolC> object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB;
+
+ return object.countC;
+}
+
+int function5 (id <ProtocolA, ProtocolB> object, int x)
+{
+ object.countA = x;
+ object.countB = x;
+ object.countC = object.countB; /* { dg-error "request for member .countC. in something not a structure or union" } */
+
+ return object.countC; /* { dg-error "request for member .countC. in something not a structure or union" } */
+}
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-16.m b/gcc/testsuite/objc.dg/property/dotsyntax-16.m
new file mode 100644
index 000000000..893db69d9
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-16.m
@@ -0,0 +1,91 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test dot-syntax with pre/post increment and decrement. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)count;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.count = 10;
+ if (object.count != 10)
+ abort ();
+
+ /* First, test that they increment/decrement as expected. */
+ object.count++;
+ if (object.count != 11)
+ abort ();
+
+ ++object.count;
+ if (object.count != 12)
+ abort ();
+
+ object.count--;
+ if (object.count != 11)
+ abort ();
+
+ --object.count;
+ if (object.count != 10)
+ abort ();
+
+ /* Now, test that they are pre/post increment/decrement, as
+ expected. */
+ if (object.count++ != 10)
+ abort ();
+
+ if (object.count != 11)
+ abort ();
+
+ if (++object.count != 12)
+ abort ();
+
+ if (object.count != 12)
+ abort ();
+
+ if (object.count-- != 12)
+ abort ();
+
+ if (object.count != 11)
+ abort ();
+
+ if (--object.count != 10)
+ abort ();
+
+ if (object.count != 10)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-17.m b/gcc/testsuite/objc.dg/property/dotsyntax-17.m
new file mode 100644
index 000000000..c28e11f48
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-17.m
@@ -0,0 +1,67 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test errors with the dot-syntax with pre/post increment and decrement. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int count;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@property (assign, readonly) int count;
+- (void) setWriteOnlyCount: (int)value;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize count;
+- (void) setWriteOnlyCount: (int)value
+{
+ a = value;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.count = 10; /* { dg-error "readonly property can not be set" } */
+ if (object.count != 10) /* Ok */
+ abort ();
+
+ /* Test errors when trying to change a readonly property using
+ pre/post increment/decrement operators. */
+ object.count++; /* { dg-error "readonly property can not be set" } */
+
+ ++object.count; /* { dg-error "readonly property can not be set" } */
+
+ object.count--; /* { dg-error "readonly property can not be set" } */
+
+ --object.count; /* { dg-error "readonly property can not be set" } */
+
+ /* Test errors when trying to change something using Objective-C 2.0
+ dot-syntax but there is a setter but no getter. */
+ object.writeOnlyCount = 10; /* Ok */
+
+ object.writeOnlyCount++; /* { dg-error "no .writeOnlyCount. getter found" } */
+
+ ++object.writeOnlyCount; /* { dg-error "no .writeOnlyCount. getter found" } */
+
+ object.writeOnlyCount--; /* { dg-error "no .writeOnlyCount. getter found" } */
+
+ --object.writeOnlyCount; /* { dg-error "no .writeOnlyCount. getter found" } */
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-18.m b/gcc/testsuite/objc.dg/property/dotsyntax-18.m
new file mode 100644
index 000000000..5697d311d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-18.m
@@ -0,0 +1,90 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test dot-syntax with tricky assignments. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)count;
+- (int) somethingToExecuteOnlyOnce;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
+- (int) somethingToExecuteOnlyOnce
+{
+ a++;
+ return 10;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object1 = [[MyRootClass alloc] init];
+ MyRootClass *object2 = [[MyRootClass alloc] init];
+ MyRootClass *object3 = [[MyRootClass alloc] init];
+ int i;
+
+ object1.count = 10;
+ if (object1.count != 10)
+ abort ();
+
+ object2.count = 10;
+ if (object2.count != 10)
+ abort ();
+
+ /* Test multiple assignments to a constant. */
+ object1.count = object2.count = 20;
+
+ if (object1.count != 20 || object2.count != 20)
+ abort ();
+
+ i = object1.count = 30;
+
+ if (i != 30 || object1.count != 30)
+ abort ();
+
+ i = object2.count = 30;
+
+ if (i != 30 || object2.count != 30)
+ abort ();
+
+ /* Test a simple assignment to something with a side-effect; the
+ 'rhs' should be evaluated only once. */
+ object1.count = ([object2 somethingToExecuteOnlyOnce] > 0 ? 30 : 45);
+
+ if (object1.count != 30 || object2.count != 31)
+ abort ();
+
+ /* Test multiple assignments with side effects. */
+ object3.count = object1.count = ([object2 somethingToExecuteOnlyOnce] > 0 ? 30 : 45);
+
+ if (object1.count != 30 || object2.count != 32 || object3.count != 30)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-19.m b/gcc/testsuite/objc.dg/property/dotsyntax-19.m
new file mode 100644
index 000000000..df4867b0a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-19.m
@@ -0,0 +1,113 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test dot-syntax with more tricky assignments. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ id a;
+ id b;
+ int p1;
+ float p2;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+
+@property (assign) id object1;
+@property (assign) id object2;
+- (id) test;
+- (id) myself;
+- (id) nilObject;
+
+@property int p1;
+@property float p2;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize object1 = a;
+@synthesize object2 = b;
+- (id) test
+{
+ /* Test multiple assignments with 'self'. */
+ self.object1 = self.object2 = self;
+
+ if (self.object1 != self || self.object2 != self)
+ abort ();
+
+ /* Test multiple assignments with a conditional and method calls. */
+ self.object1 = self.object2 = (self ? [self myself] : [self nilObject]);
+
+ if (self.object1 != self || self.object2 != self)
+ abort ();
+
+ self.object1 = self.object2 = (self ? [self nilObject] : [self myself]);
+
+ if (self.object1 != nil || self.object2 != nil)
+ abort ();
+
+ return self.object1;
+}
+- (id) myself
+{
+ return self;
+}
+- (id) nilObject
+{
+ return nil;
+}
+
+@synthesize p1;
+@synthesize p2;
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+ MyRootClass *object1 = [[MyRootClass alloc] init];
+
+ [object test];
+
+ /* Now, test multiple assignments with different types. Use
+ int/float as they seem to happily crash the compiler in gimplify
+ if proper conversions are not being generated by the
+ frontend. ;-) */
+ object.p1 = object.p2 = 12;
+
+ if (object.p1 != 12 || object.p2 != 12)
+ abort ();
+
+ object.p1 = object.p2 = 2.7;
+
+ if (object.p1 != 2)
+ abort ();
+
+ /* Just try a different loop, mixing in a few different standard C
+ constructs to cover a few other cases. */
+ object.p1 = 10;
+ object1.p1 = 0;
+ while (object.p1)
+ {
+ object1.p1 += ((object.p2 = 4.56) ? 0 : object.p1);
+ object.p1--;
+ }
+
+ if (object.p1 != 0 || object1.p1 != 0)
+ abort ();
+
+ if ((object.p1 = 0))
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-2.m b/gcc/testsuite/objc.dg/property/dotsyntax-2.m
new file mode 100644
index 000000000..03e49aebc
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-2.m
@@ -0,0 +1,72 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test the 'dot syntax' without a declarated property. This tests the case where
+ only the setter (or only the getter) exists. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+ id b;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) a;
+- (void) setCount: (int)value;
+- (id) b;
+- (void) setNext: (id)value;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) a
+{
+ return a;
+}
+- (void) setCount: (int)value
+{
+ a = value;
+}
+- (id) b
+{
+ return b;
+}
+- (void) setNext: (id)value
+{
+ b = value;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ /* This should work because -setCount: exists (even if -count does
+ not). */
+ object.count = 40;
+
+ /* This should work because -a exists (even if -setA: does not). */
+ if (object.a != 40)
+ abort ();
+
+ /* This should work because -setNext: exists (even if -next does
+ not). */
+ object.next = object;
+
+ /* This should work because -b exists (even if -setB: does not). */
+ if (object.b != object)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-20.m b/gcc/testsuite/objc.dg/property/dotsyntax-20.m
new file mode 100644
index 000000000..f1dd48e61
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-20.m
@@ -0,0 +1,67 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+/* Test warnings with the dot-syntax. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ id a;
+ id b;
+ int p1;
+ int p2;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+
+@property int p1;
+@property int p2;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize p1;
+@synthesize p2;
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ /* First, test that the artificial code generated by dot-syntax does
+ not generate unexpected warnings. */
+
+ /* All of the following should generate no warnings. */
+ object.p1 = 0;
+ object.p2 = 0;
+ object.p1 = object.p2 = 0;
+ if (object.p1 > 0)
+ object.p2 = 0;
+
+ object.p1++;
+ ++object.p1;
+ object.p1--;
+ --object.p1;
+
+ while (object.p1)
+ object.p1--;
+
+ /* Now test some warnings. */
+ object.p1; /* { dg-warning "value computed is not used" } */
+
+ /* TODO: It would be good to get the following to warn. */
+ if (object.p1 = 0) /* dg-warning "suggest parentheses around assignment used as truth value" */
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-21.m b/gcc/testsuite/objc.dg/property/dotsyntax-21.m
new file mode 100644
index 000000000..4b8945ed6
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-21.m
@@ -0,0 +1,113 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test dot-syntax with super in a category. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)count;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
+@end
+
+/* First, test 'super' in the main implementation of a subclass. */
+@interface MySubClass : MyRootClass
+- (int) superCount;
+- (void) setSuperCount: (int)count;
+@end
+
+@implementation MySubClass
+- (int) superCount
+{
+ return super.count;
+}
+- (void) setSuperCount: (int)count
+{
+ super.count = count;
+}
+@end
+
+/* Now, test 'super' in a category of a subclass. */
+@interface MySubClass (Category)
+- (int) superCount2;
+- (void) setSuperCount2: (int)count;
+- (int) test: (int)x;
+@end
+
+@implementation MySubClass (Category)
+- (int) superCount2
+{
+ return super.count;
+}
+- (void) setSuperCount2: (int)count
+{
+ super.count = count;
+}
+- (int) test: (int)x
+{
+ /* For positive x, the following will leave super.count
+ unchanged. */
+ super.count++;
+ --super.count;
+
+ super.count = (x < 0 ? x : super.count);
+
+ if ((x = super.count))
+ super.count += 1;
+
+ if ((x = super.count))
+ super.count -= 1;
+
+ /* Finally, also put a bit of self.count in the mix. */
+ self.count++;
+ super.count--;
+
+ return super.count;
+}
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+
+ object.count = 10;
+ if (object.count != 10)
+ abort ();
+
+ object.superCount = 11;
+ if (object.superCount != 11)
+ abort ();
+
+ object.superCount2 = 12;
+ if (object.superCount2 != 12)
+ abort ();
+
+ if ([object test: 45] != 12)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-22.m b/gcc/testsuite/objc.dg/property/dotsyntax-22.m
new file mode 100644
index 000000000..cc5834822
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-22.m
@@ -0,0 +1,19 @@
+/* PR objc/47784. This testcase used to crash the compiler. */
+
+typedef struct {
+ float x;
+} SomeType;
+
+@interface MyClass
+
+@property(assign,readwrite) SomeType position;
+
+@end
+
+void example (MyClass *x)
+{
+ const SomeType SomeTypeZero = {0.0f};
+
+ x.position= SomeTypeZero;
+}
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-3.m b/gcc/testsuite/objc.dg/property/dotsyntax-3.m
new file mode 100644
index 000000000..d34780628
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-3.m
@@ -0,0 +1,64 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test the 'dot syntax' without a declarated property. This tests the case where
+ the object is a Class. */
+
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int a;
+static id b;
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
++ (int) count;
++ (void) setCount: (int)value;
++ (id) next;
++ (void) setNext: (id)value;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
++ (int) count
+{
+ return a;
+}
++ (void) setCount: (int)value
+{
+ a = value;
+}
++ (id) next
+{
+ return b;
+}
++ (void) setNext: (id)value
+{
+ b = value;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ MyRootClass.count = 40;
+ if (MyRootClass.count != 40)
+ abort ();
+
+ MyRootClass.next = object;
+ if (MyRootClass.next != object)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-4.m b/gcc/testsuite/objc.dg/property/dotsyntax-4.m
new file mode 100644
index 000000000..2db067f1f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-4.m
@@ -0,0 +1,42 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test the 'dot syntax' without a declarated property. This tests
+ syntax errors in the case where the object is a Class. */
+
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@end
+
+int main (void)
+{
+ MyRootClass.invalid = 40; /* { dg-error "could not find setter.getter" } */
+ if (MyRootClass.invalid != 40) /* { dg-error "could not find setter.getter" } */
+ abort ();
+
+ MyRootClass.; /* { dg-error "expected identifier" } */
+ if (MyRootClass.) /* { dg-error "expected identifier" } */
+ abort ();
+
+ MyRootClass.int; /* { dg-error "expected identifier" } */
+ if (MyRootClass.int) /* { dg-error "expected identifier" } */
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-5.m b/gcc/testsuite/objc.dg/property/dotsyntax-5.m
new file mode 100644
index 000000000..06e113032
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-5.m
@@ -0,0 +1,78 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test the 'dot syntax' with self, both in instance and class methods. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int c;
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)count;
++ (int) classCount;
++ (void) setClassCount: (int)count;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
++ (int) classCount
+{
+ return c;
+}
++ (void) setClassCount: (int)count
+{
+ c = count;
+}
+- (int) testMe
+{
+ self.count = 400;
+ if (self.count != 400)
+ abort ();
+
+ return self.count;
+}
++ (int) testMe
+{
+ self.classCount = 4000;
+ if (self.classCount != 4000)
+ abort ();
+
+ return self.classCount;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ if ([object testMe] != 400)
+ abort ();
+
+ if ([MyRootClass testMe] != 4000)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-6.m b/gcc/testsuite/objc.dg/property/dotsyntax-6.m
new file mode 100644
index 000000000..7ecd34e3d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-6.m
@@ -0,0 +1,106 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test nested 'dot syntax' (xxx.yyy.zzz or [xxx yyy].zzz). */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@class MyRootClass;
+
+static MyRootClass *shared_root = nil;
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+ int b;
+ MyRootClass *next;
+}
+@property int b;
+@property (assign) MyRootClass *next;
++ (id) initialize;
++ (MyRootClass *)sharedInstance;
++ (id) alloc;
+- (id) init;
+- (MyRootClass *)same;
+- (int) count;
+- (void) setCount: (int)count;
+@end
+
+@implementation MyRootClass
+@synthesize b;
+@synthesize next;
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
++ (MyRootClass *)sharedInstance
+{
+ if (!shared_root)
+ shared_root = [[self alloc] init];
+
+ return shared_root;
+}
+- (MyRootClass *)same
+{
+ return self;
+}
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ /* Test ClassName.accessor.accessor. */
+ MyRootClass.sharedInstance.count = 500;
+ if (MyRootClass.sharedInstance.count != 500)
+ abort ();
+
+ /* Test object.accessor.accessor. */
+ object.same.count = 1000;
+ if (object.same.count != 1000)
+ abort ();
+
+ /* Test object.accessor.property. */
+ object.same.next = object;
+ if (object.same.next != object)
+ abort ();
+
+ /* Test lots of nesting. */
+ if (object.next.next.same.same.next.next.same != object)
+ abort ();
+
+ /* Test more nesting. */
+ MyRootClass.sharedInstance.next = object;
+ MyRootClass.sharedInstance.next.next.next.next.next.count = 2000;
+ if (MyRootClass.sharedInstance.next.next.next.next.next.count != 2000)
+ abort ();
+
+ /* Test more nesting. */
+ MyRootClass.sharedInstance.same.same.same.same.same.count = 3000;
+ if (MyRootClass.sharedInstance.same.same.same.same.same.count != 3000)
+ abort ();
+
+ /* Test [object method].property. */
+ [MyRootClass sharedInstance].count = 5000;
+ if ([MyRootClass sharedInstance].count != 5000)
+ abort ();
+
+ /* Just a final check. */
+ if (shared_root.count != 5000)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-7.m b/gcc/testsuite/objc.dg/property/dotsyntax-7.m
new file mode 100644
index 000000000..15c1725d8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-7.m
@@ -0,0 +1,48 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test dot syntax of a casted expression. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)count;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
+@end
+
+int main (void)
+{
+ id object = [[MyRootClass alloc] init];
+
+ ((MyRootClass *)object).count = 200;
+ if (((MyRootClass *)object).count != 200)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-8.m b/gcc/testsuite/objc.dg/property/dotsyntax-8.m
new file mode 100644
index 000000000..35dfda40c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-8.m
@@ -0,0 +1,62 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test the 'dot syntax' with typedefs. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int c;
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+- (int) count;
+- (void) setCount: (int)count;
++ (int) classCount;
++ (void) setClassCount: (int)count;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
++ (int) classCount
+{
+ return c;
+}
++ (void) setClassCount: (int)count
+{
+ c = count;
+}
+@end
+
+typedef MyRootClass MyType;
+
+int main (void)
+{
+ MyType *object = [[MyRootClass alloc] init];
+
+ object.count = 1974;
+ if (object.count != 1974)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-9.m b/gcc/testsuite/objc.dg/property/dotsyntax-9.m
new file mode 100644
index 000000000..61a5c0eb8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-9.m
@@ -0,0 +1,77 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test that setter/getters for dot-syntax are properly found even if
+ not declared in the @interface, but available in the local
+ @implementation before the current line (ie, [object name] can be
+ compiled in that case, so object.name should be compiled too). */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int c;
+
+@interface MyRootClass
+{
+ Class isa;
+ int a;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+- (int) count
+{
+ return a;
+}
+- (void) setCount: (int)count
+{
+ a = count;
+}
++ (int) classCount
+{
+ return c;
+}
++ (void) setClassCount: (int)count
+{
+ c = count;
+}
+- (int) testMe
+{
+ self.count = 400;
+ if (self.count != 400)
+ abort ();
+
+ return self.count;
+}
++ (int) testMe
+{
+ self.classCount = 4000;
+ if (self.classCount != 4000)
+ abort ();
+
+ return self.classCount;
+}
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ if ([object testMe] != 400)
+ abort ();
+
+ if ([MyRootClass testMe] != 4000)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-deprecated-1.m b/gcc/testsuite/objc.dg/property/dotsyntax-deprecated-1.m
new file mode 100644
index 000000000..ad627a8c1
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dotsyntax-deprecated-1.m
@@ -0,0 +1,41 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do compile } */
+
+/* Test the 'dot syntax' with deprecated methods. */
+
+#include <objc/objc.h>
+
+@interface MyClass
+{
+ Class isa;
+}
++ (int) classCount __attribute__ ((deprecated));
++ (void) setClassCount: (int)value __attribute__ ((deprecated));
+
+- (int) count __attribute__ ((deprecated));
+- (void) setCount: (int)value __attribute__ ((deprecated));
+
+- (int) classCount2;
+- (void) setClassCount2: (int)value;
+
+- (int) count2;
+- (void) setCount2: (int)value;
+@end
+
+void foo (void)
+{
+ MyClass *object = nil;
+
+
+ if (object.count > 0) /* { dg-warning "is deprecated" } */
+ object.count = 20; /* { dg-warning "is deprecated" } */
+
+ if (MyClass.classCount < -7) /* { dg-warning "is deprecated" } */
+ MyClass.classCount = 11; /* { dg-warning "is deprecated" } */
+
+ if (object.classCount2 > 0)
+ object.classCount2 = 19;
+
+ if (object.count2 < -7)
+ object.count2 = 74;
+}
diff --git a/gcc/testsuite/objc.dg/property/dynamic-1.m b/gcc/testsuite/objc.dg/property/dynamic-1.m
new file mode 100644
index 000000000..8f9737139
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dynamic-1.m
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@end
+
+@implementation MyRootClass
+@end
+
+@dynamic isa; /* { dg-error ".@dynamic. not in @implementation context" } */
+
+@interface Test : MyRootClass
+{
+ int v1;
+ int v2;
+ int v3;
+ int v4;
+}
+@property int v1;
+@property int v2;
+@property int v3;
+@property int v4;
+@end
+
+@implementation Test
+@dynamic; /* { dg-error "expected identifier" } */
+@dynamic v1, ; /* { dg-error "expected identifier" } */
+@dynamic v1, v2, v3;
+@dynamic v4;
+@end
diff --git a/gcc/testsuite/objc.dg/property/dynamic-2.m b/gcc/testsuite/objc.dg/property/dynamic-2.m
new file mode 100644
index 000000000..203ba34a1
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dynamic-2.m
@@ -0,0 +1,45 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@end
+
+@implementation MyRootClass
+@end
+
+@dynamic isa; /* { dg-error ".@dynamic. not in @implementation context" } */
+
+@interface Test : MyRootClass
+{
+ int v1;
+}
+@end
+@implementation Test
+@end
+
+
+@interface Test (Category)
+@property int v1;
+@end
+@implementation Test (Category)
+@dynamic v1;
+@end
+
+
+@interface AnotherTest : MyRootClass
+{
+}
+@property int one;
+@end
+
+@implementation AnotherTest
+@dynamic one;
+@dynamic one; /* { dg-error "property .one. already specified in .@dynamic." } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 41 } */
+@dynamic three; /* { dg-error "no declaration of property .three. found in the interface" } */
+@end
diff --git a/gcc/testsuite/objc.dg/property/dynamic-3.m b/gcc/testsuite/objc.dg/property/dynamic-3.m
new file mode 100644
index 000000000..e8a6693b0
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dynamic-3.m
@@ -0,0 +1,49 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@end
+
+@implementation MyRootClass
+@end
+
+/* Test @property/@dynamic in a category. First, a case where
+ @dynamic should turn off all warnings. */
+
+@interface MyRootClass (Category)
+@property int a;
+- (int) test;
+@end
+@implementation MyRootClass (Category)
+@dynamic a;
+- (int) test
+{
+ return self.a; /* This should compile into [self a] with no warnings. */
+}
+@end
+
+
+
+/* Test @property/@dynamic in a category. Second, a case with a
+ missing setter and no @dynamic. A warning should be generated. */
+
+@interface MyRootClass (Category2)
+@property int b;
+- (int) test;
+@end
+@implementation MyRootClass (Category2)
+- (int) b
+{
+ return 0;
+}
+- (int) test
+{
+ return self.b;
+}
+@end /* { dg-warning "incomplete implementation" } */
+/* { dg-warning "method definition for .-setB:. not found" "" { target *-*-* } 48 } */
diff --git a/gcc/testsuite/objc.dg/property/dynamic-4.m b/gcc/testsuite/objc.dg/property/dynamic-4.m
new file mode 100644
index 000000000..84998d6b4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dynamic-4.m
@@ -0,0 +1,45 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@end
+
+@implementation MyRootClass
+@end
+
+/* Test @property/@dynamic with protocols. */
+
+@protocol MyProtocol
+@property int a;
+@end
+
+
+/* This class is declared to conform to the protocol, but because of
+ @dynamic, no warnings are issued even if the getter/setter for the
+ @property are missing. */
+@interface MyClass1 : MyRootClass <MyProtocol>
+@end
+
+@implementation MyClass1
+@dynamic a;
+@end
+
+
+/* This class is declared to conform to the protocol and warnings are
+ issued because the setter for the @property is missing. */
+@interface MyClass2 : MyRootClass <MyProtocol>
+@end
+
+@implementation MyClass2
+- (int) a
+{
+ return 0;
+}
+@end /* { dg-warning "incomplete implementation" } */
+/* { dg-warning "method definition for .-setA:. not found" "" { target *-*-* } 43 } */
+/* { dg-warning "class .MyClass2. does not fully implement the .MyProtocol. protocol" "" { target *-*-* } 43 } */
diff --git a/gcc/testsuite/objc.dg/property/dynamic-5.m b/gcc/testsuite/objc.dg/property/dynamic-5.m
new file mode 100644
index 000000000..77e81411a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dynamic-5.m
@@ -0,0 +1,53 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test @dynamic in the real scenario where a class declares a
+ @property, uses @dynamic to avoid implementing it, then subclasses
+ implement it. */
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+#include <stdlib.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@property int a;
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@dynamic a;
+@end
+
+@interface Test : MyRootClass
+{
+ int v1;
+}
+@end
+
+@implementation Test
+@synthesize a = v1;
+@end
+
+int main (void)
+{
+ /* Note how 'object' is declared to be of class 'MyRootClass', but
+ actually is of the subclass which implements the property for
+ real. */
+ MyRootClass *object = [[Test alloc] init];
+
+ object.a = 40;
+
+ if (object.a != 40)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/dynamic-6.m b/gcc/testsuite/objc.dg/property/dynamic-6.m
new file mode 100644
index 000000000..23a7a8905
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/dynamic-6.m
@@ -0,0 +1,26 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test case when an accessor from a @property matches a method
+ required by a protocol. If the @property is @dynamic, then no
+ warning should be generated. */
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+#include <stdlib.h>
+
+@protocol Count
+- (int) count;
+@end
+
+@interface MyRootClass <Count>
+{
+ Class isa;
+}
+@property int count;
+@end
+
+@implementation MyRootClass
+/* This @dynamic turns off any warnings for -count and -setCount:. */
+@dynamic count;
+@end
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 000000000..ddc0589e0
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/fsf-property-basic.m
@@ -0,0 +1,62 @@
+/* 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);
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface Bar
+{
+@public
+ Class isa;
+ int FooBar;
+}
++ (id) initialize;
++ (id) alloc ;
+- (id) init;
+- (int) whatIsFooBar;
+@property int FooBar;
+@end
+
+@implementation Bar
+
++initialize { return self;}
++ (id) alloc { return class_createInstance (self, 0); }
+
+- (id) init {return self;}
+
+- (int) whatIsFooBar { return self->FooBar; }
+@synthesize 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 whatIsFooBar] != 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 object.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 000000000..01eea5bf7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/fsf-property-method-access.m
@@ -0,0 +1,67 @@
+/* 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);
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface Bar
+{
+@public
+ Class isa;
+ int FooBar;
+}
++ (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_createInstance(self, 0);}
+
+- (id) init {return self;}
+
+@synthesize 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 000000000..545856850
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/fsf-property-named-ivar.m
@@ -0,0 +1,61 @@
+/* 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);
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface Bar
+{
+@public
+ Class isa;
+ int var;
+}
++ (id) initialize;
++ (id) alloc ;
+- (id) init;
+
+@property int FooBar;
+@end
+
+@implementation Bar
+
++initialize { return self;}
++ (id) alloc { return class_createInstance (self, 0); }
+
+- (id) init {return self;}
+
+@synthesize FooBar = var;
+@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 object.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 000000000..147f007b9
--- /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-additional-sources "../../objc-obj-c++-shared/Object1.m" } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#import "../../objc-obj-c++-shared/Object1.h"
+
+@interface Bar : Object
+{
+ int iVar;
+}
+@property (setter=MySetter:) int FooBar;
+@end
+
+@implementation Bar
+@synthesize FooBar=iVar;
+
+- (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-encoding-1.m b/gcc/testsuite/objc.dg/property/property-encoding-1.m
new file mode 100644
index 000000000..dc12c3137
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-encoding-1.m
@@ -0,0 +1,182 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, March 2011. */
+/* Test encoding properties. */
+/* { dg-do run } */
+/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+
+#include <objc/runtime.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+@interface MyRootClass
+{ Class isa; }
++ alloc;
+- init;
++ initialize;
+@end
+
+@implementation MyRootClass
++ alloc { return class_createInstance (self, 0); }
+- init { return self; }
++ initialize { return self; }
+@end
+
+@interface MySubClass : MyRootClass
+{
+ char char_property;
+ short short_property;
+ int int_property;
+ long long_property;
+ float float_property;
+ double double_property;
+ int *int_pointer_property;
+
+ id propertyA;
+ id propertyB;
+ id propertyC;
+ id propertyD;
+ int propertyE;
+ id propertyF;
+
+ id other_variable;
+}
+@property char char_property;
+@property short short_property;
+@property int int_property;
+@property long long_property;
+@property float float_property;
+@property double double_property;
+@property int *int_pointer_property;
+
+@property (assign, getter=getP, setter=setP:) id propertyA;
+@property (assign) id propertyB;
+@property (copy) id propertyC;
+@property (retain) id propertyD;
+@property (nonatomic) int propertyE;
+@property (nonatomic, readonly, copy) id propertyF;
+
+@property (assign) id propertyG;
+@property (assign, readonly, getter=X) id propertyH;
+@end
+
+@implementation MySubClass
+@synthesize char_property;
+@synthesize short_property;
+@synthesize int_property;
+@synthesize long_property;
+@synthesize float_property;
+@synthesize double_property;
+@synthesize int_pointer_property;
+
+@synthesize propertyA;
+@synthesize propertyB;
+@synthesize propertyC;
+@synthesize propertyD;
+@synthesize propertyE;
+@synthesize propertyF;
+
+@synthesize propertyG = other_variable;
+@dynamic propertyH;
+@end
+
+#ifdef __OBJC2__
+void error (objc_property_t p)
+{
+ printf ("Error - property_getAttributes (\"%s\") returns \"%s\"\n",
+ property_getName (p),
+ property_getAttributes (p));
+ abort ();
+}
+
+/* Concatenate 3 strings and return the result. */
+char *concat (const char *a, const char *b, const char *c)
+{
+ /* We happily leak memory here. This is a test. */
+ char *x = (char *)malloc (sizeof (char) * 128);
+ snprintf (x, 128, "%s%s%s", a, b, c);
+ return x;
+}
+
+#endif
+
+int main (void)
+{
+#ifdef __OBJC2__
+ Class c = objc_getClass ("MySubClass");
+ objc_property_t p;
+
+ p = class_getProperty (c, "char_property");
+ /* Usually we expect "Tc,Vchar_property", but if a char is of
+ different size, it may be encoded differently than "c". */
+ if (strcmp (concat ("T", @encode (char), ",Vchar_property"),
+ property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "short_property");
+ if (strcmp (concat ("T", @encode (short), ",Vshort_property"),
+ property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "int_property");
+ if (strcmp (concat ("T", @encode (int), ",Vint_property"),
+ property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "long_property");
+ if (strcmp (concat ("T", @encode (long), ",Vlong_property"),
+ property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "float_property");
+ if (strcmp (concat ("T", @encode (float), ",Vfloat_property"),
+ property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "double_property");
+ if (strcmp (concat ("T", @encode (double), ",Vdouble_property"),
+ property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "int_pointer_property");
+ if (strcmp (concat ("T", @encode (int *), ",Vint_pointer_property"),
+ property_getAttributes (p)) != 0)
+ error (p);
+
+ /* Objects are always encoded as '@' hence the string does not
+ depend on the architecture. */
+ p = class_getProperty (c, "propertyA");
+ if (strcmp ("T@,GgetP,SsetP:,VpropertyA", property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "propertyB");
+ if (strcmp ("T@,VpropertyB", property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "propertyC");
+ if (strcmp ("T@,C,VpropertyC", property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "propertyD");
+ if (strcmp ("T@,&,VpropertyD", property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "propertyE");
+ if (strcmp (concat ("T", @encode (int), ",N,VpropertyE"),
+ property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "propertyF");
+ if (strcmp ("T@,R,C,N,VpropertyF", property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "propertyG");
+ if (strcmp ("T@,Vother_variable", property_getAttributes (p)) != 0)
+ error (p);
+
+ p = class_getProperty (c, "propertyH");
+ if (strcmp ("T@,R,D,GX", property_getAttributes (p)) != 0)
+ error (p);
+#endif
+
+ return 0;
+}
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 000000000..cae1a5615
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-neg-1.m
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+@interface Bar
+{
+ int iVar;
+}
+@property int fooBar;
+@end
+
+@implementation Bar
+@end /* { dg-warning "incomplete implementation of class .Bar." } */
+ /* { dg-warning "method definition for .-setFooBar:. not found" "" { target *-*-* } 11 } */
+ /* { dg-warning "method definition for .-fooBar. not found" "" { target *-*-* } 11 } */
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 000000000..f730fe846
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-neg-2.m
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+@interface Bar
+@end
+
+@implementation Bar
+@property int FooBar; /* { dg-error "property declaration not in @interface or @protocol context" } */
+@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 000000000..0b30931a8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-neg-3.m
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+@interface Person
+{
+ char *firstName;
+}
+@property char *firstName;
+@end
+
+@implementation Person
+@dynamic firstName;
+@synthesize firstName; /* { dg-error "property .firstName. already specified in .@dynamic." } */
+ /* { dg-message "originally specified here" "" { target *-*-* } 11 } */
+@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 000000000..cc25d84af
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-neg-4.m
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+@interface Person
+{
+ char *fullName;
+}
+@property char *fullName;
++ (void) testClass;
+@end
+
+
+@implementation Person
+@synthesize fullName;
++ (void) testClass {
+ self.fullName = "MyName"; /* { dg-error "request for member .fullName." } */
+}
+@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 000000000..464470cba
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-neg-5.m
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+
+@interface Foo
+@property ( readonly, getter = HELLO, setter = THERE : ) int value; /* { dg-error ".readonly. attribute conflicts with .setter. attribute" } */
+@end
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 000000000..7059a56f0
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-neg-6.m
@@ -0,0 +1,9 @@
+/* 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" } */
+/* { dg-error "expected ..end. at end of input" "" { target *-*-* } 8 } */
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 000000000..4c3d5d7d3
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property-neg-7.m
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+@interface NSArray
+{
+ int count;
+}
+@property(readonly) int count;
+@end
+
+@implementation NSArray
+@synthesize count;
+@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 000000000..e87730188
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/property.exp
@@ -0,0 +1,43 @@
+# GCC Objective-C testsuite that uses the `dg.exp' driver.
+# Copyright (C) 1997, 2001, 2007, 2010 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.
+# but Properties are not supported by the runtime lib before Darwin 9.
+if [istarget "*-*-darwin\[9123\]*" ] {
+ dg-runtest $tests "-fnext-runtime" $DEFAULT_CFLAGS
+}
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/objc.dg/property/synthesize-1.m b/gcc/testsuite/objc.dg/property/synthesize-1.m
new file mode 100644
index 000000000..fbc8e03ee
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-1.m
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
+@end
+
+@implementation MyRootClass
+@end
+
+@synthesize isa; /* { dg-error ".@synthesize. not in @implementation context" } */
+
+@interface Test : MyRootClass
+{
+ int v1;
+ int v2;
+ int v3;
+ int v4;
+ int v5;
+ int v6;
+ int v7;
+ int v8;
+}
+@property int v1;
+@property int v2;
+@property int v3;
+@property int v4;
+@property int v5;
+@property int v6;
+@property int v7;
+@property int v8;
+@end
+
+@implementation Test
+@synthesize; /* { dg-error "expected identifier" } */
+@synthesize v1, ; /* { dg-error "expected identifier" } */
+@synthesize v2, v3 = ; /* { dg-error "expected identifier" } */
+@synthesize v4, v5=v6, v6 = v5,v7;
+@synthesize v8;
+/* Some of the @synthesize above will fail due to syntax errors. The
+ compiler will then complain that the methods implementing the
+ properties are missing. That is correct, but we are not
+ interested. The following ones shut up the compiler. */
+- (int) v1 { return v1; }
+- (void) setV1: (int)a { v1 = a; }
+- (int) v2 { return v2; }
+- (void) setV2: (int)a { v2 = a; }
+- (int) v3 { return v3; }
+- (void) setV3: (int)a { v3 = a; }
+@end
diff --git a/gcc/testsuite/objc.dg/property/synthesize-10.m b/gcc/testsuite/objc.dg/property/synthesize-10.m
new file mode 100644
index 000000000..fc4683187
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-10.m
@@ -0,0 +1,53 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test @synthesize with bitfield instance variables. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int countA : 2;
+ int countB : 3;
+ int countC : 4;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@property (nonatomic) int countA;
+@property (nonatomic) int countB;
+@property (nonatomic) int countC;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize countA;
+@synthesize countB;
+@synthesize countC;
+@end
+
+int main (void)
+{
+ MyRootClass *object = [[MyRootClass alloc] init];
+
+ object.countA = 1;
+ object.countB = 3;
+ object.countC = 4;
+
+ if (object.countA != 1)
+ abort ();
+
+ if (object.countB != 3)
+ abort ();
+
+ if (object.countC != 4)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/synthesize-11.m b/gcc/testsuite/objc.dg/property/synthesize-11.m
new file mode 100644
index 000000000..e49d23424
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-11.m
@@ -0,0 +1,31 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test errors when @synthesize is used with bitfield instance variables in an incorrect way. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+ Class isa;
+ int countA : 2; /* { dg-message "originally specified here" } */
+ int countB : 3; /* { dg-message "originally specified here" } */
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@property int countA;
+@property (nonatomic) short countB;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize countA; /* { dg-error ".atomic. property .countA. is using bit-field instance variable .countA." } */
+@synthesize countB; /* { dg-error "property .countB. is using instance variable .countB. of incompatible type" } */
+@end /* { dg-warning "incomplete implementation of class" } */
+/* { dg-warning "method definition for ..setCountA.. not found" "" { target *-*-* } 29 } */
+/* { dg-warning "method definition for ..countA. not found" "" { target *-*-* } 29 } */
diff --git a/gcc/testsuite/objc.dg/property/synthesize-2.m b/gcc/testsuite/objc.dg/property/synthesize-2.m
new file mode 100644
index 000000000..92170678f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-2.m
@@ -0,0 +1,51 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+#include <stdlib.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@end
+
+@interface Test : MyRootClass
+{
+ int v1;
+}
+@property int v1;
+/* TODO: Test more types of properties with different semantics
+ (retain, copy, atomic, nonatomic, and test various C and
+ Objective-C types). */
+@end
+
+@implementation Test
+@synthesize v1;
+@end
+
+int main (void)
+{
+ Test *object = [[Test alloc] init];
+
+ /* Check that the synthesized methods exist and work. Do not invoke
+ them via property syntax - that is another test. Here we just
+ want to test the synthesis of the methods. */
+ [object setV1: 400];
+
+ if ([object v1] != 400)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/synthesize-3.m b/gcc/testsuite/objc.dg/property/synthesize-3.m
new file mode 100644
index 000000000..866990531
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-3.m
@@ -0,0 +1,66 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test @synthesize for a @property which is not declared directly in
+ the @interface, but in a @protocol that the @interface conforms
+ to. */
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+#include <stdlib.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@end
+
+@protocol MyProtocol
+@property int v1;
+@end
+
+@protocol MyProtocol2
+@property int v2;
+@end
+
+@interface Test : MyRootClass <MyProtocol, MyProtocol2>
+{
+ int v1;
+ int _v2;
+}
+@end
+
+@implementation Test
+@synthesize v1;
+@synthesize v2 = _v2;
+@end
+
+int main (void)
+{
+ Test *object = [[Test alloc] init];
+
+ /* Check that the synthesized methods exist and work. Do not invoke
+ them via property syntax - that is another test. Here we just
+ want to test the synthesis of the methods. */
+ [object setV1: 400];
+
+ if ([object v1] != 400)
+ abort ();
+
+ [object setV2: 31];
+
+ if ([object v2] != 31)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/synthesize-4.m b/gcc/testsuite/objc.dg/property/synthesize-4.m
new file mode 100644
index 000000000..602dc68b4
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-4.m
@@ -0,0 +1,67 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test @synthesize for a @property where the setter/getter are also
+ declared by the user. This is fine. */
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+#include <stdlib.h>
+
+@interface MyRootClass
+{
+ Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@end
+
+@protocol MyProtocol
+@property int v1;
+@end
+
+@protocol MyProtocol2
+@property int v2;
+@end
+
+@interface Test : MyRootClass <MyProtocol, MyProtocol2>
+{
+ int v1;
+ int _v2;
+}
+- (int)v1;
+- (void)setV1: (int)aNumber;
+- (int)v2;
+@end
+
+@implementation Test
+@synthesize v1;
+@synthesize v2 = _v2;
+@end
+
+int main (void)
+{
+ Test *object = [[Test alloc] init];
+
+ /* We use dot-syntax here as this is just a general test that
+ user-declared setters/getters don't cause confusion. */
+ object.v1 = 400;
+
+ if (object.v1 != 400)
+ abort ();
+
+ object.v2 = 31;
+
+ if (object.v2 != 31)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/synthesize-5.m b/gcc/testsuite/objc.dg/property/synthesize-5.m
new file mode 100644
index 000000000..0871b63ee
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-5.m
@@ -0,0 +1,18 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test that @synthesize does not ICE if asked to use a non-existing
+ ivar. */
+
+#include <objc/objc.h>
+
+@interface Test
+@property int v1;
+@end
+
+@implementation Test
+@synthesize v1; /* { dg-error "must be an existing ivar" } */
+@end
+/* { dg-warning "incomplete implementation" "" { target *-*-* } 15 } */
+/* { dg-warning "method definition for .-setV1:. not found" "" { target *-*-* } 15 } */
+/* { dg-warning "method definition for .-v1. not found" "" { target *-*-* } 15 } */
diff --git a/gcc/testsuite/objc.dg/property/synthesize-6.m b/gcc/testsuite/objc.dg/property/synthesize-6.m
new file mode 100644
index 000000000..19f7c9534
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-6.m
@@ -0,0 +1,32 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test that each @synthesize is using a different instance variable,
+ and that it must belong to the class (not to a superclass). */
+
+#include <objc/objc.h>
+
+@interface Test
+{
+ int v;
+ int w;
+}
+@property int v1;
+@property int v2;
+@end
+
+@implementation Test
+@synthesize v1 = v; /* { dg-message "originally specified here" } */
+@synthesize v2 = v; /* { dg-error "property .v2. is using the same instance variable as property .v1." } */
+@end
+
+@interface Test2 : Test
+@property int w1;
+@end
+
+@implementation Test2
+@synthesize w1; /* { dg-error "ivar .w1. used by .@synthesize. declaration must be an existing ivar" } */
+@end
+/* { dg-warning "incomplete implementation" "" { target *-*-* } 29 } */
+/* { dg-warning "method definition for .-setW1:. not found" "" { target *-*-* } 29 } */
+/* { dg-warning "method definition for .-w1. not found" "" { target *-*-* } 29 } */
diff --git a/gcc/testsuite/objc.dg/property/synthesize-7.m b/gcc/testsuite/objc.dg/property/synthesize-7.m
new file mode 100644
index 000000000..929e3803b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-7.m
@@ -0,0 +1,86 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test @synthesize with protocols of protocols. */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@protocol ProtocolA
+@property int countA;
+@end
+
+@protocol ProtocolB <ProtocolA>
+@property int countB;
+@end
+
+@protocol ProtocolC <ProtocolB>
+@property int countC;
+@end
+
+@protocol ProtocolD
+@property int countD;
+@end
+
+@interface MyRootClass <ProtocolC>
+{
+ Class isa;
+ int countA;
+ int countB;
+ int countC;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize countA;
+@synthesize countB;
+@synthesize countC;
+@end
+
+@interface MySubClass : MyRootClass <ProtocolD>
+{
+ int countD;
+}
+@end
+
+@implementation MySubClass
+@synthesize countD;
+@end
+
+int main (void)
+{
+ MySubClass *object = [[MySubClass alloc] init];
+ int i;
+
+ for (i = 0; i < 10; i++)
+ {
+ object.countA += i;
+ object.countB += i + 1;
+ object.countC += i + 2;
+ object.countD += i + 3;
+ }
+
+ if (object.countA != 45)
+ abort ();
+
+ if (object.countB != 55)
+ abort ();
+
+ if (object.countC != 65)
+ abort ();
+
+ if (object.countD != 75)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/objc.dg/property/synthesize-8.m b/gcc/testsuite/objc.dg/property/synthesize-8.m
new file mode 100644
index 000000000..4af3ecc74
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-8.m
@@ -0,0 +1,80 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test that when using @synthesize the instance variable and the
+ property have exactly the same type. */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void)aMethod;
+@end
+
+@interface ClassA
+@end
+
+@interface ClassB : ClassA
+@end
+
+
+/* This is all OK. */
+@interface Test
+{
+ int v;
+ float w;
+ id x;
+ Test *y;
+ id <MyProtocol> *z;
+ ClassA *a;
+ ClassB *b;
+ ClassA <MyProtocol> *c;
+}
+@property (assign) int v;
+@property (assign) float w;
+@property (assign) id x;
+@property (assign) Test *y;
+@property (assign) id <MyProtocol> *z;
+@property (assign) ClassA *a;
+@property (assign) ClassB *b;
+@end
+
+@implementation Test
+@synthesize v;
+@synthesize w;
+@synthesize x;
+@synthesize y;
+@synthesize z;
+@synthesize a;
+@synthesize b;
+@end
+
+
+/* This is not OK. */
+@interface Test2
+{
+ int v; /* { dg-message "originally specified here" } */
+ float w; /* { dg-message "originally specified here" } */
+ id x; /* { dg-message "originally specified here" } */
+ Test *y; /* { dg-message "originally specified here" } */
+ id <MyProtocol> *z; /* { dg-message "originally specified here" } */
+ ClassA *a; /* { dg-message "originally specified here" } */
+ ClassB *b; /* { dg-message "originally specified here" } */
+}
+@property (assign) float v;
+@property (assign) id w;
+@property (assign) int x;
+@property (assign) id y;
+@property (assign) Test *z;
+@property (assign) ClassB *a;
+@property (assign) ClassA *b;
+@end
+
+@implementation Test2
+@synthesize v; /* { dg-error "property .v. is using instance variable .v. of incompatible type" } */
+@synthesize w; /* { dg-error "property .w. is using instance variable .w. of incompatible type" } */
+@synthesize x; /* { dg-error "property .x. is using instance variable .x. of incompatible type" } */
+@synthesize y; /* { dg-error "property .y. is using instance variable .y. of incompatible type" } */
+@synthesize z; /* { dg-error "property .z. is using instance variable .z. of incompatible type" } */
+@synthesize a; /* { dg-error "property .a. is using instance variable .a. of incompatible type" } */
+@synthesize b; /* { dg-error "property .b. is using instance variable .b. of incompatible type" } */
+@end
diff --git a/gcc/testsuite/objc.dg/property/synthesize-9.m b/gcc/testsuite/objc.dg/property/synthesize-9.m
new file mode 100644
index 000000000..7eae31d3f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/synthesize-9.m
@@ -0,0 +1,80 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
+/* { dg-do compile } */
+
+/* Test that when using @synthesize with a readonly property, the
+ instance variable can be a specialization of the property type. */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void)aMethod;
+@end
+
+@interface ClassA
+@end
+
+@interface ClassB : ClassA
+@end
+
+
+/* This is all OK. */
+@interface Test
+{
+ int v;
+ float w;
+ id x;
+ Test *y;
+ id <MyProtocol> *z;
+ ClassA *a;
+ ClassB *b;
+ ClassA <MyProtocol> *c;
+}
+@property (assign, readonly) int v;
+@property (assign, readonly) float w;
+@property (assign, readonly) id x;
+@property (assign, readonly) Test *y;
+@property (assign, readonly) id <MyProtocol> *z;
+@property (assign, readonly) ClassA *a;
+@property (assign, readonly) ClassB *b;
+@end
+
+@implementation Test
+@synthesize v;
+@synthesize w;
+@synthesize x;
+@synthesize y;
+@synthesize z;
+@synthesize a;
+@synthesize b;
+@end
+
+
+/* This is sometimes OK, sometimes not OK. */
+@interface Test2
+{
+ int v; /* { dg-message "originally specified here" } */
+ float w; /* { dg-message "originally specified here" } */
+ id x; /* { dg-message "originally specified here" } */
+ Test *y;
+ id <MyProtocol> *z; /* { dg-message "originally specified here" } */
+ ClassA *a; /* { dg-message "originally specified here" } */
+ ClassB *b;
+}
+@property (assign, readonly) float v;
+@property (assign, readonly) id w;
+@property (assign, readonly) int x;
+@property (assign, readonly) id y;
+@property (assign, readonly) Test *z;
+@property (assign, readonly) ClassB *a;
+@property (assign, readonly) ClassA *b;
+@end
+
+@implementation Test2
+@synthesize v; /* { dg-error "property .v. is using instance variable .v. of incompatible type" } */
+@synthesize w; /* { dg-error "property .w. is using instance variable .w. of incompatible type" } */
+@synthesize x; /* { dg-error "property .x. is using instance variable .x. of incompatible type" } */
+@synthesize y;
+@synthesize z; /* { dg-error "property .z. is using instance variable .z. of incompatible type" } */
+@synthesize a; /* { dg-error "property .a. is using instance variable .a. of incompatible type" } */
+@synthesize b;
+@end