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:
Nicola Pero 2010-11-14 11:11:18 +00:00 committed by Nicola Pero
parent 8a7a250d32
commit 8926bd5d5c
28 changed files with 979 additions and 112 deletions

View 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

View 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, "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;

View 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.

View 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

View File

@ -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

View File

@ -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

View 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

View 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;
}

View 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

View 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" } */

View File

@ -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" } */

View 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

View 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

View 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

View 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;
}

View 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 } */

View File

@ -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 } */

View 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

View File

@ -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

View File

@ -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

View 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

View 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;
}

View 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

View 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" } */

View 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

View 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;
}

View 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 } */

View 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