===================================================================
@@ -948,8 +948,7 @@ objc_add_property_declaration (location_t location
if (parsed_property_readonly && parsed_property_setter_ident)
{
- /* Maybe this should be an error ? The Apple documentation says it is a warning. */
- warning_at (location, 0, "%<readonly%> attribute conflicts with %<setter%> attribute");
+ error_at (location, "%<readonly%> attribute conflicts with %<setter%> attribute");
property_readonly = false;
}
@@ -989,17 +988,44 @@ objc_add_property_declaration (location_t location
/* At this point we know that we are either in an interface, a
category, or a protocol. */
- /* Check that the property does not have an initial value specified.
- This should never happen as the parser doesn't allow this, but
- it's just in case. */
- if (DECL_INITIAL (decl))
+ /* We expect a FIELD_DECL from the parser. Make sure we didn't get
+ something else, as that would confuse the checks below. */
+ if (TREE_CODE (decl) != FIELD_DECL)
{
- error_at (location, "property can not have an initial value");
+ error_at (location, "invalid property declaration");
+ return;
+ }
+
+ /* Do some spot-checks for the most obvious invalid types. */
+
+ if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
+ {
+ error_at (location, "property can not be an array");
return;
}
- /* TODO: Check that the property type is an Objective-C object or a "POD". */
+ /* The C++/ObjC++ parser seems to reject the ':' for a bitfield when
+ parsing, while the C/ObjC parser accepts it and gives us a
+ FIELD_DECL with a DECL_INITIAL set. So we use the DECL_INITIAL
+ to check for a bitfield when doing ObjC. */
+#ifndef OBJCPLUS
+ if (DECL_INITIAL (decl))
+ {
+ /* A @property is not an actual variable, but it is a way to
+ describe a pair of accessor methods, so its type (which is
+ the type of the return value of the getter and the first
+ argument of the setter) can't be a bitfield (as return values
+ and arguments of functions can not be bitfields). The
+ underlying instance variable could be a bitfield, but that is
+ a different matter. */
+ error_at (location, "property can not be a bit-field");
+ return;
+ }
+#endif
+ /* TODO: Check that the property type is an Objective-C object or a
+ "POD". */
+
/* Implement -Wproperty-assign-default (which is enabled by default). */
if (warn_property_assign_default
/* If garbage collection is not being used, then 'assign' is
@@ -1136,7 +1162,8 @@ objc_add_property_declaration (location_t location
if (PROPERTY_NONATOMIC (x) != parsed_property_nonatomic)
{
- error_at (location, "'nonatomic' attribute of property %qD conflicts with previous declaration", decl);
+ warning_at (location, 0,
+ "'nonatomic' attribute of property %qD conflicts with previous declaration", decl);
if (original_location != UNKNOWN_LOCATION)
inform (original_location, "originally specified here");
@@ -1145,7 +1172,8 @@ objc_add_property_declaration (location_t location
if (PROPERTY_GETTER_NAME (x) != parsed_property_getter_ident)
{
- error_at (location, "'getter' attribute of property %qD conflicts with previous declaration", decl);
+ warning_at (location, 0,
+ "'getter' attribute of property %qD conflicts with previous declaration", decl);
if (original_location != UNKNOWN_LOCATION)
inform (original_location, "originally specified here");
@@ -1157,7 +1185,8 @@ objc_add_property_declaration (location_t location
{
if (PROPERTY_SETTER_NAME (x) != parsed_property_setter_ident)
{
- error_at (location, "'setter' attribute of property %qD conflicts with previous declaration", decl);
+ warning_at (location, 0,
+ "'setter' attribute of property %qD conflicts with previous declaration", decl);
if (original_location != UNKNOWN_LOCATION)
inform (original_location, "originally specified here");
@@ -1167,7 +1196,8 @@ objc_add_property_declaration (location_t location
if (PROPERTY_ASSIGN_SEMANTICS (x) != property_assign_semantics)
{
- error_at (location, "assign semantics attributes of property %qD conflict with previous declaration", decl);
+ warning_at (location, 0,
+ "assign semantics attributes of property %qD conflict with previous declaration", decl);
if (original_location != UNKNOWN_LOCATION)
inform (original_location, "originally specified here");
@@ -1177,7 +1207,8 @@ objc_add_property_declaration (location_t location
/* It's ok to have a readonly property that becomes a readwrite, but not vice versa. */
if (PROPERTY_READONLY (x) == 0 && property_readonly == 1)
{
- error_at (location, "'readonly' attribute of property %qD conflicts with previous declaration", decl);
+ warning_at (location, 0,
+ "'readonly' attribute of property %qD conflicts with previous declaration", decl);
if (original_location != UNKNOWN_LOCATION)
inform (original_location, "originally specified here");
@@ -9854,6 +9885,7 @@ objc_add_synthesize_declaration_for_property (loca
instance variable is only used in one synthesized property). */
{
tree ivar = is_ivar (CLASS_IVARS (interface), ivar_name);
+ tree type_of_ivar;
if (!ivar)
{
error_at (location, "ivar %qs used by %<@synthesize%> declaration must be an existing ivar",
@@ -9861,8 +9893,19 @@ objc_add_synthesize_declaration_for_property (loca
return;
}
- /* If the instance variable has a different C type, we warn. */
- if (!comptypes (TREE_TYPE (property), TREE_TYPE (ivar)))
+ if (DECL_BIT_FIELD_TYPE (ivar))
+ type_of_ivar = DECL_BIT_FIELD_TYPE (ivar);
+ else
+ type_of_ivar = TREE_TYPE (ivar);
+
+ /* If the instance variable has a different C type, we throw an error ... */
+ if (!comptypes (TREE_TYPE (property), type_of_ivar)
+ /* ... unless the property is readonly, in which case we allow
+ the instance variable to be more specialized (this means we
+ can generate the getter all right and it works). */
+ && (!PROPERTY_READONLY (property)
+ || !objc_compare_types (TREE_TYPE (property),
+ type_of_ivar, -5, NULL_TREE)))
{
location_t original_location = DECL_SOURCE_LOCATION (ivar);
@@ -9873,6 +9916,43 @@ objc_add_synthesize_declaration_for_property (loca
if (original_location != UNKNOWN_LOCATION)
inform (original_location, "originally specified here");
}
+
+ /* If the instance variable is a bitfield, the property must be
+ 'assign', 'nonatomic' because the runtime getter/setter helper
+ do not work with bitfield instance variables. */
+ if (DECL_BIT_FIELD_TYPE (ivar))
+ {
+ /* If there is an error, we return and not generate any
+ getter/setter because trying to set up the runtime
+ getter/setter helper calls with bitfields is at high risk
+ of ICE. */
+
+ if (PROPERTY_ASSIGN_SEMANTICS (property) != OBJC_PROPERTY_ASSIGN)
+ {
+ location_t original_location = DECL_SOURCE_LOCATION (ivar);
+
+ error_at (location, "'assign' property %qs is using bit-field instance variable %qs",
+ IDENTIFIER_POINTER (property_name),
+ IDENTIFIER_POINTER (ivar_name));
+
+ if (original_location != UNKNOWN_LOCATION)
+ inform (original_location, "originally specified here");
+ return;
+ }
+
+ if (!PROPERTY_NONATOMIC (property))
+ {
+ location_t original_location = DECL_SOURCE_LOCATION (ivar);
+
+ error_at (location, "'atomic' property %qs is using bit-field instance variable %qs",
+ IDENTIFIER_POINTER (property_name),
+ IDENTIFIER_POINTER (ivar_name));
+
+ if (original_location != UNKNOWN_LOCATION)
+ inform (original_location, "originally specified here");
+ return;
+ }
+ }
}
/* Check that no other property is using the same instance
@@ -12566,8 +12646,8 @@ objc_type_valid_for_messaging (tree type, bool acc
if (objc_is_object_id (type))
return true;
- if (accept_classes && objc_is_class_id (type))
- return true;
+ if (objc_is_class_id (type))
+ return accept_classes;
if (TYPE_HAS_OBJC_INFO (type))
return true;
===================================================================
@@ -1,5 +1,24 @@
2010-11-13 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'.
+
+2010-11-13 Nicola Pero <nicola.pero@meta-innovation.com>
+
* objc-act.c (objc_get_protocol_qualified_type): detect cases
where we are asked to attach a protocol to something which is not
an Objective-C object type, and produce an error.
===================================================================
@@ -1,3 +1,39 @@
+2010-11-13 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).
+
2010-11-13 Paolo Bonzini <bonzini@gnu.org>
PR c/46462
===================================================================
@@ -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
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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" } */
===================================================================
@@ -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
===================================================================
@@ -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
===================================================================
@@ -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
===================================================================
@@ -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
===================================================================
@@ -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 } */
===================================================================
@@ -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
===================================================================
@@ -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
===================================================================
@@ -14,12 +14,10 @@
@property int v1;
@property int v2;
@end
-#if 0 /* This is a problem in the testsuite; the compiler is fine, but the testsuite still barfs on the following. */
@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." */
+@synthesize v1 = v; /* { dg-warning "originally specified here" } */
+@synthesize v2 = v; /* { dg-error "property .v2. is using the same instance variable as property .v1." } */
@end
-#endif
@interface Test2 : Test
@property int w1;
@end
@@ -27,6 +25,6 @@
@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 } */
+/* { dg-warning "incomplete implementation" "" { target *-*-* } 27 } */
+/* { dg-warning "method definition for .-setW1:. not found" "" { target *-*-* } 27 } */
+/* { dg-warning "method definition for .-w1. not found" "" { target *-*-* } 27 } */
===================================================================
@@ -9,16 +9,12 @@
}
/* Test the warnings on 'assign'. */
-/* FIXME - there is a problem with the testuite in running the following test. The compiler
- generates the messages, but the testsuite still complains. */
-/*@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 id property_a; /* { dg-warning "object property .property.a. has no .assign., .retain. or .copy. attribute" } */
+ /* { dg-warning ".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). */
-/* FIXME - there is a problem with the testuite in running the following test. The compiler
- generates the messages, but the testsuite still complains. */
-/*@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 */
+@property MyRootClass *property_e; /* { dg-warning "object property .property.e. has no .assign., .retain. or .copy. attribute" } */
+ /* { dg-warning ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 18 } */
@end
===================================================================
@@ -24,24 +24,23 @@
@property (readonly,getter=getMe) int i;
@property (nonatomic) float j;
@end
-/* FIXME - there is a problem with the testuite in running the following test. The compiler generates the messages, but the testsuite still complains. */
@interface MyRootClass (Category)
-/*@property (retain) id a; */ /* dg-error "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" */
- /* dg-message "originally specified here" "" { target *-*-* } 17 */
-/*@property (nonatomic) int c; */ /* dg-error ".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" */
- /* dg-message "originally specified here" "" { target *-*-* } 19 */
-/*@property (setter=setX:) int e; */ /* dg-error ".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" */
- /* dg-message "originally specified here" "" { target *-*-* } 21 */
-/*@property (readonly) int g; */ /* dg-error ".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" */
- /* dg-message "originally specified here" "" { target *-*-* } 24 */
+@property (retain) id a; /* { dg-warning "assign semantics attributes of property .a. conflict with previous declaration" } */
+ /* { dg-warning "originally specified here" "" { target *-*-* } 16 } */
+@property (assign) id b; /* { dg-warning "assign semantics attributes of property .b. conflict with previous declaration" } */
+ /* { dg-warning "originally specified here" "" { target *-*-* } 17 } */
+@property (nonatomic) int c; /* { dg-warning ".nonatomic. attribute of property .c. conflicts with previous declaration" } */
+ /* { dg-warning "originally specified here" "" { target *-*-* } 18 } */
+@property int d; /* { dg-warning ".nonatomic. attribute of property .d. conflicts with previous declaration" } */
+ /* { dg-warning "originally specified here" "" { target *-*-* } 19 } */
+@property (setter=setX:) int e; /* { dg-warning ".setter. attribute of property .e. conflicts with previous declaration" } */
+ /* { dg-warning "originally specified here" "" { target *-*-* } 20 } */
+@property (getter=x) int f; /* { dg-warning ".getter. attribute of property .f. conflicts with previous declaration" } */
+ /* { dg-warning "originally specified here" "" { target *-*-* } 21 } */
+@property (readonly) int g; /* { dg-warning ".readonly. attribute of property .g. conflicts with previous declaration" } */
+ /* { dg-warning "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-warning "originally specified here" "" { target *-*-* } 24 } */
@property (nonatomic) float j; /* Ok */
@end
===================================================================
@@ -39,9 +39,7 @@
@implementation AnotherTest
@dynamic one;
-/* FIXME - there is a problem with the testuite in running the following test. The compiler
- generates the messages, but the testsuite still complains. */
-/*@dynamic one;*/ /* dg-error "property .one. already specified in .@dynamic." */
- /* dg-message "originally specified here" "" { target *-*-* } 40 */
+@dynamic one; /* { dg-error "property .one. already specified in .@dynamic." } */
+ /* { dg-warning "originally specified here" "" { target *-*-* } 41 } */
@dynamic three; /* { dg-error "no declaration of property .three. found in the interface" } */
@end
===================================================================
@@ -0,0 +1,18 @@
+/* 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 "expected" } */
+@property int c[]; /* { dg-error "property can not be an array" } */
+ /* { dg-error "ISO C.. forbids zero-size array" "" { target *-*-* } 16 } */
+@end
===================================================================
@@ -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-warning "originally specified here" } */
+ float w; /* { dg-warning "originally specified here" } */
+ id x; /* { dg-warning "originally specified here" } */
+ Test *y;
+ id <MyProtocol> *z; /* { dg-warning "originally specified here" } */
+ ClassA *a; /* { dg-warning "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
===================================================================
@@ -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-warning "originally specified here" } */
+ int countB : 3; /* { dg-warning "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 } */
===================================================================
@@ -17,10 +17,8 @@
}
/* Test various error messages. */
-/* FIXME - there is a problem with the testuite in running the following test. The compiler
- generates the messages, but the testsuite still complains. */
-/*@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 id property_a; /* { dg-warning "object property .property.a. has no .assign., .retain. or .copy. attribute" } */
+ /* { dg-warning ".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" } */
@@ -29,10 +27,8 @@
@property (retain) id property_f;
@property (retain) id property_g;
@property (retain) id property_h;
-/* FIXME - there is a problem with the testuite in running the following test. The compiler
- generates the messages, but the testsuite still complains. */
-/*@property (retain) id property_e;*/ /* dg-error "redeclaration of property .property_e." */
- /* dg-message "originally specified here" "" { target *-*-* } 26 */
+@property (retain) id property_e; /* { dg-error "redeclaration of property .property_e." } */
+ /* { dg-warning "originally specified here" "" { target *-*-* } 26 } */
@end
@property id test; /* { dg-error "misplaced .@property. Objective-C.. construct" } */
===================================================================
@@ -9,8 +9,6 @@
@implementation Person
@dynamic firstName;
-/* FIXME - there is a problem with the testuite in running the following test. The compiler
- generates the messages, but the testsuite still complains. */
-/*@synthesize firstName;*/ /* dg-error "property .firstName. already specified in .@dynamic." */
- /* dg-message "originally specified here" "" { target *-*-* } 11 */
+@synthesize firstName; /* { dg-error "property .firstName. already specified in .@dynamic." } */
+ /* { dg-warning "originally specified here" "" { target *-*-* } 11 } */
@end
===================================================================
@@ -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;
+}
===================================================================
@@ -10,15 +10,16 @@
{
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 (assign) id a; /* { dg-warning "originally specified here" } */
+@property (retain) id b; /* { dg-warning "originally specified here" } */
+@property int c; /* { dg-warning "originally specified here" } */
+@property (nonatomic) int d; /* { dg-warning "originally specified here" } */
+/* FIXME: The compiler generates these errors, but the testsuite still fails the tests. */
+@property int e; /* dg-warning "originally specified here" */
+@property int f; /* dg-warning "originally specified here" */
+@property int g; /* dg-warning "originally specified here" */
+@property (readonly) int h; /* Ok */
+@property (readonly,getter=getMe) int i; /* { dg-warning "originally specified here" } */
@end
@interface MyClass : MyRootClass
@@ -32,23 +33,16 @@
@property (readonly) int h;
@property (readonly,getter=getMe) int i;
@end
-/* FIXME - there is a problem with the testuite in running the following test. The compiler generates the messages, but the testsuite still complains. */
+
@interface MyClass2 : MyRootClass
-/* @property (retain) id a; */ /* dg-error "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" */
- /* dg-message "originally specified here" "" { target *-*-* } 14 */
-/* @property (nonatomic) int c; */ /* dg-error ".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" */
- /* dg-message "originally specified here" "" { target *-*-* } 16 */
-/* @property (setter=setX:) int e; */ /* dg-error ".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" */
- /* dg-message "originally specified here" "" { target *-*-* } 18 */
-/* @property (readonly) int g; */ /* dg-error ".readonly. attribute of property .g. conflicts with previous declaration" */
- /* dg-message "originally specified here" "" { target *-*-* } 19 */
+@property (retain) id a; /* { dg-warning "assign semantics attributes of property .a. conflict with previous declaration" } */
+@property (assign) id b; /* { dg-warning "assign semantics attributes of property .b. conflict with previous declaration" } */
+@property (nonatomic) int c; /* { dg-warning ".nonatomic. attribute of property .c. conflicts with previous declaration" } */
+@property int d; /* { dg-warning ".nonatomic. attribute of property .d. conflicts with previous declaration" } */
+/* FIXME: The compiler generates these errors, but the testsuite still fails the tests. */
+/*@property (setter=setX:) int e;*/ /* dg-warning ".setter. attribute of property .e. conflicts with previous declaration" */
+/*@property (getter=x) int f;*/ /* dg-warning ".getter. attribute of property .f. conflicts with previous declaration" */
+/*@property (readonly) int g;*/ /* dg-warning ".readonly. attribute of property .g. conflicts with previous declaration" */
@property (readwrite) int h; /* Ok */
-/* @property (readonly) int i; */ /* dg-error ".getter. attribute of property .i. conflicts with previous declaration" */
- /* dg-message "originally specified here" "" { target *-*-* } 21 */
+@property (readonly) int i; /* { dg-warning ".getter. attribute of property .i. conflicts with previous declaration" } */
@end
===================================================================
@@ -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;
+}
===================================================================
@@ -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" } */
===================================================================
@@ -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-warning ".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-warning ".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