summaryrefslogtreecommitdiff
path: root/gcc/testsuite/objc.dg/property
diff options
context:
space:
mode:
authornicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-14 11:11:18 +0000
committernicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-14 11:11:18 +0000
commit25bf03837aac94d1deb2d0b87f442cd65d23bbea (patch)
treeb6f11702f34e4302b1b845cbdea6c13f0797e1f5 /gcc/testsuite/objc.dg/property
parent146ab3394d9cdbe6b6b4260e4bd4e9dffa66517f (diff)
downloadgcc-25bf03837aac94d1deb2d0b87f442cd65d23bbea.tar.gz
In gcc/objc/:
2010-11-14 Nicola Pero <nicola.pero@meta-innovation.com> * objc-act.c (objc_add_property_declaration): Check that the decl we received from the parser is a FIELD_DECL; reject array and bitfield properties. Convert the warning when a property is readonly and a setter is specified into an error. Convert errors when a property declaration does not match a property declaration in a superclass into warnings. (objc_add_synthesize_declaration_for_property): Use DECL_BIT_FIELD_TYPE to determine the type of an instance variable if it is a bitfield. Throw an error if we are asked to synthesize setters/getters for a bitfield instance variable but the property is not appropriate - it must be assign and nonatomic. If the property is readonly, allow the instance variable type to be a specialization of the property type. (objc_type_valid_for_messaging): Fixed returning 'false' for a Class qualified with a protocol when the 'accept_classes' argument is 'false'. In gcc/testsuite/: 2010-11-14 Nicola Pero <nicola.pero@meta-innovation.com> * objc.dg/property/at-property-21.m: New. * objc.dg/property/at-property-22.m: New. * objc.dg/property/at-property-23.m: New. * objc.dg/property/synthesize-9.m: New. * objc.dg/property/synthesize-10.m: New. * objc.dg/property/synthesize-11.m: New. * obj-c++.dg/property/at-property-21.mm: New. * obj-c++.dg/property/at-property-22.mm: New. * obj-c++.dg/property/at-property-23.mm: New. * obj-c++.dg/property/synthesize-9.mm: New. * obj-c++.dg/property/synthesize-10.mm: New. * obj-c++.dg/property/synthesize-11.mm: New. * objc.dg/property/at-property-4.m: Updated to match new compiler where some errors have been converted into warnings and vice versa. * objc.dg/property/at-property-16.m: Same change. * objc.dg/property/at-property-18.m: Same change. * objc.dg/property/property-neg-5.m: Same change. * obj-c++.dg/property/at-property-4.mm: Same change. * obj-c++.dg/property/at-property-16.mm: Same change. * obj-c++.dg/property/at-property-18.mm: Same change. * obj-c++.dg/property/property-neg-5.mm: Same change. * obj-c++.dg/property/dynamic-2.mm: Enable tests that were commented out because of testsuite problems; I found out that using dg-warning instead of dg-message gets them to work. * obj-c++.dg/property/property-neg-3.mm: Same change. * obj-c++.dg/property/synthesize-6.mm: Same change. * obj-c++.dg/property/at-property-5.mm: Same change. * obj-c++.dg/property/at-property-14.mm: Same change. * obj-c++.dg/property/at-property-18.mm: Same change. * obj-c++.dg/property/at-property-16.mm: Same change (in this file, some tests still do not work due to some other testsuite issue). git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@166730 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/testsuite/objc.dg/property')
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-16.m16
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-18.m16
-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-4.m2
-rw-r--r--gcc/testsuite/objc.dg/property/property-neg-5.m2
-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-9.m80
10 files changed, 394 insertions, 18 deletions
diff --git a/gcc/testsuite/objc.dg/property/at-property-16.m b/gcc/testsuite/objc.dg/property/at-property-16.m
index f40225dea67..95f82e41beb 100644
--- a/gcc/testsuite/objc.dg/property/at-property-16.m
+++ b/gcc/testsuite/objc.dg/property/at-property-16.m
@@ -34,22 +34,22 @@
@end
@interface MyClass2 : MyRootClass
-@property (retain) id a; /* { dg-error "assign semantics attributes of property .a. conflict with previous declaration" } */
+@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-error "assign semantics attributes of property .b. conflict with previous declaration" } */
+@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-error ".nonatomic. attribute of property .c. conflicts with previous declaration" } */
+@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-error ".nonatomic. attribute of property .d. conflicts with previous declaration" } */
+@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-error ".setter. attribute of property .e. conflicts with previous declaration" } */
+@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-error ".getter. attribute of property .f. conflicts with previous declaration" } */
+@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-error ".readonly. attribute of property .g. conflicts with previous declaration" } */
+@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-error ".getter. attribute of property .i. conflicts with previous declaration" } */
+@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-18.m b/gcc/testsuite/objc.dg/property/at-property-18.m
index 58b1d6a07cc..e6ffb39cbd2 100644
--- a/gcc/testsuite/objc.dg/property/at-property-18.m
+++ b/gcc/testsuite/objc.dg/property/at-property-18.m
@@ -26,22 +26,22 @@
@end
@interface MyRootClass (Category)
-@property (retain) id a; /* { dg-error "assign semantics attributes of property .a. conflict with previous declaration" } */
+@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-error "assign semantics attributes of property .b. conflict with previous declaration" } */
+@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-error ".nonatomic. attribute of property .c. conflicts with previous declaration" } */
+@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-error ".nonatomic. attribute of property .d. conflicts with previous declaration" } */
+@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-error ".setter. attribute of property .e. conflicts with previous declaration" } */
+@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-error ".getter. attribute of property .f. conflicts with previous declaration" } */
+@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-error ".readonly. attribute of property .g. conflicts with previous declaration" } */
+@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-error ".getter. attribute of property .i. conflicts with previous declaration" } */
+@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-21.m b/gcc/testsuite/objc.dg/property/at-property-21.m
new file mode 100644
index 00000000000..d1f54b1cda8
--- /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 00000000000..af7f3bc1b4e
--- /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 = 0;
+ if (object.pcharp != 0)
+ abort ();
+
+ object.pshortp = 0;
+ if (object.pshortp != 0)
+ abort ();
+
+ object.pintp = 0;
+ if (object.pintp != 0)
+ abort ();
+
+ object.plongp = 0;
+ if (object.plongp != 0)
+ abort ();
+
+ object.pfloatp = 0;
+ if (object.pfloatp != 0)
+ abort ();
+
+ object.pdoublep = 0;
+ if (object.pdoublep != 0)
+ abort ();
+
+ object.penump = 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 00000000000..c1fd29df4f3
--- /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-4.m b/gcc/testsuite/objc.dg/property/at-property-4.m
index e327930f87b..941aab8e33c 100644
--- a/gcc/testsuite/objc.dg/property/at-property-4.m
+++ b/gcc/testsuite/objc.dg/property/at-property-4.m
@@ -28,7 +28,7 @@
/* Now test various problems. */
@property (readonly, readwrite) int a; /* { dg-error ".readonly. attribute conflicts with .readwrite. attribute" } */
-@property (readonly, setter=mySetterB:) int b; /* { dg-warning ".readonly. attribute conflicts with .setter. 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" } */
diff --git a/gcc/testsuite/objc.dg/property/property-neg-5.m b/gcc/testsuite/objc.dg/property/property-neg-5.m
index 403f6841c8d..464470cba7b 100644
--- a/gcc/testsuite/objc.dg/property/property-neg-5.m
+++ b/gcc/testsuite/objc.dg/property/property-neg-5.m
@@ -1,5 +1,5 @@
/* { dg-do compile } */
@interface Foo
-@property ( readonly, getter = HELLO, setter = THERE : ) int value; /* { dg-warning ".readonly. attribute conflicts with .setter. attribute" } */
+@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/synthesize-10.m b/gcc/testsuite/objc.dg/property/synthesize-10.m
new file mode 100644
index 00000000000..fc4683187df
--- /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 00000000000..e49d23424b9
--- /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-9.m b/gcc/testsuite/objc.dg/property/synthesize-9.m
new file mode 100644
index 00000000000..7eae31d3f4d
--- /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