diff options
author | Nicola Pero <nicola.pero@meta-innovation.com> | 2010-10-30 11:22:46 +0000 |
---|---|---|
committer | Nicola Pero <nicola@gcc.gnu.org> | 2010-10-30 11:22:46 +0000 |
commit | 46a88c12210a5677435efa706e424a4e37ab4646 (patch) | |
tree | d24923cb06c7a7884a4a40a2264c96d6ab65b95c /gcc/testsuite/objc.dg/property | |
parent | cc74e2a13cddff984302633cfc644b027ddc476d (diff) | |
download | gcc-46a88c12210a5677435efa706e424a4e37ab4646.zip gcc-46a88c12210a5677435efa706e424a4e37ab4646.tar.gz gcc-46a88c12210a5677435efa706e424a4e37ab4646.tar.bz2 |
In gcc/: 2010-10-30 Nicola Pero <nicola.pero@meta-innovation.com>
In gcc/:
2010-10-30 Nicola Pero <nicola.pero@meta-innovation.com>
Implemented Objective-C 2.0 @property, @synthesize and @dynamic.
* c-parser.c (c_parser_objc_at_property_declaration): Removed
parsing of RID_COPIES and RID_IVAR. Updated call to
objc_add_property_declaration.
* c-typecheck.c (build_component_ref): Call
objc_maybe_build_component_ref instead of objc_build_setter_call.
Use objc_is_property_ref to improve Objective-C checks.
(cp_build_modify_expr): Call objc_maybe_build_modify_expr instead
of objc_build_getter_call.
In gcc/c-family/:
2010-10-30 Nicola Pero <nicola.pero@meta-innovation.com>
Implemented Objective-C 2.0 @property, @synthesize and @dynamic.
* c-common.h (enum rid): Removed RID_COPIES and RID_IVAR.
(objc_add_property_declaration): Removed arguments for copies and
ivar.
(objc_build_getter_call): Renamed to
objc_maybe_build_component_ref.
(objc_build_setter_call): Renamed to objc_maybe_build_modify_expr.
(objc_is_property_ref): New.
* c-common.c (c_common_reswords): Removed copies and ivar.
* stub-objc.c (objc_add_property_declaration): Removed arguments
for copies and ivar.
(objc_build_getter_call): Renamed to
objc_maybe_build_component_ref.
(objc_build_setter_call): Renamed to objc_maybe_build_modify_expr.
(objc_is_property_ref): New.
In gcc/cp/:
2010-10-30 Nicola Pero <nicola.pero@meta-innovation.com>
Implemented Objective-C 2.0 @property, @synthesize and @dynamic.
* parser.c (cp_parser_objc_at_property_declaration): Removed
parsing of RID_COPIES and RID_IVAR. Updated call to
objc_add_property_declaration.
* typecheck.c (finish_class_member_access_expr): Call
objc_maybe_build_component_ref instead of objc_build_setter_call.
(cp_build_modify_expr): Call objc_maybe_build_modify_expr instead
of objc_build_getter_call.
In gcc/objc/:
2010-10-30 Nicola Pero <nicola.pero@meta-innovation.com>
Implemented Objective-C 2.0 @property, @synthesize and @dynamic.
* objc-tree.def (PROPERTY_REF): New.
* objc-act.h: Added comments for all the PROPERTY_ macros.
(PROPERTY_NAME): Use DECL_NAME.
(PROPERTY_COPIES): Removed.
(PROPERTY_READONLY): Use DECL_LANG_FLAG_0 for it.
(PROPERTY_NONATOMIC): New.
(objc_property_assign_semantics): Make it a typedef.
(PROPERTY_ASSIGN_SEMANTICS): New.
(PROPERTY_DYNAMIC): New.
(PROPERTY_REF_OBJECT): New.
(PROPERTY_REF_PROPERTY_DECL): New.
* objc-act.c (CALL_EXPR_OBJC_PROPERTY_GETTER): Removed.
(in_objc_property_setter_name_context): Removed.
(objc_add_property_declaration): Removed copies and ivar arguments
and code supporting them. Fixed recovering when readonly and
setter attributes are specified. Removed support for @property in
@implementation context. Updated error message. Double-check
that a property does not have a DECL_INITIAL. Validate the
property assign semantics and emit appropriate errors and
warnings. Check for duplicate property declarations. Set
DECL_SOURCE_LOCATION, TREE_DEPRECATED, PROPERTY_NONATOMIC,
PROPERTY_ASSIGN_SEMANTICS and PROPERTY_DYNAMIC of the new
PROPERTY_DECL. Do not set PROPERTY_COPIES. Set
PROPERTY_IVAR_NAME to NULL_TREE.
(objc_build_getter_call): Renamed to
objc_maybe_build_component_ref. If the property is not found in
the interface, search in the protocol list. Do not generate the
getter call; instead, build and return a PROPERTY_REF.
(objc_is_property_ref): New.
(objc_setter_func_call): Removed.
(get_selector_from_reference): Removed.
(is_property): Removed.
(objc_build_setter_call): Renamed to objc_maybe_build_modify_expr.
Updated to work on a PROPERTY_REF and use the PROPERTY_DECL from
the PROPERTY_REF. Generate an error if the property is read-only.
(build_property_reference): Removed.
(objc_finish_message_expr): Removed check to produce "readonly
property can not be set" error when
in_objc_property_setter_name_context. We now generate the error
earlier, in objc_maybe_build_modify_expr, which will only generate
the setter call if the property is readwrite.
(check_methods): Recognize dynamic properties.
(check_methods_accessible): Same change.
(objc_build_property_ivar_name): Removed.
(objc_build_property_setter_name): Dropped bool argument. Always
add the ':' at the end.
(objc_gen_one_property_datum): Removed.
(objc_process_getter_setter): Removed.
(objc_synthesize_getter): Mark 'klass' argument as unused. Use
PROPERTY_GETTER_NAME instead of PROPERTY_NAME. Set the
DECL_SOURCE_LOCATION of the new method to be the same as the one
for the @synthesize. Always use PROPERTY_IVAR_NAME as it is
instead of trying to guess what it should be. Removed use of
CLASS_IVARS. Use the location of @synthesize for c_finish_return
and c_end_compound_statement.
(objc_synthesize_setter): Mark 'klass' argument as unused. Use
PROPERTY_SETTER_NAME instead of trying to guess what it should be.
Set the DECL_SOURCE_LOCATION of the new method to be the same as
the one for the @synthesize. Always use PROPERTY_IVAR_NAME as it
is instead of trying to guess what it should be. Removed use of
CLASS_IVARS. Use the location of @synthesize for c_finish_return
and c_end_compound_statement. Emit an error and keep going,
instead of aborting, if the setter prototype does not have the
expected argument.
(objc_add_synthesize_declaration_for_property): New.
(objc_add_synthesize_declaration): Removed ATTRIBUTE_UNUSED from
all arguments. Improved error message. Filled in the rest of the
function, which used to be a placeholder, with an actual
implementation.
(objc_add_dynamic_declaration_for_property): New.
(objc_add_dynamic_declaration): Removed ATTRIBUTE_UNUSED from all
arguments. Improved error message. Filled in the rest of the
function, which used to be a placeholder, with an actual
implementation.
(objc_gen_property_data): Rewritten.
(finish_class): Added explicit switch cases for
CLASS_INTERFACE_TYPE, CATEGORY_INTERFACE_TYPE and
PROTOCOL_INTERFACE_TYPE. Added a default switch case which is
gcc_unreachable. Rewritten the processing of properties, in
particular to not synthesize prototypes for getters and setters if
they already exist and to install the getter and setter names into
PROPERTY_GETTER_NAME and PROPERTY_SETTER_NAME. Do not generate
warnings about setter, getter and ivar property attributes.
(objc_lookup_ivar): Removed support for properties.
(objc_gimplify_property_ref): New.
(objc_gimplify_expr): Use a switch. In case of a PROPERTY_REF, call
objc_gimplify_property_ref.
In gcc/testsuite/:
2010-10-30 Nicola Pero <nicola.pero@meta-innovation.com>
Implemented Objective-C 2.0 @property, @synthesize and @dynamic.
* objc.dg/property/property-neg-1.m: Updated for changes in the
syntax of @property and the implementation of
@synthesize/@dynamic.
* objc.dg/property/property-neg-2.m: Same change.
* objc.dg/property/property-neg-3.m: Same change.
* objc.dg/property/property-neg-4.m: Same change.
* objc.dg/property/property-neg-5.m: Same change.
* objc.dg/property/property-neg-7.m: Same change.
* objc.dg/property/property-1.m: Same change.
* objc.dg/property/synthesize-1.m: Same change.
* objc.dg/property/at-property-2.m: Same change.
* objc.dg/property/at-property-4.m: Same change.
* objc.dg/property/fsf-property-method-acces.m: Updated for
changes in the syntax of @property and the implementation of
@synthesize/@dynamic. Use the same code for GNU and NeXT runtime.
* objc.dg/property/fsf-property-basic.m: Same change.
* objc.dg/property/fsf-property-named-ivar.m: Same change.
* objc.dg/property/at-property-5.m: New.
* objc.dg/property/at-property-6.m: New.
* objc.dg/property/at-property-7.m: New.
* objc.dg/property/at-property-8.m: New.
* objc.dg/property/at-property-9.m: New.
* objc.dg/property/at-property-10.m: New.
* objc.dg/property/at-property-11.m: New.
* objc.dg/property/synthesize-2.m: New.
* objc.dg/property/dynamic-2.m: New.
* obj-c++.dg/property/property-neg-1.mm: Updated for changes in the
syntax of @property and the implementation of
@synthesize/@dynamic.
* obj-c++.dg/property/property-neg-2.mm: Same change.
* obj-c++.dg/property/property-neg-3.mm: Same change.
* obj-c++.dg/property/property-neg-4.mm: Same change.
* obj-c++.dg/property/property-neg-5.mm: Same change.
* obj-c++.dg/property/property-neg-7.mm: Same change.
* obj-c++.dg/property/property-1.mm: Same change.
* obj-c++.dg/property/synthesize-1.mm: Same change.
* obj-c++.dg/property/at-property-2.mm: Same change.
* obj-c++.dg/property/at-property-4.mm: Same change.
* obj-c++.dg/property/fsf-property-method-acces.mm: Updated for
changes in the syntax of @property and the implementation of
@synthesize/@dynamic. Use the same code for GNU and NeXT runtime.
* obj-c++.dg/property/fsf-property-basic.mm: Same change.
* obj-c++.dg/property/fsf-property-named-ivar.mm: Same change.
* obj-c++.dg/property/at-property-5.mm: New.
* obj-c++.dg/property/at-property-6.mm: New.
* obj-c++.dg/property/at-property-7.mm: New.
* obj-c++.dg/property/at-property-8.mm: New.
* obj-c++.dg/property/at-property-9.mm: New.
* obj-c++.dg/property/at-property-10.mm: New.
* obj-c++.dg/property/at-property-11.mm: New.
* obj-c++.dg/property/synthesize-2.mm: New.
* obj-c++.dg/property/dynamic-2.mm: New.
From-SVN: r166087
Diffstat (limited to 'gcc/testsuite/objc.dg/property')
24 files changed, 586 insertions, 111 deletions
diff --git a/gcc/testsuite/objc.dg/property/at-property-10.m b/gcc/testsuite/objc.dg/property/at-property-10.m new file mode 100644 index 0000000..bc6380c --- /dev/null +++ b/gcc/testsuite/objc.dg/property/at-property-10.m @@ -0,0 +1,100 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ +/* { dg-do run } */ + +/* Test the property syntax in a number of expressions. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +@interface MyRootClass +{ + Class isa; + int a; +} +@property int a; ++ (id) initialize; ++ (id) alloc; +- (id) init; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +@synthesize a; +@end + +int +test (int g) +{ + return g; +} + +int main (void) +{ + MyRootClass *object = [[MyRootClass alloc] init]; + MyRootClass *object2 = [[MyRootClass alloc] init]; + + object.a = 14; + object.a = object.a + object.a; + + if (object.a != 28) + abort (); + + object.a = 99; + /* TODO: The following one does not work yet. */ + /* object.a++; */ + object.a = object.a + 1; + + if (object.a != 100) + abort (); + + object.a = 99; + object.a *= 2; + + if (object.a != 198) + abort (); + + { + int f = object.a; + + if (f != 198) + abort (); + + if (f != object.a) + abort (); + + if (object.a != f) + abort (); + + object.a = object.a; + + if (object.a != 198) + abort (); + } + + if (test (object.a) != 198) + abort (); + + object.a = -object.a; + + if (object.a != -198) + abort (); + + /* TODO: The following one does not work yet. */ + /* for (object.a = 0; object.a < 99; object.a++) */ + for (object.a = 0; object.a < 99; object.a = object.a + 1) + object2.a = object.a; + + if (object2.a != object.a - 1) + abort (); + + if (object2.a != 98) + abort (); + + if (object.a != 99) + abort (); + + return 0; +} diff --git a/gcc/testsuite/objc.dg/property/at-property-11.m b/gcc/testsuite/objc.dg/property/at-property-11.m new file mode 100644 index 0000000..84857e0 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/at-property-11.m @@ -0,0 +1,43 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ +/* { dg-do run } */ + +/* Test that properties are found even if implemented in superclasses. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +@interface MyRootClass +{ + Class isa; + int a; +} +@property int a; ++ (id) initialize; ++ (id) alloc; +- (id) init; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +@synthesize a; +@end + +@interface MySubClass : MyRootClass +@end + +@implementation MySubClass +@end + +int main (void) +{ + MySubClass *object = [[MySubClass alloc] init]; + + object.a = 40; + if (object.a != 40) + abort (); + + return 0; +} diff --git a/gcc/testsuite/objc.dg/property/at-property-2.m b/gcc/testsuite/objc.dg/property/at-property-2.m index 23bd485..19d59fd 100644 --- a/gcc/testsuite/objc.dg/property/at-property-2.m +++ b/gcc/testsuite/objc.dg/property/at-property-2.m @@ -6,8 +6,8 @@ { Class isa; } -@property id name __attribute__((deprecated)); -@property id table __attribute__((xxx)); /* { dg-warning ".xxx. attribute directive ignored" } */ +@property int name __attribute__((deprecated)); +@property int table __attribute__((xxx)); /* { dg-warning ".xxx. attribute directive ignored" } */ @property void function (void); /* { dg-error "declared as a function" } */ @property typedef int j; /* { dg-error "expected" } */ @end diff --git a/gcc/testsuite/objc.dg/property/at-property-4.m b/gcc/testsuite/objc.dg/property/at-property-4.m index 05223a3..e327930 100644 --- a/gcc/testsuite/objc.dg/property/at-property-4.m +++ b/gcc/testsuite/objc.dg/property/at-property-4.m @@ -6,36 +6,35 @@ { Class isa; } -- (id) myGetter; -- (id) myGetterB; -- (void) mySetter: (id)property; -- (void) mySetterB: (id)property; +- (int) myGetter; +- (int) myGetterB; +- (int) myGetter2; +- (void) mySetter: (int)property; +- (void) mySetterB: (int)property; +- (void) mySetter2: (int)property; /* Test that all the new property attributes can be parsed. */ @property (assign) id property_a; @property (copy) id property_b; -@property (nonatomic) id property_c; -@property (readonly) id property_d; -@property (readwrite) id property_e; +@property (nonatomic) int property_c; +@property (readonly) int property_d; +@property (readwrite) int property_e; @property (retain) id property_f; -@property (release) id property_g; /* { dg-error "unknown property attribute" } */ +@property (release) int property_g; /* { dg-error "unknown property attribute" } */ -/* The following will be enabled when @synthesized is implemented. */ -/* @property (getter=myGetter) id property_h; */ -/* @property (setter=mySetter:) id property_i; */ +@property (getter=myGetter) int property_h; +@property (setter=mySetter:) int property_i; /* Now test various problems. */ @property (readonly, readwrite) int a; /* { dg-error ".readonly. attribute conflicts with .readwrite. attribute" } */ -/* The following will be enabled when @synthesized is implemented. */ -/* @property (readonly, setter=setA:) int b; */ /* dg-warning ".readonly. attribute conflicts with .setter. attribute" */ +@property (readonly, setter=mySetterB:) int b; /* { dg-warning ".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" } */ @property (copy, retain) id e; /* { dg-error ".retain. attribute conflicts with .copy. attribute" } */ -/* The following will be enabled when @synthesized is implemented. */ -/* @property (setter=mySetter:,setter=mySetterB:) id f; */ /* dg-error ".setter. attribute may only be specified once" */ -/* @property (getter=myGetter:,getter=myGetterB:) id f; */ /* dg-error ".getter. attribute may only be specified once" */ +@property (setter=mySetter:,setter=mySetter2:) int f; /* { dg-error ".setter. attribute may only be specified once" } */ +@property (getter=myGetter, getter=myGetter2 ) int g; /* { dg-error ".getter. attribute may only be specified once" } */ @end diff --git a/gcc/testsuite/objc.dg/property/at-property-5.m b/gcc/testsuite/objc.dg/property/at-property-5.m new file mode 100644 index 0000000..e4abd27 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/at-property-5.m @@ -0,0 +1,34 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ +/* { dg-do compile } */ + +#include <objc/objc.h> + +@interface MyRootClass +{ + Class isa; + id property_a; + int property_b; + int property_c; + int property_d; + id property_e; + id property_f; + id property_g; + id property_h; +} + +/* Test various error messages. */ +@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 int property_b = 4; /* { dg-error "expected" } */ +@property (retain) int property_c; /* { dg-error ".retain. attribute is only valid for Objective-C objects" } */ +@property (copy) int property_d; /* { dg-error ".copy. attribute is only valid for Objective-C objects" } */ + +@property (retain) id property_e; +@property (retain) id property_f; +@property (retain) id property_g; +@property (retain) id property_h; +@property (retain) id property_e; /* { dg-error "redeclaration of property .property_e." } */ + /* { dg-message "originally declared here" "" { target *-*-* } 26 } */ +@end + +@property id test; /* { dg-error "property declaration not in .interface or .protocol context" } */ diff --git a/gcc/testsuite/objc.dg/property/at-property-6.m b/gcc/testsuite/objc.dg/property/at-property-6.m new file mode 100644 index 0000000..a97c0b0 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/at-property-6.m @@ -0,0 +1,60 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ +/* { dg-do run } */ + +/* Test the property syntax with non-synthesized setter/getter + and with standard names. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +@interface MyRootClass +{ + Class isa; + int a; +} +@property int a; ++ (id) initialize; ++ (id) alloc; +- (id) init; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } + +- (int) a +{ + return a; +} +- (void) setA: (int)value +{ + a = value; +} +@end + +int main (void) +{ + MyRootClass *object = [[MyRootClass alloc] init]; + + if (object.a != 0) + abort (); + + object.a = 14; + + if (object.a != 14) + abort (); + + object.a = 23; + + if (object.a != 23) + abort (); + + object.a = 78; + + if (object.a != 78) + abort (); + + return 0; +} diff --git a/gcc/testsuite/objc.dg/property/at-property-7.m b/gcc/testsuite/objc.dg/property/at-property-7.m new file mode 100644 index 0000000..dce2764 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/at-property-7.m @@ -0,0 +1,57 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ +/* { dg-do run } */ + +/* Test the property syntax with non-synthesized setter/getter + and with a non-standard name for the getter. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +@interface MyRootClass +{ + Class isa; + int a; +} +@property (getter = getA) int a; ++ (id) initialize; ++ (id) alloc; +- (id) init; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } + +- (int) getA +{ + return a; +} +- (void) setA: (int)value +{ + a = value; +} +@end + +int main (void) +{ + MyRootClass *object = [[MyRootClass alloc] init]; + + object.a = 14; + + if (object.a != 14) + abort (); + + object.a = 23; + + if (object.a != 23) + abort (); + + object.a = 78; + + if (object.a != 78) + abort (); + + return 0; +} diff --git a/gcc/testsuite/objc.dg/property/at-property-8.m b/gcc/testsuite/objc.dg/property/at-property-8.m new file mode 100644 index 0000000..eb15889 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/at-property-8.m @@ -0,0 +1,57 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ +/* { dg-do run } */ + +/* Test the property syntax with non-synthesized setter/getter + and with a non-standard name for the setter. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +@interface MyRootClass +{ + Class isa; + int a; +} +@property (setter = writeA:) int a; ++ (id) initialize; ++ (id) alloc; +- (id) init; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } + +- (int) a +{ + return a; +} +- (void) writeA: (int)value +{ + a = value; +} +@end + +int main (void) +{ + MyRootClass *object = [[MyRootClass alloc] init]; + + object.a = 14; + + if (object.a != 14) + abort (); + + object.a = 23; + + if (object.a != 23) + abort (); + + object.a = 78; + + if (object.a != 78) + abort (); + + return 0; +} diff --git a/gcc/testsuite/objc.dg/property/at-property-9.m b/gcc/testsuite/objc.dg/property/at-property-9.m new file mode 100644 index 0000000..203eb30 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/at-property-9.m @@ -0,0 +1,49 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ +/* { dg-do run } */ + +/* Test the property syntax with synthesized setter/getter + and with a non-standard name for the getter and setter. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +@interface MyRootClass +{ + Class isa; + int a; +} +@property (getter = giveMeA, setter = writeA:) int a; ++ (id) initialize; ++ (id) alloc; +- (id) init; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +@synthesize a; +@end + +int main (void) +{ + MyRootClass *object = [[MyRootClass alloc] init]; + + object.a = 14; + + if (object.a != 14) + abort (); + + object.a = 23; + + if (object.a != 23) + abort (); + + object.a = 78; + + if (object.a != 78) + abort (); + + return 0; +} diff --git a/gcc/testsuite/objc.dg/property/dynamic-1.m b/gcc/testsuite/objc.dg/property/dynamic-1.m index b91a030..8f97371 100644 --- a/gcc/testsuite/objc.dg/property/dynamic-1.m +++ b/gcc/testsuite/objc.dg/property/dynamic-1.m @@ -20,11 +20,15 @@ int v3; int v4; } +@property int v1; +@property int v2; +@property int v3; +@property int v4; @end @implementation Test @dynamic; /* { dg-error "expected identifier" } */ @dynamic v1, ; /* { dg-error "expected identifier" } */ -@dynamic v1, v2, v3; /* { dg-error ".@dynamic. is not supported in this version of the compiler" } */ -@dynamic v4; /* { dg-error ".@dynamic. is not supported in this version of the compiler" } */ +@dynamic v1, v2, v3; +@dynamic v4; @end diff --git a/gcc/testsuite/objc.dg/property/dynamic-2.m b/gcc/testsuite/objc.dg/property/dynamic-2.m new file mode 100644 index 0000000..313d8dc --- /dev/null +++ b/gcc/testsuite/objc.dg/property/dynamic-2.m @@ -0,0 +1,44 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ +/* { dg-do compile } */ + +#include <objc/objc.h> + +@interface MyRootClass +{ + Class isa; +} +@end + +@implementation MyRootClass +@end + +@dynamic isa; /* { dg-error ".@dynamic. not in @implementation context" } */ + +@interface Test : MyRootClass +{ + int v1; +} +@end +@implementation Test +@end + + +@interface Test (Category) +@end +@implementation Test (Category) +@dynamic v1; /* { dg-error ".@dynamic. can not be used in categories" } */ +@end + + +@interface AnotherTest : MyRootClass +{ +} +@property int one; +@end + +@implementation AnotherTest +@dynamic one; +@dynamic one; /* { dg-error "property .one. already specified in .@dynamic." } */ + /* { dg-message "originally specified here" "" { target *-*-* } 40 } */ +@dynamic three; /* { dg-error "no declaration of property .three. found in the interface" } */ +@end diff --git a/gcc/testsuite/objc.dg/property/fsf-property-basic.m b/gcc/testsuite/objc.dg/property/fsf-property-basic.m index 13a00a2..20fd978 100644 --- a/gcc/testsuite/objc.dg/property/fsf-property-basic.m +++ b/gcc/testsuite/objc.dg/property/fsf-property-basic.m @@ -1,47 +1,34 @@ /* Basic test, auto-generated getter/setter based on property name. */ /* { dg-do run } */ -/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ extern int printf (char *fmt,...) ; extern void abort (void); -typedef struct objc_class *Class; - -#ifdef __NEXT_RUNTIME__ - -extern id class_createInstance(Class, long); -#define class_create_instance(C) class_createInstance(C, 0) - -#else - -extern id class_create_instance(Class); - -#endif +#include <objc/objc.h> +#include <objc/runtime.h> @interface Bar { @public -#ifdef __NEXT_RUNTIME__ Class isa; -#else - Class class_pointer; -#endif + int FooBar; } + (id) initialize; + (id) alloc ; - (id) init; - +- (int) whatIsFooBar; @property int FooBar; @end @implementation Bar +initialize { return self;} -+ (id) alloc { return class_create_instance(self);} ++ (id) alloc { return class_createInstance (self, 0); } - (id) init {return self;} -@property int FooBar ; +- (int) whatIsFooBar { return self->FooBar; } +@synthesize FooBar; @end int main(int argc, char *argv[]) { @@ -52,15 +39,15 @@ int main(int argc, char *argv[]) { and operate correctly. */ [f setFooBar:1]; - if (f->_FooBar != 1) - { printf ("setFooBar did not set _FooBar\n"); abort ();} + if ([f whatIsFooBar] != 1) + { printf ("setFooBar did not set FooBar\n"); abort ();} res = [f FooBar]; if (res != 1 ) { printf ("[f FooBar] = %d\n", res); abort ();} - /* Now check the short-cut CLASS.property syntax. */ + /* Now check the short-cut object.property syntax. */ /* Read... */ res = f.FooBar; if (res != 1 ) diff --git a/gcc/testsuite/objc.dg/property/fsf-property-method-access.m b/gcc/testsuite/objc.dg/property/fsf-property-method-access.m index fae4969..866f522 100644 --- a/gcc/testsuite/objc.dg/property/fsf-property-method-access.m +++ b/gcc/testsuite/objc.dg/property/fsf-property-method-access.m @@ -1,31 +1,17 @@ /* test access in methods, auto-generated getter/setter based on property name. */ /* { dg-do run } */ -/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ extern int printf (char *fmt,...) ; extern void abort (void); -typedef struct objc_class *Class; - -#ifdef __NEXT_RUNTIME__ - -extern id class_createInstance(Class, long); -#define class_create_instance(C) class_createInstance(C, 0) - -#else - -extern id class_create_instance(Class); - -#endif +#include <objc/objc.h> +#include <objc/runtime.h> @interface Bar { @public -#ifdef __NEXT_RUNTIME__ Class isa; -#else - Class class_pointer; -#endif + int FooBar; } + (id) initialize; + (id) alloc ; @@ -40,11 +26,11 @@ extern id class_create_instance(Class); @implementation Bar +initialize { return self;} -+ (id) alloc { return class_create_instance(self);} ++ (id) alloc { return class_createInstance(self, 0);} - (id) init {return self;} -@property int FooBar; +@synthesize FooBar; - (int) lookAtProperty { return FooBar; } - (void) setProperty: (int) v { FooBar = v; } @@ -59,8 +45,8 @@ int main(int argc, char *argv[]) { and operate correctly. */ [f setProperty:11]; - if (f->_FooBar != 11) - { printf ("setProperty did not set _FooBar\n"); abort ();} + if (f.FooBar != 11) + { printf ("setProperty did not set FooBar\n"); abort ();} res = [f lookAtProperty]; if (res != 11 ) diff --git a/gcc/testsuite/objc.dg/property/fsf-property-named-ivar.m b/gcc/testsuite/objc.dg/property/fsf-property-named-ivar.m index 837d303..3e0b529 100644 --- a/gcc/testsuite/objc.dg/property/fsf-property-named-ivar.m +++ b/gcc/testsuite/objc.dg/property/fsf-property-named-ivar.m @@ -1,31 +1,16 @@ /* Basic test, auto-generated getter/setter based on named ivar */ /* { dg-do run } */ -/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ extern int printf (char *fmt,...) ; extern void abort (void); -typedef struct objc_class *Class; - -#ifdef __NEXT_RUNTIME__ - -extern id class_createInstance(Class, long); -#define class_create_instance(C) class_createInstance(C, 0) - -#else - -extern id class_create_instance(Class); - -#endif +#include <objc/objc.h> +#include <objc/runtime.h> @interface Bar { @public -#ifdef __NEXT_RUNTIME__ Class isa; -#else - Class class_pointer; -#endif int var; } + (id) initialize; @@ -38,11 +23,11 @@ extern id class_create_instance(Class); @implementation Bar +initialize { return self;} -+ (id) alloc { return class_create_instance(self);} ++ (id) alloc { return class_createInstance (self, 0); } - (id) init {return self;} -@property (ivar = var) int FooBar ; +@synthesize FooBar = var; @end int main(int argc, char *argv[]) { @@ -61,7 +46,7 @@ int main(int argc, char *argv[]) { if (res != 1234 ) { printf ("[f FooBar] = %d\n", res); abort ();} - /* Now check the short-cut CLASS.property syntax. */ + /* Now check the short-cut object.property syntax. */ /* Read .... */ res = f.FooBar; if (res != 1234 ) diff --git a/gcc/testsuite/objc.dg/property/property-1.m b/gcc/testsuite/objc.dg/property/property-1.m index 89537ca..fbc181eb 100644 --- a/gcc/testsuite/objc.dg/property/property-1.m +++ b/gcc/testsuite/objc.dg/property/property-1.m @@ -1,7 +1,6 @@ /* This program tests use of property provided setter/getter functions. */ /* { dg-options "-std=c99" } */ /* { dg-do run } */ -/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ /* { dg-additional-sources "../../objc-obj-c++-shared/Object1.m" } */ #import "../../objc-obj-c++-shared/Object1.h" @@ -10,11 +9,11 @@ { int iVar; } -@property int FooBar; +@property (setter=MySetter:) int FooBar; @end @implementation Bar -@property (ivar = iVar, setter = MySetter:) int FooBar; +@synthesize FooBar=iVar; - (void) MySetter : (int) value { iVar = value; } diff --git a/gcc/testsuite/objc.dg/property/property-2.m b/gcc/testsuite/objc.dg/property/property-2.m index 2a923e0..c14d759 100644 --- a/gcc/testsuite/objc.dg/property/property-2.m +++ b/gcc/testsuite/objc.dg/property/property-2.m @@ -7,6 +7,8 @@ /* Force ABI = 0 in the NeXT headers, also suppress deprecation warnings. */ /* { dg-options "-framework Foundation -fobjc-exceptions -mmacosx-version-min=10.4 -Wno-deprecated-declarations" } */ +/* FIXME: There is no reason to use NSString in this file. */ + #include <objc/objc-api.h> #include <Foundation/Foundation.h> diff --git a/gcc/testsuite/objc.dg/property/property-neg-1.m b/gcc/testsuite/objc.dg/property/property-neg-1.m index ffb8253..cae1a56 100644 --- a/gcc/testsuite/objc.dg/property/property-neg-1.m +++ b/gcc/testsuite/objc.dg/property/property-neg-1.m @@ -1,14 +1,13 @@ -/* This program checks for proper use of 'readonly' attribute. */ /* { dg-do compile } */ @interface Bar { int iVar; } -@property (readonly) int FooBar; +@property int fooBar; @end @implementation Bar -@property int FooBar; /* { dg-error "property 'FooBar' 'readonly' attribute conflicts with its interface version" } */ - -@end +@end /* { dg-warning "incomplete implementation of class .Bar." } */ + /* { dg-warning "method definition for .-setFooBar:. not found" "" { target *-*-* } 11 } */ + /* { dg-warning "method definition for .-fooBar. not found" "" { target *-*-* } 11 } */ diff --git a/gcc/testsuite/objc.dg/property/property-neg-2.m b/gcc/testsuite/objc.dg/property/property-neg-2.m index 7046da8..f730fe8 100644 --- a/gcc/testsuite/objc.dg/property/property-neg-2.m +++ b/gcc/testsuite/objc.dg/property/property-neg-2.m @@ -1,9 +1,8 @@ -/* This program checks for proper declaration of property. */ /* { dg-do compile } */ @interface Bar @end @implementation Bar -@property int foo; /* { dg-error "no declaration of property 'foo' found in the interface" } */ +@property int FooBar; /* { dg-error "property declaration not in @interface or @protocol context" } */ @end diff --git a/gcc/testsuite/objc.dg/property/property-neg-3.m b/gcc/testsuite/objc.dg/property/property-neg-3.m index 5b48044..0b30931 100644 --- a/gcc/testsuite/objc.dg/property/property-neg-3.m +++ b/gcc/testsuite/objc.dg/property/property-neg-3.m @@ -1,14 +1,14 @@ -/* Property name cannot match the ivar name. */ /* { dg-do compile } */ -/* Suppress warnings for incomplete class definition etc. */ -/* { dg-options "-w" } */ @interface Person { char *firstName; } -@property char *firstName; /* { dg-error "property 'firstName' may not have the same name as an ivar in the class" } */ +@property char *firstName; @end @implementation Person +@dynamic firstName; +@synthesize firstName; /* { dg-error "property .firstName. already specified in .@dynamic." } */ + /* { dg-message "originally specified here" "" { target *-*-* } 11 } */ @end diff --git a/gcc/testsuite/objc.dg/property/property-neg-4.m b/gcc/testsuite/objc.dg/property/property-neg-4.m index 960c6d6..cc25d84 100644 --- a/gcc/testsuite/objc.dg/property/property-neg-4.m +++ b/gcc/testsuite/objc.dg/property/property-neg-4.m @@ -1,17 +1,17 @@ -/* Property cannot be accessed in class method. */ /* { dg-do compile } */ @interface Person { + char *fullName; } @property char *fullName; + (void) testClass; @end + @implementation Person -@property char *fullName; +@synthesize fullName; + (void) testClass { - fullName = "MyName"; /* { dg-error "property 'fullName' accessed in class method" } */ + self.fullName = "MyName"; /* { dg-error "request for member .fullName." } */ } @end - diff --git a/gcc/testsuite/objc.dg/property/property-neg-5.m b/gcc/testsuite/objc.dg/property/property-neg-5.m index 7a9090a..403f684 100644 --- a/gcc/testsuite/objc.dg/property/property-neg-5.m +++ b/gcc/testsuite/objc.dg/property/property-neg-5.m @@ -1,7 +1,5 @@ -/* getter/setter cannot be specified in an interface. */ /* { dg-do compile } */ @interface Foo @property ( readonly, getter = HELLO, setter = THERE : ) int value; /* { dg-warning ".readonly. attribute conflicts with .setter. attribute" } */ -@end /* { dg-warning "getter = \\'HELLO\\' may not be specified in an interface" } */ - /* { dg-warning "setter = \\'THERE\\:\\' may not be specified in an interface" "" { target *-*-* } 6 } */ +@end diff --git a/gcc/testsuite/objc.dg/property/property-neg-7.m b/gcc/testsuite/objc.dg/property/property-neg-7.m index 506f097..4c3d5d7 100644 --- a/gcc/testsuite/objc.dg/property/property-neg-7.m +++ b/gcc/testsuite/objc.dg/property/property-neg-7.m @@ -1,13 +1,14 @@ -/* Cannot write into a read-only property. */ /* { dg-do compile } */ -/* Suppress warnings for incomplete class definition etc. */ -/* { dg-options "-w" } */ @interface NSArray +{ + int count; +} @property(readonly) int count; @end @implementation NSArray +@synthesize count; @end void foo (NSArray *ans[], id pid, id apid[], int i) { diff --git a/gcc/testsuite/objc.dg/property/synthesize-1.m b/gcc/testsuite/objc.dg/property/synthesize-1.m index 09085d8..fbc8e03 100644 --- a/gcc/testsuite/objc.dg/property/synthesize-1.m +++ b/gcc/testsuite/objc.dg/property/synthesize-1.m @@ -19,13 +19,35 @@ int v2; int v3; int v4; + int v5; + int v6; + int v7; + int v8; } +@property int v1; +@property int v2; +@property int v3; +@property int v4; +@property int v5; +@property int v6; +@property int v7; +@property int v8; @end @implementation Test @synthesize; /* { dg-error "expected identifier" } */ @synthesize v1, ; /* { dg-error "expected identifier" } */ -@synthesize v1, v2 = ; /* { dg-error "expected identifier" } */ -@synthesize v1, v2=v2, v3 = v3,v4; /* { dg-error ".@synthesize. is not supported in this version of the compiler" } */ -@synthesize v4; /* { dg-error ".@synthesize. is not supported in this version of the compiler" } */ +@synthesize v2, v3 = ; /* { dg-error "expected identifier" } */ +@synthesize v4, v5=v6, v6 = v5,v7; +@synthesize v8; +/* Some of the @synthesize above will fail due to syntax errors. The + compiler will then complain that the methods implementing the + properties are missing. That is correct, but we are not + interested. The following ones shut up the compiler. */ +- (int) v1 { return v1; } +- (void) setV1: (int)a { v1 = a; } +- (int) v2 { return v2; } +- (void) setV2: (int)a { v2 = a; } +- (int) v3 { return v3; } +- (void) setV3: (int)a { v3 = a; } @end diff --git a/gcc/testsuite/objc.dg/property/synthesize-2.m b/gcc/testsuite/objc.dg/property/synthesize-2.m new file mode 100644 index 0000000..4bc3e3c --- /dev/null +++ b/gcc/testsuite/objc.dg/property/synthesize-2.m @@ -0,0 +1,50 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ +/* { dg-do run } */ + +#include <objc/objc.h> +#include <objc/runtime.h> +#include <stdlib.h> + +@interface MyRootClass +{ + Class isa; +} ++ (id) initialize; ++ (id) alloc; +- (id) init; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +@end + +@interface Test : MyRootClass +{ + int v1; +} +@property int v1; +/* TODO: Test more types of properties with different semantics + (retain, copy, atomic, nonatomic, and test various C and + Objective-C types). */ +@end + +@implementation Test +@synthesize v1; +@end + +int main (void) +{ + Test *object = [[Test alloc] init]; + + /* Check that the synthesized methods exist and work. Do not invoke + them via property syntax - that is another test. Here we just + want to test the synthesis of the methods. */ + [object setV1: 400]; + + if ([object v1] != 400) + abort (); + + return 0; +} |