aboutsummaryrefslogtreecommitdiff
path: root/gcc/objc/objc-act.c
diff options
context:
space:
mode:
authorNicola Pero <nicola.pero@meta-innovation.com>2010-11-14 11:11:18 +0000
committerNicola Pero <nicola@gcc.gnu.org>2010-11-14 11:11:18 +0000
commit8926bd5d5c308154694122957e2a54c965ebee08 (patch)
treeb6f11702f34e4302b1b845cbdea6c13f0797e1f5 /gcc/objc/objc-act.c
parent8a7a250d322e4913add44c4bd6d854d25650d389 (diff)
downloadgcc-8926bd5d5c308154694122957e2a54c965ebee08.zip
gcc-8926bd5d5c308154694122957e2a54c965ebee08.tar.gz
gcc-8926bd5d5c308154694122957e2a54c965ebee08.tar.bz2
In gcc/objc/: 2010-11-14 Nicola Pero <nicola.pero@meta-innovation.com>
In gcc/objc/: 2010-11-14 Nicola Pero <nicola.pero@meta-innovation.com> * objc-act.c (objc_add_property_declaration): Check that the decl we received from the parser is a FIELD_DECL; reject array and bitfield properties. Convert the warning when a property is readonly and a setter is specified into an error. Convert errors when a property declaration does not match a property declaration in a superclass into warnings. (objc_add_synthesize_declaration_for_property): Use DECL_BIT_FIELD_TYPE to determine the type of an instance variable if it is a bitfield. Throw an error if we are asked to synthesize setters/getters for a bitfield instance variable but the property is not appropriate - it must be assign and nonatomic. If the property is readonly, allow the instance variable type to be a specialization of the property type. (objc_type_valid_for_messaging): Fixed returning 'false' for a Class qualified with a protocol when the 'accept_classes' argument is 'false'. In gcc/testsuite/: 2010-11-14 Nicola Pero <nicola.pero@meta-innovation.com> * objc.dg/property/at-property-21.m: New. * objc.dg/property/at-property-22.m: New. * objc.dg/property/at-property-23.m: New. * objc.dg/property/synthesize-9.m: New. * objc.dg/property/synthesize-10.m: New. * objc.dg/property/synthesize-11.m: New. * obj-c++.dg/property/at-property-21.mm: New. * obj-c++.dg/property/at-property-22.mm: New. * obj-c++.dg/property/at-property-23.mm: New. * obj-c++.dg/property/synthesize-9.mm: New. * obj-c++.dg/property/synthesize-10.mm: New. * obj-c++.dg/property/synthesize-11.mm: New. * objc.dg/property/at-property-4.m: Updated to match new compiler where some errors have been converted into warnings and vice versa. * objc.dg/property/at-property-16.m: Same change. * objc.dg/property/at-property-18.m: Same change. * objc.dg/property/property-neg-5.m: Same change. * obj-c++.dg/property/at-property-4.mm: Same change. * obj-c++.dg/property/at-property-16.mm: Same change. * obj-c++.dg/property/at-property-18.mm: Same change. * obj-c++.dg/property/property-neg-5.mm: Same change. * obj-c++.dg/property/dynamic-2.mm: Enable tests that were commented out because of testsuite problems; I found out that using dg-warning instead of dg-message gets them to work. * obj-c++.dg/property/property-neg-3.mm: Same change. * obj-c++.dg/property/synthesize-6.mm: Same change. * obj-c++.dg/property/at-property-5.mm: Same change. * obj-c++.dg/property/at-property-14.mm: Same change. * obj-c++.dg/property/at-property-18.mm: Same change. * obj-c++.dg/property/at-property-16.mm: Same change (in this file, some tests still do not work due to some other testsuite issue). From-SVN: r166730
Diffstat (limited to 'gcc/objc/objc-act.c')
-rw-r--r--gcc/objc/objc-act.c114
1 files changed, 97 insertions, 17 deletions
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 48b04ac..da97e14 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -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;