diff options
author | nicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-14 11:11:18 +0000 |
---|---|---|
committer | nicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-14 11:11:18 +0000 |
commit | 25bf03837aac94d1deb2d0b87f442cd65d23bbea (patch) | |
tree | b6f11702f34e4302b1b845cbdea6c13f0797e1f5 /gcc/testsuite/objc.dg/property | |
parent | 146ab3394d9cdbe6b6b4260e4bd4e9dffa66517f (diff) | |
download | gcc-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.m | 16 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/at-property-18.m | 16 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/at-property-21.m | 23 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/at-property-22.m | 172 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/at-property-23.m | 17 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/at-property-4.m | 2 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/property-neg-5.m | 2 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/synthesize-10.m | 53 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/synthesize-11.m | 31 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/synthesize-9.m | 80 |
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 |