mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-21 08:30:35 +08:00
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
This commit is contained in:
parent
8a7a250d32
commit
8926bd5d5c
@ -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
|
||||
|
@ -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, "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
|
||||
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
23
gcc/testsuite/obj-c++.dg/property/at-property-21.mm
Normal file
23
gcc/testsuite/obj-c++.dg/property/at-property-21.mm
Normal file
@ -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
|
172
gcc/testsuite/obj-c++.dg/property/at-property-22.mm
Normal file
172
gcc/testsuite/obj-c++.dg/property/at-property-22.mm
Normal file
@ -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;
|
||||
}
|
18
gcc/testsuite/obj-c++.dg/property/at-property-23.mm
Normal file
18
gcc/testsuite/obj-c++.dg/property/at-property-23.mm
Normal file
@ -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
|
@ -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" } */
|
||||
|
@ -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" } */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
53
gcc/testsuite/obj-c++.dg/property/synthesize-10.mm
Normal file
53
gcc/testsuite/obj-c++.dg/property/synthesize-10.mm
Normal file
@ -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;
|
||||
}
|
31
gcc/testsuite/obj-c++.dg/property/synthesize-11.mm
Normal file
31
gcc/testsuite/obj-c++.dg/property/synthesize-11.mm
Normal file
@ -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 } */
|
@ -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 } */
|
||||
|
80
gcc/testsuite/obj-c++.dg/property/synthesize-9.mm
Normal file
80
gcc/testsuite/obj-c++.dg/property/synthesize-9.mm
Normal file
@ -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
|
@ -34,22 +34,22 @@
|
||||
@end
|
||||
|
||||
@interface MyClass2 : MyRootClass
|
||||
@property (retain) id a; /* { dg-error "assign semantics attributes of property .a. conflict with previous declaration" } */
|
||||
@property (retain) id a; /* { dg-warning "assign semantics attributes of property .a. conflict with previous declaration" } */
|
||||
/* { dg-message "originally specified here" "" { target *-*-* } 13 } */
|
||||
@property (assign) id b; /* { dg-error "assign semantics attributes of property .b. conflict with previous declaration" } */
|
||||
@property (assign) id b; /* { dg-warning "assign semantics attributes of property .b. conflict with previous declaration" } */
|
||||
/* { dg-message "originally specified here" "" { target *-*-* } 14 } */
|
||||
@property (nonatomic) int c; /* { dg-error ".nonatomic. attribute of property .c. conflicts with previous declaration" } */
|
||||
@property (nonatomic) int c; /* { dg-warning ".nonatomic. attribute of property .c. conflicts with previous declaration" } */
|
||||
/* { dg-message "originally specified here" "" { target *-*-* } 15 } */
|
||||
@property int d; /* { dg-error ".nonatomic. attribute of property .d. conflicts with previous declaration" } */
|
||||
@property int d; /* { dg-warning ".nonatomic. attribute of property .d. conflicts with previous declaration" } */
|
||||
/* { dg-message "originally specified here" "" { target *-*-* } 16 } */
|
||||
@property (setter=setX:) int e; /* { dg-error ".setter. attribute of property .e. conflicts with previous declaration" } */
|
||||
@property (setter=setX:) int e; /* { dg-warning ".setter. attribute of property .e. conflicts with previous declaration" } */
|
||||
/* { dg-message "originally specified here" "" { target *-*-* } 17 } */
|
||||
@property (getter=x) int f; /* { dg-error ".getter. attribute of property .f. conflicts with previous declaration" } */
|
||||
@property (getter=x) int f; /* { dg-warning ".getter. attribute of property .f. conflicts with previous declaration" } */
|
||||
/* { dg-message "originally specified here" "" { target *-*-* } 18 } */
|
||||
@property (readonly) int g; /* { dg-error ".readonly. attribute of property .g. conflicts with previous declaration" } */
|
||||
@property (readonly) int g; /* { dg-warning ".readonly. attribute of property .g. conflicts with previous declaration" } */
|
||||
/* { dg-message "originally specified here" "" { target *-*-* } 19 } */
|
||||
@property (readwrite) int h; /* Ok */
|
||||
@property (readonly) int i; /* { dg-error ".getter. attribute of property .i. conflicts with previous declaration" } */
|
||||
@property (readonly) int i; /* { dg-warning ".getter. attribute of property .i. conflicts with previous declaration" } */
|
||||
/* { dg-message "originally specified here" "" { target *-*-* } 21 } */
|
||||
@end
|
||||
|
||||
|
@ -26,22 +26,22 @@
|
||||
@end
|
||||
|
||||
@interface MyRootClass (Category)
|
||||
@property (retain) id a; /* { dg-error "assign semantics attributes of property .a. conflict with previous declaration" } */
|
||||
@property (retain) id a; /* { dg-warning "assign semantics attributes of property .a. conflict with previous declaration" } */
|
||||
/* { dg-message "originally specified here" "" { target *-*-* } 16 } */
|
||||
@property (assign) id b; /* { dg-error "assign semantics attributes of property .b. conflict with previous declaration" } */
|
||||
@property (assign) id b; /* { dg-warning "assign semantics attributes of property .b. conflict with previous declaration" } */
|
||||
/* { dg-message "originally specified here" "" { target *-*-* } 17 } */
|
||||
@property (nonatomic) int c; /* { dg-error ".nonatomic. attribute of property .c. conflicts with previous declaration" } */
|
||||
@property (nonatomic) int c; /* { dg-warning ".nonatomic. attribute of property .c. conflicts with previous declaration" } */
|
||||
/* { dg-message "originally specified here" "" { target *-*-* } 18 } */
|
||||
@property int d; /* { dg-error ".nonatomic. attribute of property .d. conflicts with previous declaration" } */
|
||||
@property int d; /* { dg-warning ".nonatomic. attribute of property .d. conflicts with previous declaration" } */
|
||||
/* { dg-message "originally specified here" "" { target *-*-* } 19 } */
|
||||
@property (setter=setX:) int e; /* { dg-error ".setter. attribute of property .e. conflicts with previous declaration" } */
|
||||
@property (setter=setX:) int e; /* { dg-warning ".setter. attribute of property .e. conflicts with previous declaration" } */
|
||||
/* { dg-message "originally specified here" "" { target *-*-* } 20 } */
|
||||
@property (getter=x) int f; /* { dg-error ".getter. attribute of property .f. conflicts with previous declaration" } */
|
||||
@property (getter=x) int f; /* { dg-warning ".getter. attribute of property .f. conflicts with previous declaration" } */
|
||||
/* { dg-message "originally specified here" "" { target *-*-* } 21 } */
|
||||
@property (readonly) int g; /* { dg-error ".readonly. attribute of property .g. conflicts with previous declaration" } */
|
||||
@property (readonly) int g; /* { dg-warning ".readonly. attribute of property .g. conflicts with previous declaration" } */
|
||||
/* { dg-message "originally specified here" "" { target *-*-* } 22 } */
|
||||
@property (readwrite) int h; /* Ok */
|
||||
@property (readonly) int i; /* { dg-error ".getter. attribute of property .i. conflicts with previous declaration" } */
|
||||
@property (readonly) int i; /* { dg-warning ".getter. attribute of property .i. conflicts with previous declaration" } */
|
||||
/* { dg-message "originally specified here" "" { target *-*-* } 24 } */
|
||||
@property (nonatomic) float j; /* Ok */
|
||||
@end
|
||||
|
23
gcc/testsuite/objc.dg/property/at-property-21.m
Normal file
23
gcc/testsuite/objc.dg/property/at-property-21.m
Normal file
@ -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
|
172
gcc/testsuite/objc.dg/property/at-property-22.m
Normal file
172
gcc/testsuite/objc.dg/property/at-property-22.m
Normal file
@ -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;
|
||||
}
|
17
gcc/testsuite/objc.dg/property/at-property-23.m
Normal file
17
gcc/testsuite/objc.dg/property/at-property-23.m
Normal file
@ -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
|
@ -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" } */
|
||||
|
@ -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
|
||||
|
53
gcc/testsuite/objc.dg/property/synthesize-10.m
Normal file
53
gcc/testsuite/objc.dg/property/synthesize-10.m
Normal file
@ -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;
|
||||
}
|
31
gcc/testsuite/objc.dg/property/synthesize-11.m
Normal file
31
gcc/testsuite/objc.dg/property/synthesize-11.m
Normal file
@ -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 } */
|
80
gcc/testsuite/objc.dg/property/synthesize-9.m
Normal file
80
gcc/testsuite/objc.dg/property/synthesize-9.m
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user