Patchwork More Objective-C 2.0 @property/@synthesize fixes

login
register
mail settings
Submitter Nicola Pero
Date Nov. 13, 2010, 5:36 p.m.
Message ID <1289669784.682220516@192.168.2.228>
Download mbox | patch
Permalink /patch/71064/
State New
Headers show

Comments

Nicola Pero - Nov. 13, 2010, 5:36 p.m.
This new ObjC/ObjC++ patch contains another group of @property/@synthesize type fixes and improvements:

 * it removes an incorrect warning when 'assign' is used in a @property declaration with 'Class <MyProtocol>'.

 * it allows the type of an instance variable for a @synthesized property to be "more specialized"
than the type of the property, if the property is read-only.

 * it detects and rejects attempts to declare @properties of type array or which are bit-fields, 
which are invalid.

 * it allows a bit-field instance variable to be used by @synthesize.  The runtime getter/setter helpers
do not work with bit-field instance variables though, so I added explicit checks that the @property was
'nonatomic' and 'assign' to make sure that direct variable access (which works fine with bit-field variables) 
could be used when generating the accessors.  I doubt bit-fields would be used much with properties; 
it's nice to have them for completeness though.

 * it tidies up some warnings and errors.  It's sometimes hard to decide what should be a warning and
what should be an error and I changed my mind a few times.  Anyway, in the end I'm leaving most of the
errors and warnings as they are, with two exceptions: if a property is declared readonly, and a getter
is specified at the same time, I made that into an error because it does seem very inconsistent and
the compiler can't guess what is meant; error recovery (ie, ignoring one of the two) would have to kick
in and that seems to be an error situation.  Vice versa, if a @property is re-declared in a subclass with 
different attributes, I changed these to be warnings as opposed to errors because we can compile everything 
fine and there may be reasons why it does not matter and everything will actually work (eg, maybe one 
of the properties is never actually used; I suppose it is also possible that all property accesses are done 
using accurate casts to make sure the right property is picked up).  We still warn and you can't really turn 
off the warnings, which is still quite heavy, but we don't refuse to compile any more.

Testcases for all of the changes above are included.  I also added a couple of testcases testing properties 
of type 'enum' and of other types, just to make sure there are no surprises.  I also figured out that most of
the ObjC++ testsuite issues I had go away if you use dg-warning instead of dg-message to match things like
"note: originally specified here".  I updated the relevant ObjC++ testcases and was able to enable them so
we have a better ObjC++ testsuite coverage.

Ok to commit to trunk ?

Thanks

PS: It's all starting to be in good shape.  The main key remaining problems to work on are:

 * ObjC 2.0 dot-syntax accessors don't work in quite a few cases (object.property++, object.property1 = object.property2 = x etc)

 * @optional + @property does not work

 * the checks that user-generated setters/getters have the right signature are missing

I guess I am a few patches away from finishing (even if I felt "a few patches away" for the past few weeks (if not months), 
but now it seems I may really be) :-)


In gcc/objc/:
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'.

In gcc/testsuite/:
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).
Nicola Pero - Nov. 13, 2010, 5:40 p.m.
> if a property is declared readonly, and a getter is specified at the same time, I made that into an error

I obviously meant "if a property is declared readonly, and a *setter* is specified at the same time" ;-)

Apologies

Thanks
Mike Stump - Nov. 14, 2010, 5:32 a.m.
On Nov 13, 2010, at 9:36 AM, "Nicola Pero" <nicola.pero@meta-innovation.com> wrote:
> This new ObjC/ObjC++ patch contains another group of @property/@synthesize type fixes and improvements:

> It's sometimes hard to decide what should be a warning and
> what should be an error and I changed my mind a few times.

I'd hope that clang could provide guidance...

> Ok to commit to trunk ?

Ok.
>

Patch

Index: gcc/objc/objc-act.c
===================================================================
--- gcc/objc/objc-act.c	(revision 166711)
+++ gcc/objc/objc-act.c	(working copy)
@@ -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;
Index: gcc/objc/ChangeLog
===================================================================
--- gcc/objc/ChangeLog	(revision 166711)
+++ gcc/objc/ChangeLog	(working copy)
@@ -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.
Index: gcc/testsuite/ChangeLog
===================================================================
--- gcc/testsuite/ChangeLog	(revision 166711)
+++ gcc/testsuite/ChangeLog	(working copy)
@@ -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
Index: gcc/testsuite/objc.dg/property/property-neg-5.m
===================================================================
--- gcc/testsuite/objc.dg/property/property-neg-5.m	(revision 166711)
+++ gcc/testsuite/objc.dg/property/property-neg-5.m	(working copy)
@@ -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
Index: gcc/testsuite/objc.dg/property/at-property-22.m
===================================================================
--- gcc/testsuite/objc.dg/property/at-property-22.m	(revision 0)
+++ gcc/testsuite/objc.dg/property/at-property-22.m	(revision 0)
@@ -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;
+}
Index: gcc/testsuite/objc.dg/property/synthesize-10.m
===================================================================
--- gcc/testsuite/objc.dg/property/synthesize-10.m	(revision 0)
+++ gcc/testsuite/objc.dg/property/synthesize-10.m	(revision 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;
+}
Index: gcc/testsuite/objc.dg/property/at-property-4.m
===================================================================
--- gcc/testsuite/objc.dg/property/at-property-4.m	(revision 166711)
+++ gcc/testsuite/objc.dg/property/at-property-4.m	(working copy)
@@ -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" } */
Index: gcc/testsuite/objc.dg/property/at-property-16.m
===================================================================
--- gcc/testsuite/objc.dg/property/at-property-16.m	(revision 166711)
+++ gcc/testsuite/objc.dg/property/at-property-16.m	(working copy)
@@ -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
 
Index: gcc/testsuite/objc.dg/property/at-property-18.m
===================================================================
--- gcc/testsuite/objc.dg/property/at-property-18.m	(revision 166711)
+++ gcc/testsuite/objc.dg/property/at-property-18.m	(working copy)
@@ -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
Index: gcc/testsuite/objc.dg/property/at-property-21.m
===================================================================
--- gcc/testsuite/objc.dg/property/at-property-21.m	(revision 0)
+++ gcc/testsuite/objc.dg/property/at-property-21.m	(revision 0)
@@ -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
Index: gcc/testsuite/objc.dg/property/at-property-23.m
===================================================================
--- gcc/testsuite/objc.dg/property/at-property-23.m	(revision 0)
+++ gcc/testsuite/objc.dg/property/at-property-23.m	(revision 0)
@@ -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
Index: gcc/testsuite/objc.dg/property/synthesize-11.m
===================================================================
--- gcc/testsuite/objc.dg/property/synthesize-11.m	(revision 0)
+++ gcc/testsuite/objc.dg/property/synthesize-11.m	(revision 0)
@@ -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 } */
Index: gcc/testsuite/objc.dg/property/synthesize-9.m
===================================================================
--- gcc/testsuite/objc.dg/property/synthesize-9.m	(revision 0)
+++ gcc/testsuite/objc.dg/property/synthesize-9.m	(revision 0)
@@ -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
Index: gcc/testsuite/obj-c++.dg/property/property-neg-5.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/property/property-neg-5.mm	(revision 166711)
+++ gcc/testsuite/obj-c++.dg/property/property-neg-5.mm	(working copy)
@@ -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
Index: gcc/testsuite/obj-c++.dg/property/synthesize-6.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/property/synthesize-6.mm	(revision 166711)
+++ gcc/testsuite/obj-c++.dg/property/synthesize-6.mm	(working copy)
@@ -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 } */
Index: gcc/testsuite/obj-c++.dg/property/at-property-14.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/property/at-property-14.mm	(revision 166711)
+++ gcc/testsuite/obj-c++.dg/property/at-property-14.mm	(working copy)
@@ -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
Index: gcc/testsuite/obj-c++.dg/property/at-property-18.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/property/at-property-18.mm	(revision 166711)
+++ gcc/testsuite/obj-c++.dg/property/at-property-18.mm	(working copy)
@@ -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
Index: gcc/testsuite/obj-c++.dg/property/dynamic-2.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/property/dynamic-2.mm	(revision 166711)
+++ gcc/testsuite/obj-c++.dg/property/dynamic-2.mm	(working copy)
@@ -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
Index: gcc/testsuite/obj-c++.dg/property/at-property-23.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/property/at-property-23.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/property/at-property-23.mm	(revision 0)
@@ -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
Index: gcc/testsuite/obj-c++.dg/property/synthesize-9.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/property/synthesize-9.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/property/synthesize-9.mm	(revision 0)
@@ -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
Index: gcc/testsuite/obj-c++.dg/property/synthesize-11.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/property/synthesize-11.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/property/synthesize-11.mm	(revision 0)
@@ -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 } */
Index: gcc/testsuite/obj-c++.dg/property/at-property-5.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/property/at-property-5.mm	(revision 166711)
+++ gcc/testsuite/obj-c++.dg/property/at-property-5.mm	(working copy)
@@ -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" } */
Index: gcc/testsuite/obj-c++.dg/property/property-neg-3.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/property/property-neg-3.mm	(revision 166711)
+++ gcc/testsuite/obj-c++.dg/property/property-neg-3.mm	(working copy)
@@ -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
Index: gcc/testsuite/obj-c++.dg/property/at-property-22.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/property/at-property-22.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/property/at-property-22.mm	(revision 0)
@@ -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;
+}
Index: gcc/testsuite/obj-c++.dg/property/at-property-16.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/property/at-property-16.mm	(revision 166711)
+++ gcc/testsuite/obj-c++.dg/property/at-property-16.mm	(working copy)
@@ -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
Index: gcc/testsuite/obj-c++.dg/property/synthesize-10.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/property/synthesize-10.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/property/synthesize-10.mm	(revision 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;
+}
Index: gcc/testsuite/obj-c++.dg/property/at-property-4.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/property/at-property-4.mm	(revision 166711)
+++ gcc/testsuite/obj-c++.dg/property/at-property-4.mm	(working copy)
@@ -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" } */
Index: gcc/testsuite/obj-c++.dg/property/at-property-21.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/property/at-property-21.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/property/at-property-21.mm	(revision 0)
@@ -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