OSDN Git Service

In gcc/objc/:
authornicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 14 Nov 2010 11:11:18 +0000 (11:11 +0000)
committernicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 14 Nov 2010 11:11:18 +0000 (11:11 +0000)
2010-11-14  Nicola Pero  <nicola.pero@meta-innovation.com>

        * objc-act.c (objc_add_property_declaration): Check that the decl
        we received from the parser is a FIELD_DECL; reject array and
        bitfield properties.  Convert the warning when a property is
        readonly and a setter is specified into an error.  Convert errors
        when a property declaration does not match a property declaration
        in a superclass into warnings.
        (objc_add_synthesize_declaration_for_property): Use
        DECL_BIT_FIELD_TYPE to determine the type of an instance variable
        if it is a bitfield.  Throw an error if we are asked to synthesize
        setters/getters for a bitfield instance variable but the property
        is not appropriate - it must be assign and nonatomic.  If the
        property is readonly, allow the instance variable type to be a
        specialization of the property type.
        (objc_type_valid_for_messaging): Fixed returning 'false' for a
        Class qualified with a protocol when the 'accept_classes' argument
        is 'false'.

In gcc/testsuite/:
2010-11-14  Nicola Pero  <nicola.pero@meta-innovation.com>

        * objc.dg/property/at-property-21.m: New.
        * objc.dg/property/at-property-22.m: New.
        * objc.dg/property/at-property-23.m: New.
        * objc.dg/property/synthesize-9.m: New.
        * objc.dg/property/synthesize-10.m: New.
        * objc.dg/property/synthesize-11.m: New.
        * obj-c++.dg/property/at-property-21.mm: New.
        * obj-c++.dg/property/at-property-22.mm: New.
        * obj-c++.dg/property/at-property-23.mm: New.
        * obj-c++.dg/property/synthesize-9.mm: New.
        * obj-c++.dg/property/synthesize-10.mm: New.
        * obj-c++.dg/property/synthesize-11.mm: New.

        * objc.dg/property/at-property-4.m: Updated to match new compiler
        where some errors have been converted into warnings and vice versa.
        * objc.dg/property/at-property-16.m: Same change.
        * objc.dg/property/at-property-18.m: Same change.
        * objc.dg/property/property-neg-5.m: Same change.
        * obj-c++.dg/property/at-property-4.mm: Same change.
        * obj-c++.dg/property/at-property-16.mm: Same change.
        * obj-c++.dg/property/at-property-18.mm: Same change.
        * obj-c++.dg/property/property-neg-5.mm: Same change.

        * obj-c++.dg/property/dynamic-2.mm: Enable tests that were
        commented out because of testsuite problems; I found out that
        using dg-warning instead of dg-message gets them to work.
        * obj-c++.dg/property/property-neg-3.mm: Same change.
        * obj-c++.dg/property/synthesize-6.mm: Same change.
        * obj-c++.dg/property/at-property-5.mm: Same change.
        * obj-c++.dg/property/at-property-14.mm: Same change.
        * obj-c++.dg/property/at-property-18.mm: Same change.
        * obj-c++.dg/property/at-property-16.mm: Same change (in this file,
        some tests still do not work due to some other testsuite issue).

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@166730 138bc75d-0d04-0410-961f-82ee72b054a4

28 files changed:
gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/testsuite/ChangeLog
gcc/testsuite/obj-c++.dg/property/at-property-14.mm
gcc/testsuite/obj-c++.dg/property/at-property-16.mm
gcc/testsuite/obj-c++.dg/property/at-property-18.mm
gcc/testsuite/obj-c++.dg/property/at-property-21.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/at-property-22.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/at-property-23.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/at-property-4.mm
gcc/testsuite/obj-c++.dg/property/at-property-5.mm
gcc/testsuite/obj-c++.dg/property/dynamic-2.mm
gcc/testsuite/obj-c++.dg/property/property-neg-3.mm
gcc/testsuite/obj-c++.dg/property/property-neg-5.mm
gcc/testsuite/obj-c++.dg/property/synthesize-10.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/synthesize-11.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/synthesize-6.mm
gcc/testsuite/obj-c++.dg/property/synthesize-9.mm [new file with mode: 0644]
gcc/testsuite/objc.dg/property/at-property-16.m
gcc/testsuite/objc.dg/property/at-property-18.m
gcc/testsuite/objc.dg/property/at-property-21.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/at-property-22.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/at-property-23.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/at-property-4.m
gcc/testsuite/objc.dg/property/property-neg-5.m
gcc/testsuite/objc.dg/property/synthesize-10.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/synthesize-11.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/synthesize-9.m [new file with mode: 0644]

index 41bc796..9dfc4f9 100644 (file)
@@ -1,3 +1,22 @@
+2010-11-14  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * objc-act.c (objc_add_property_declaration): Check that the decl
+       we received from the parser is a FIELD_DECL; reject array and
+       bitfield properties.  Convert the warning when a property is
+       readonly and a setter is specified into an error.  Convert errors
+       when a property declaration does not match a property declaration
+       in a superclass into warnings.
+       (objc_add_synthesize_declaration_for_property): Use
+       DECL_BIT_FIELD_TYPE to determine the type of an instance variable
+       if it is a bitfield.  Throw an error if we are asked to synthesize
+       setters/getters for a bitfield instance variable but the property
+       is not appropriate - it must be assign and nonatomic.  If the
+       property is readonly, allow the instance variable type to be a
+       specialization of the property type.
+       (objc_type_valid_for_messaging): Fixed returning 'false' for a
+       Class qualified with a protocol when the 'accept_classes' argument
+       is 'false'.
+
 2010-11-13  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        * objc-act.c (objc_get_protocol_qualified_type): detect cases
index 48b04ac..da97e14 100644 (file)
@@ -948,8 +948,7 @@ objc_add_property_declaration (location_t location, tree decl,
 
   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,16 +988,43 @@ objc_add_property_declaration (location_t location, tree decl,
   /* 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, "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 have an initial value");
+      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
@@ -1136,7 +1162,8 @@ objc_add_property_declaration (location_t location, tree decl,
          
       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, tree decl,
 
       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, tree decl,
        {
          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, tree decl,
 
       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, tree decl,
       /* 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 (location_t location, tree interfac
      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 (location_t location, tree interfac
        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 (location_t location, tree interfac
        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 accept_classes)
   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 f5456a1..5e19894 100644 (file)
@@ -1,3 +1,39 @@
+2010-11-14  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * objc.dg/property/at-property-21.m: New.
+       * objc.dg/property/at-property-22.m: New.
+       * objc.dg/property/at-property-23.m: New.       
+       * objc.dg/property/synthesize-9.m: New.
+       * objc.dg/property/synthesize-10.m: New.
+       * objc.dg/property/synthesize-11.m: New.        
+       * obj-c++.dg/property/at-property-21.mm: New.
+       * obj-c++.dg/property/at-property-22.mm: New.
+       * obj-c++.dg/property/at-property-23.mm: New.   
+       * obj-c++.dg/property/synthesize-9.mm: New.
+       * obj-c++.dg/property/synthesize-10.mm: New.
+       * obj-c++.dg/property/synthesize-11.mm: New.    
+
+       * objc.dg/property/at-property-4.m: Updated to match new compiler
+       where some errors have been converted into warnings and vice versa.
+       * objc.dg/property/at-property-16.m: Same change.
+       * objc.dg/property/at-property-18.m: Same change.
+       * objc.dg/property/property-neg-5.m: Same change.
+       * obj-c++.dg/property/at-property-4.mm: Same change.
+       * obj-c++.dg/property/at-property-16.mm: Same change.
+       * obj-c++.dg/property/at-property-18.mm: Same change.
+       * obj-c++.dg/property/property-neg-5.mm: Same change.
+       
+       * obj-c++.dg/property/dynamic-2.mm: Enable tests that were
+       commented out because of testsuite problems; I found out that
+       using dg-warning instead of dg-message gets them to work.
+       * obj-c++.dg/property/property-neg-3.mm: Same change.
+       * obj-c++.dg/property/synthesize-6.mm: Same change.
+       * obj-c++.dg/property/at-property-5.mm: Same change.    
+       * obj-c++.dg/property/at-property-14.mm: Same change.   
+       * obj-c++.dg/property/at-property-18.mm: Same change.
+       * obj-c++.dg/property/at-property-16.mm: Same change (in this file,
+       some tests still do not work due to some other testsuite issue).
+
 2010-11-13  Jason Merrill  <jason@redhat.com>
 
        * g++.dg/cpp0x/auto20.C: New.
index af42738..33744eb 100644 (file)
@@ -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 ca8a68c..8cab00a 100644 (file)
 {
   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
 @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 482e1ff..72abb6b 100644 (file)
 @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
diff --git a/gcc/testsuite/obj-c++.dg/property/at-property-21.mm b/gcc/testsuite/obj-c++.dg/property/at-property-21.mm
new file mode 100644 (file)
index 0000000..6106b7e
--- /dev/null
@@ -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
diff --git a/gcc/testsuite/obj-c++.dg/property/at-property-22.mm b/gcc/testsuite/obj-c++.dg/property/at-property-22.mm
new file mode 100644 (file)
index 0000000..af7f3bc
--- /dev/null
@@ -0,0 +1,172 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010.  */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test properties of different types.  */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+enum colour { Red, Black };
+
+@interface MyRootClass
+{
+  Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
++ (Class) class;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
++ (Class) class { return self; }
+@end
+
+
+@interface MyClass : MyRootClass
+{
+  /* A bunch of C types.  */
+  char         pchar;
+  short        pshort;
+  int          pint;
+  long         plong;
+  float        pfloat;
+  double       pdouble;
+  enum colour  penum;
+
+  /* A bunch of pointers to C types.  */
+  char        *pcharp;
+  short       *pshortp;
+  int         *pintp;
+  long        *plongp;
+  float       *pfloatp;
+  double      *pdoublep;
+  enum colour *penump;
+
+  /* A bunch of Objective-C types.  */
+  id           pid;
+  Class        pclass;
+  MyClass     *pMyClassp;
+}
+@property (assign) char pchar;
+@property (assign) short pshort;
+@property (assign) int pint;
+@property (assign) long plong;
+@property (assign) float pfloat;
+@property (assign) double pdouble;
+@property (assign) enum colour penum;
+
+@property (assign) char *pcharp;
+@property (assign) short *pshortp;
+@property (assign) int *pintp;
+@property (assign) long *plongp;
+@property (assign) float *pfloatp;
+@property (assign) double *pdoublep;
+@property (assign) enum colour *penump;
+
+@property (assign) id pid;
+@property (assign) Class pclass;
+@property (assign) MyClass *pMyClassp;
+@end
+
+@implementation MyClass
+@synthesize pchar;
+@synthesize pshort;
+@synthesize pint;
+@synthesize plong;
+@synthesize pfloat;
+@synthesize pdouble;
+@synthesize penum;
+
+@synthesize pcharp;
+@synthesize pshortp;
+@synthesize pintp;
+@synthesize plongp;
+@synthesize pfloatp;
+@synthesize pdoublep;
+@synthesize penump;
+
+@synthesize pid;
+@synthesize pclass;
+@synthesize pMyClassp;
+@end
+
+int main (void)
+{
+  MyClass *object = [[MyClass alloc] init];
+
+  object.pchar = 1;
+  if (object.pchar != 1)
+    abort ();
+
+  object.pshort = 2;
+  if (object.pshort != 2)
+    abort ();
+
+  object.pint = 3;
+  if (object.pint != 3)
+    abort ();
+
+  object.plong = 4;
+  if (object.plong != 4)
+    abort ();
+
+  object.pfloat = 0;
+  if (object.pfloat != 0)
+    abort ();
+
+  object.pdouble = 0;
+  if (object.pdouble != 0)
+    abort ();
+
+  object.penum = Black;
+  if (object.penum != Black)
+    abort ();
+
+  object.pcharp = 0;
+  if (object.pcharp != 0)
+    abort ();
+  
+  object.pshortp = 0;
+  if (object.pshortp != 0)
+    abort ();
+
+  object.pintp = 0;
+  if (object.pintp != 0)
+    abort ();
+    
+  object.plongp = 0;
+  if (object.plongp != 0)
+    abort ();
+    
+  object.pfloatp = 0;
+  if (object.pfloatp != 0)
+    abort ();
+    
+  object.pdoublep = 0;
+  if (object.pdoublep != 0)
+    abort ();
+    
+  object.penump = 0;
+  if (object.penump != 0)
+    abort ();
+
+  object.pid = object;
+  if (object.pid != object)
+    abort ();
+
+  object.pclass = [MyClass class];
+  if (object.pclass != [MyClass class])
+    abort ();
+
+  object.pMyClassp = object;
+  if (object.pMyClassp != object)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/obj-c++.dg/property/at-property-23.mm b/gcc/testsuite/obj-c++.dg/property/at-property-23.mm
new file mode 100644 (file)
index 0000000..73138f6
--- /dev/null
@@ -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 e327930..941aab8 100644 (file)
@@ -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 7ccf4c9..92dd114 100644 (file)
 }
 
 /* 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" } */
 @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 631eeee..39ef6b2 100644 (file)
@@ -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 a749c28..a298bf0 100644 (file)
@@ -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 403f684..464470c 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
 
 @interface Foo
-@property ( readonly, getter = HELLO, setter = THERE : ) int value; /* { dg-warning ".readonly. attribute conflicts with .setter. attribute" } */
+@property ( readonly, getter = HELLO, setter = THERE : ) int value; /* { dg-error ".readonly. attribute conflicts with .setter. attribute" } */
 @end
diff --git a/gcc/testsuite/obj-c++.dg/property/synthesize-10.mm b/gcc/testsuite/obj-c++.dg/property/synthesize-10.mm
new file mode 100644 (file)
index 0000000..fc46831
--- /dev/null
@@ -0,0 +1,53 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010.  */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test @synthesize with bitfield instance variables.  */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+  Class isa;
+  int countA : 2;
+  int countB : 3;
+  int countC : 4;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@property (nonatomic) int countA;
+@property (nonatomic) int countB;
+@property (nonatomic) int countC;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize countA;
+@synthesize countB;
+@synthesize countC;
+@end
+
+int main (void)
+{
+  MyRootClass *object = [[MyRootClass alloc] init];
+
+  object.countA = 1;
+  object.countB = 3;
+  object.countC = 4;
+
+  if (object.countA != 1)
+    abort ();
+
+  if (object.countB != 3)
+    abort ();
+
+  if (object.countC != 4)
+    abort ();
+  
+  return 0;
+}
diff --git a/gcc/testsuite/obj-c++.dg/property/synthesize-11.mm b/gcc/testsuite/obj-c++.dg/property/synthesize-11.mm
new file mode 100644 (file)
index 0000000..5d808d0
--- /dev/null
@@ -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 2d03927..f6f5293 100644 (file)
 @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 } */
diff --git a/gcc/testsuite/obj-c++.dg/property/synthesize-9.mm b/gcc/testsuite/obj-c++.dg/property/synthesize-9.mm
new file mode 100644 (file)
index 0000000..bcf195f
--- /dev/null
@@ -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 f40225d..95f82e4 100644 (file)
 @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 58b1d6a..e6ffb39 100644 (file)
 @end
 
 @interface MyRootClass (Category)
-@property (retain) id a;         /* { dg-error "assign semantics attributes of property .a. conflict with previous declaration" } */
+@property (retain) id a;         /* { dg-warning "assign semantics attributes of property .a. conflict with previous declaration" } */
                                  /* { dg-message "originally specified here" "" { target *-*-* } 16 } */
-@property (assign) id b;         /* { dg-error "assign semantics attributes of property .b. conflict with previous declaration" } */
+@property (assign) id b;         /* { dg-warning "assign semantics attributes of property .b. conflict with previous declaration" } */
                                  /* { dg-message "originally specified here" "" { target *-*-* } 17 } */
-@property (nonatomic) int c;     /* { dg-error ".nonatomic. attribute of property .c. conflicts with previous declaration" } */
+@property (nonatomic) int c;     /* { dg-warning ".nonatomic. attribute of property .c. conflicts with previous declaration" } */
                                  /* { dg-message "originally specified here" "" { target *-*-* } 18 } */
-@property int d;                 /* { dg-error ".nonatomic. attribute of property .d. conflicts with previous declaration" } */
+@property int d;                 /* { dg-warning ".nonatomic. attribute of property .d. conflicts with previous declaration" } */
                                  /* { dg-message "originally specified here" "" { target *-*-* } 19 } */
-@property (setter=setX:) int e;  /* { dg-error ".setter. attribute of property .e. conflicts with previous declaration" } */
+@property (setter=setX:) int e;  /* { dg-warning ".setter. attribute of property .e. conflicts with previous declaration" } */
                                  /* { dg-message "originally specified here" "" { target *-*-* } 20 } */
-@property (getter=x) int f;      /* { dg-error ".getter. attribute of property .f. conflicts with previous declaration" } */
+@property (getter=x) int f;      /* { dg-warning ".getter. attribute of property .f. conflicts with previous declaration" } */
                                  /* { dg-message "originally specified here" "" { target *-*-* } 21 } */
-@property (readonly) int g;      /* { dg-error ".readonly. attribute of property .g. conflicts with previous declaration" } */
+@property (readonly) int g;      /* { dg-warning ".readonly. attribute of property .g. conflicts with previous declaration" } */
                                  /* { dg-message "originally specified here" "" { target *-*-* } 22 } */
 @property (readwrite) int h;     /* Ok */
-@property (readonly) int i;      /* { dg-error ".getter. attribute of property .i. conflicts with previous declaration" } */
+@property (readonly) int i;      /* { dg-warning ".getter. attribute of property .i. conflicts with previous declaration" } */
                                  /* { dg-message "originally specified here" "" { target *-*-* } 24 } */
 @property (nonatomic) float j;   /* Ok */
 @end
diff --git a/gcc/testsuite/objc.dg/property/at-property-21.m b/gcc/testsuite/objc.dg/property/at-property-21.m
new file mode 100644 (file)
index 0000000..d1f54b1
--- /dev/null
@@ -0,0 +1,23 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010.  */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol
+- (void) message;
+@end
+
+@interface MyRootClass
+{
+  Class isa;
+}
+
+/* Test the warnings on 'assign' with protocols.  */
+@property id <MyProtocol> property_a;      /* { dg-warning "object property .property.a. has no .assign., .retain. or .copy. attribute" } */
+                                          /* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 16 } */
+
+@property MyRootClass <MyProtocol> *property_b; /* { dg-warning "object property .property.b. has no .assign., .retain. or .copy. attribute" } */
+                                               /* { dg-message ".assign. can be unsafe for Objective-C objects" "" { target *-*-* } 19 } */
+
+@property Class <MyProtocol> property_c;   /* No 'assign' warning (Classes are static objects so assign semantics do not matter for them). */
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-22.m b/gcc/testsuite/objc.dg/property/at-property-22.m
new file mode 100644 (file)
index 0000000..af7f3bc
--- /dev/null
@@ -0,0 +1,172 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010.  */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test properties of different types.  */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+enum colour { Red, Black };
+
+@interface MyRootClass
+{
+  Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
++ (Class) class;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
++ (Class) class { return self; }
+@end
+
+
+@interface MyClass : MyRootClass
+{
+  /* A bunch of C types.  */
+  char         pchar;
+  short        pshort;
+  int          pint;
+  long         plong;
+  float        pfloat;
+  double       pdouble;
+  enum colour  penum;
+
+  /* A bunch of pointers to C types.  */
+  char        *pcharp;
+  short       *pshortp;
+  int         *pintp;
+  long        *plongp;
+  float       *pfloatp;
+  double      *pdoublep;
+  enum colour *penump;
+
+  /* A bunch of Objective-C types.  */
+  id           pid;
+  Class        pclass;
+  MyClass     *pMyClassp;
+}
+@property (assign) char pchar;
+@property (assign) short pshort;
+@property (assign) int pint;
+@property (assign) long plong;
+@property (assign) float pfloat;
+@property (assign) double pdouble;
+@property (assign) enum colour penum;
+
+@property (assign) char *pcharp;
+@property (assign) short *pshortp;
+@property (assign) int *pintp;
+@property (assign) long *plongp;
+@property (assign) float *pfloatp;
+@property (assign) double *pdoublep;
+@property (assign) enum colour *penump;
+
+@property (assign) id pid;
+@property (assign) Class pclass;
+@property (assign) MyClass *pMyClassp;
+@end
+
+@implementation MyClass
+@synthesize pchar;
+@synthesize pshort;
+@synthesize pint;
+@synthesize plong;
+@synthesize pfloat;
+@synthesize pdouble;
+@synthesize penum;
+
+@synthesize pcharp;
+@synthesize pshortp;
+@synthesize pintp;
+@synthesize plongp;
+@synthesize pfloatp;
+@synthesize pdoublep;
+@synthesize penump;
+
+@synthesize pid;
+@synthesize pclass;
+@synthesize pMyClassp;
+@end
+
+int main (void)
+{
+  MyClass *object = [[MyClass alloc] init];
+
+  object.pchar = 1;
+  if (object.pchar != 1)
+    abort ();
+
+  object.pshort = 2;
+  if (object.pshort != 2)
+    abort ();
+
+  object.pint = 3;
+  if (object.pint != 3)
+    abort ();
+
+  object.plong = 4;
+  if (object.plong != 4)
+    abort ();
+
+  object.pfloat = 0;
+  if (object.pfloat != 0)
+    abort ();
+
+  object.pdouble = 0;
+  if (object.pdouble != 0)
+    abort ();
+
+  object.penum = Black;
+  if (object.penum != Black)
+    abort ();
+
+  object.pcharp = 0;
+  if (object.pcharp != 0)
+    abort ();
+  
+  object.pshortp = 0;
+  if (object.pshortp != 0)
+    abort ();
+
+  object.pintp = 0;
+  if (object.pintp != 0)
+    abort ();
+    
+  object.plongp = 0;
+  if (object.plongp != 0)
+    abort ();
+    
+  object.pfloatp = 0;
+  if (object.pfloatp != 0)
+    abort ();
+    
+  object.pdoublep = 0;
+  if (object.pdoublep != 0)
+    abort ();
+    
+  object.penump = 0;
+  if (object.penump != 0)
+    abort ();
+
+  object.pid = object;
+  if (object.pid != object)
+    abort ();
+
+  object.pclass = [MyClass class];
+  if (object.pclass != [MyClass class])
+    abort ();
+
+  object.pMyClassp = object;
+  if (object.pMyClassp != object)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/at-property-23.m b/gcc/testsuite/objc.dg/property/at-property-23.m
new file mode 100644 (file)
index 0000000..c1fd29d
--- /dev/null
@@ -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 e327930..941aab8 100644 (file)
@@ -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 403f684..464470c 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
 
 @interface Foo
-@property ( readonly, getter = HELLO, setter = THERE : ) int value; /* { dg-warning ".readonly. attribute conflicts with .setter. attribute" } */
+@property ( readonly, getter = HELLO, setter = THERE : ) int value; /* { dg-error ".readonly. attribute conflicts with .setter. attribute" } */
 @end
diff --git a/gcc/testsuite/objc.dg/property/synthesize-10.m b/gcc/testsuite/objc.dg/property/synthesize-10.m
new file mode 100644 (file)
index 0000000..fc46831
--- /dev/null
@@ -0,0 +1,53 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010.  */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+/* Test @synthesize with bitfield instance variables.  */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+  Class isa;
+  int countA : 2;
+  int countB : 3;
+  int countC : 4;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@property (nonatomic) int countA;
+@property (nonatomic) int countB;
+@property (nonatomic) int countC;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize countA;
+@synthesize countB;
+@synthesize countC;
+@end
+
+int main (void)
+{
+  MyRootClass *object = [[MyRootClass alloc] init];
+
+  object.countA = 1;
+  object.countB = 3;
+  object.countC = 4;
+
+  if (object.countA != 1)
+    abort ();
+
+  if (object.countB != 3)
+    abort ();
+
+  if (object.countC != 4)
+    abort ();
+  
+  return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/synthesize-11.m b/gcc/testsuite/objc.dg/property/synthesize-11.m
new file mode 100644 (file)
index 0000000..e49d234
--- /dev/null
@@ -0,0 +1,31 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010.  */
+/* { dg-do compile } */
+
+/* Test errors when @synthesize is used with bitfield instance variables in an incorrect way.  */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+@interface MyRootClass
+{
+  Class isa;
+  int countA : 2;                  /* { dg-message "originally specified here" } */
+  int countB : 3;                  /* { dg-message "originally specified here" } */
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
+@property int countA;       
+@property (nonatomic) short countB;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
+@synthesize countA; /* { dg-error ".atomic. property .countA. is using bit-field instance variable .countA." } */
+@synthesize countB; /* { dg-error "property .countB. is using instance variable .countB. of incompatible type" } */
+@end /* { dg-warning "incomplete implementation of class" } */
+/* { dg-warning "method definition for ..setCountA.. not found" "" { target *-*-* } 29 } */
+/* { dg-warning "method definition for ..countA. not found" "" { target *-*-* } 29 } */
diff --git a/gcc/testsuite/objc.dg/property/synthesize-9.m b/gcc/testsuite/objc.dg/property/synthesize-9.m
new file mode 100644 (file)
index 0000000..7eae31d
--- /dev/null
@@ -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