diff options
-rw-r--r-- | gcc/c-family/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-family/c-objc.h | 2 | ||||
-rw-r--r-- | gcc/objc/ChangeLog | 22 | ||||
-rw-r--r-- | gcc/objc/objc-act.c | 78 | ||||
-rw-r--r-- | gcc/objc/objc-act.h | 5 | ||||
-rw-r--r-- | gcc/objc/objc-tree.def | 10 | ||||
-rw-r--r-- | gcc/objcp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/objcp/objcp-lang.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/property/at-property-deprecated-1.mm | 4 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/property/at-property-deprecated-2.mm | 25 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/property/dotsyntax-deprecated-1.mm | 41 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/at-property-deprecated-1.m | 4 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/at-property-deprecated-2.m | 25 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/dotsyntax-deprecated-1.m | 41 |
15 files changed, 246 insertions, 34 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index defca77..bf0bc76 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2010-12-29 Nicola Pero <nicola@nicola.brainstorm.co.uk> + + PR objc/47075 + * c-objc.h (objc_finish_message_expr): Added argument to + prototype. + 2010-12-22 Nathan Froyd <froydnj@codesourcery.com> * c-common.c (handle_nonnull_attribute, handle_sentinel_attribute): diff --git a/gcc/c-family/c-objc.h b/gcc/c-family/c-objc.h index afe7fcc..e67eede 100644 --- a/gcc/c-family/c-objc.h +++ b/gcc/c-family/c-objc.h @@ -54,7 +54,7 @@ extern void objc_declare_alias (tree, tree); extern void objc_declare_class (tree); extern void objc_declare_protocols (tree, tree); extern tree objc_build_message_expr (tree); -extern tree objc_finish_message_expr (tree, tree, tree); +extern tree objc_finish_message_expr (tree, tree, tree, tree*); extern tree objc_build_selector_expr (location_t, tree); extern tree objc_build_protocol_expr (tree); extern tree objc_build_encode_expr (tree); diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 34f3478..d5da4ce 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,25 @@ +2010-12-29 Nicola Pero <nicola.pero@meta-innovation.com> + + PR objc/47075 + * objc-act.h (PROPERTY_REF_DEPRECATED_GETTER): New. + * objc-tree.def (PROPERTY_REF): Increased the number of operands + from 3 to 4. + * objc-act.c (objc_finish_message_expr): Added optional argument + allowing to return the deprecated method prototype for deprecated + methods, instead of immediately emitting the deprecation warning. + (objc_maybe_build_component_ref): Do not warn for a deprecated + property. When building the getter call, get the deprecated + method prototype from objc_finish_message_expr() and put it into + the PROPERTY_REF. + (objc_build_class_component_ref): Same change. + (finish_class): Mark the getter and setter as deprecated if they + are generated from a deprecated property. + (objc_gimplify_property_ref): If the getter is deprecated, emit a + deprecation warning. + (objc_build_setter_call, objc_build_message_expr, + objc_finish_foreach_loop): Updated call to + objc_finish_message_expr. + 2010-12-28 Nicola Pero <nicola.pero@meta-innovation.com> PR objc/47076 diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index c7fd4a9..57f0460 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -1468,7 +1468,7 @@ maybe_make_artificial_property_decl (tree interface, tree implementation, DECL_SOURCE_LOCATION (property_decl) = input_location; TREE_DEPRECATED (property_decl) = 0; DECL_ARTIFICIAL (property_decl) = 1; - + /* Add property-specific information. Note that one of PROPERTY_GETTER_NAME or PROPERTY_SETTER_NAME may refer to a non-existing method; this will generate an error when the @@ -1743,6 +1743,7 @@ objc_maybe_build_component_ref (tree object, tree property_ident) { tree expression; tree getter_call; + tree deprecated_method_prototype = NULL_TREE; /* We have an additional nasty problem here; if this PROPERTY_REF needs to become a 'getter', then the conversion @@ -1770,14 +1771,16 @@ objc_maybe_build_component_ref (tree object, tree property_ident) if (PROPERTY_HAS_NO_GETTER (x)) getter_call = NULL_TREE; else - getter_call = objc_finish_message_expr (object, - PROPERTY_GETTER_NAME (x), - NULL_TREE); - - if (TREE_DEPRECATED (x)) - warn_deprecated_use (x, NULL_TREE); - - expression = build3 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call); + getter_call = objc_finish_message_expr + (object, PROPERTY_GETTER_NAME (x), NULL_TREE, + /* Disable the immediate deprecation warning if the getter + is deprecated, but record the fact that the getter is + deprecated by setting PROPERTY_REF_DEPRECATED_GETTER to + the method prototype. */ + &deprecated_method_prototype); + + expression = build4 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call, + deprecated_method_prototype); SET_EXPR_LOCATION (expression, input_location); TREE_SIDE_EFFECTS (expression) = 1; @@ -1839,17 +1842,17 @@ objc_build_class_component_ref (tree class_name, tree property_ident) { tree expression; tree getter_call; + tree deprecated_method_prototype = NULL_TREE; if (PROPERTY_HAS_NO_GETTER (x)) getter_call = NULL_TREE; else - getter_call = objc_finish_message_expr (object, - PROPERTY_GETTER_NAME (x), - NULL_TREE); - if (TREE_DEPRECATED (x)) - warn_deprecated_use (x, NULL_TREE); + getter_call = objc_finish_message_expr + (object, PROPERTY_GETTER_NAME (x), NULL_TREE, + &deprecated_method_prototype); - expression = build3 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call); + expression = build4 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call, + deprecated_method_prototype); SET_EXPR_LOCATION (expression, input_location); TREE_SIDE_EFFECTS (expression) = 1; @@ -1906,7 +1909,7 @@ objc_build_setter_call (tree lhs, tree rhs) /* TODO: Decay arguments in C. */ setter = objc_finish_message_expr (object_expr, PROPERTY_SETTER_NAME (property_decl), - setter_argument); + setter_argument, NULL); return setter; } @@ -8029,7 +8032,7 @@ objc_build_message_expr (tree mess) method_params); #endif - return objc_finish_message_expr (receiver, sel_name, method_params); + return objc_finish_message_expr (receiver, sel_name, method_params, NULL); } /* Look up method SEL_NAME that would be suitable for receiver @@ -8058,10 +8061,20 @@ lookup_method_in_hash_lists (tree sel_name, int is_class) /* The 'objc_finish_message_expr' routine is called from within 'objc_build_message_expr' for non-template functions. In the case of C++ template functions, it is called from 'build_expr_from_tree' - (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */ - + (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. + + If the DEPRECATED_METHOD_PROTOTYPE argument is NULL, then we warn + if the method being used is deprecated. If it is not NULL, instead + of deprecating, we set *DEPRECATED_METHOD_PROTOTYPE to the method + prototype that was used and is deprecated. This is useful for + getter calls that are always generated when compiling dot-syntax + expressions, even if they may not be used. In that case, we don't + want the warning immediately; we produce it (if needed) at gimplify + stage when we are sure that the deprecated getter is being + used. */ tree -objc_finish_message_expr (tree receiver, tree sel_name, tree method_params) +objc_finish_message_expr (tree receiver, tree sel_name, tree method_params, + tree *deprecated_method_prototype) { tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype; tree selector, retval, class_tree; @@ -8278,7 +8291,12 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params) is often used precisely to turn off warnings associated with the object being of a particular class. */ if (TREE_DEPRECATED (method_prototype) && rtype != NULL_TREE) - warn_deprecated_use (method_prototype, NULL_TREE); + { + if (deprecated_method_prototype) + *deprecated_method_prototype = method_prototype; + else + warn_deprecated_use (method_prototype, NULL_TREE); + } } @@ -10743,6 +10761,7 @@ finish_class (tree klass) objc_add_method (objc_interface_context, getter_decl, false, true); else objc_add_method (objc_interface_context, getter_decl, false, false); + TREE_DEPRECATED (getter_decl) = TREE_DEPRECATED (x); METHOD_PROPERTY_CONTEXT (getter_decl) = x; } @@ -10786,6 +10805,7 @@ finish_class (tree klass) objc_add_method (objc_interface_context, setter_decl, false, true); else objc_add_method (objc_interface_context, setter_decl, false, false); + TREE_DEPRECATED (setter_decl) = TREE_DEPRECATED (x); METHOD_PROPERTY_CONTEXT (setter_decl) = x; } } @@ -13118,6 +13138,14 @@ objc_gimplify_property_ref (tree *expr_p) return; } + if (PROPERTY_REF_DEPRECATED_GETTER (*expr_p)) + { + /* PROPERTY_REF_DEPRECATED_GETTER contains the method prototype + that is deprecated. */ + warn_deprecated_use (PROPERTY_REF_DEPRECATED_GETTER (*expr_p), + NULL_TREE); + } + call_exp = getter; #ifdef OBJCPLUS /* In C++, a getter which returns an aggregate value results in a @@ -13511,7 +13539,7 @@ objc_finish_foreach_loop (location_t location, tree object_expression, tree coll tree_cons /* __objc_foreach_items */ (NULL_TREE, objc_foreach_items_decl, tree_cons /* 16 */ - (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE)))); + (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))), NULL); #else /* In C, we need to decay the __objc_foreach_items array that we are passing. */ { @@ -13524,7 +13552,7 @@ objc_finish_foreach_loop (location_t location, tree object_expression, tree coll tree_cons /* __objc_foreach_items */ (NULL_TREE, default_function_array_conversion (location, array).value, tree_cons /* 16 */ - (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE)))); + (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))), NULL); } #endif t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl, @@ -13685,7 +13713,7 @@ objc_finish_foreach_loop (location_t location, tree object_expression, tree coll tree_cons /* __objc_foreach_items */ (NULL_TREE, objc_foreach_items_decl, tree_cons /* 16 */ - (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE)))); + (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))), NULL); #else /* In C, we need to decay the __objc_foreach_items array that we are passing. */ { @@ -13698,7 +13726,7 @@ objc_finish_foreach_loop (location_t location, tree object_expression, tree coll tree_cons /* __objc_foreach_items */ (NULL_TREE, default_function_array_conversion (location, array).value, tree_cons /* 16 */ - (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE)))); + (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))), NULL); } #endif t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl, diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h index 7e8e418..4d023e8 100644 --- a/gcc/objc/objc-act.h +++ b/gcc/objc/objc-act.h @@ -144,6 +144,11 @@ typedef enum objc_property_assign_semantics { use it. */ #define PROPERTY_REF_GETTER_CALL(NODE) TREE_OPERAND (PROPERTY_REF_CHECK (NODE), 2) +/* PROPERTY_REF_DEPRECATED_GETTER is normally set to NULL_TREE. If + the property getter is deprecated, it is set to the method + prototype for it, which is used to generate the deprecation warning + when the getter is used. */ +#define PROPERTY_REF_DEPRECATED_GETTER(NODE) TREE_OPERAND (PROPERTY_REF_CHECK (NODE), 3) /* CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE, CATEGORY_INTERFACE_TYPE, CATEGORY_IMPLEMENTATION_TYPE, diff --git a/gcc/objc/objc-tree.def b/gcc/objc/objc-tree.def index e33fc78..f72f233 100644 --- a/gcc/objc/objc-tree.def +++ b/gcc/objc/objc-tree.def @@ -46,7 +46,10 @@ DEFTREECODE (CLASS_REFERENCE_EXPR, "class_reference_expr", tcc_expression, 1) representing the expression), and Operand 1 is the property (the PROPERTY_DECL). Operand 2 is the 'getter' call, ready to be used; we pregenerate it because it is hard to generate it properly later - on. A PROPERTY_REF tree needs to be transformed into 'setter' and + on. Operand 3 records whether using the 'getter' call should + generate a deprecation warning or not. + + A PROPERTY_REF tree needs to be transformed into 'setter' and 'getter' calls at some point; at the moment this happens in two places: @@ -58,13 +61,14 @@ DEFTREECODE (CLASS_REFERENCE_EXPR, "class_reference_expr", tcc_expression, 1) gimplification; at that point, we convert each PROPERTY_REF into a 'getter' call during ObjC/ObjC++ gimplify. At that point, it is quite hard to build a 'getter' call, but we have already built - it and we just need to swap Operand 2 in. + it and we just need to swap Operand 2 in, and emit the deprecation + warnings from Operand 3 if needed. Please note that when the Objective-C 2.0 "dot-syntax" 'object.component' is encountered, where 'component' is not a property but there are valid setter/getter methods for it, an artificial PROPERTY_DECL is generated and used in the PROPERTY_REF. */ -DEFTREECODE (PROPERTY_REF, "property_ref", tcc_expression, 3) +DEFTREECODE (PROPERTY_REF, "property_ref", tcc_expression, 4) /* Local variables: diff --git a/gcc/objcp/ChangeLog b/gcc/objcp/ChangeLog index 8295ad4..70c71e9 100644 --- a/gcc/objcp/ChangeLog +++ b/gcc/objcp/ChangeLog @@ -1,3 +1,8 @@ +2010-12-29 Nicola Pero <nicola.pero@meta-innovation.com> + + * objcp-lang.c (objcp_tsubst_copy_and_build): Update call to + objc_finish_message_expr. + 2010-12-26 Nicola Pero <nicola.pero@meta-innovation.com> * config-lang.in (gtfiles): Added c-family/c-cppbuiltin.c. diff --git a/gcc/objcp/objcp-lang.c b/gcc/objcp/objcp-lang.c index c0a13b4..008697d 100644 --- a/gcc/objcp/objcp-lang.c +++ b/gcc/objcp/objcp-lang.c @@ -76,7 +76,7 @@ objcp_tsubst_copy_and_build (tree t, tree args, tsubst_flags_t complain, return objc_finish_message_expr (RECURSE (TREE_OPERAND (t, 0)), TREE_OPERAND (t, 1), /* No need to expand the selector. */ - RECURSE (TREE_OPERAND (t, 2))); + RECURSE (TREE_OPERAND (t, 2)), NULL); case CLASS_REFERENCE_EXPR: return objc_get_class_reference diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 514dae3..695685c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2010-12-29 Nicola Pero <nicola.pero@meta-innovation.com> + + PR objc/47075 + * objc.dg/property/at-property-deprecated-1.m: Updated. + * objc.dg/property/at-property-deprecated-2.m: New. + * objc.dg/property/dotsyntax-deprecated-1.m: New. + * obj-c++.dg/property/at-property-deprecated-1.mm: Updated. + * obj-c++.dg/property/at-property-deprecated-2.mm: New. + * obj-c++.dg/property/dotsyntax-deprecated-1.mm: New. + 2010-12-28 Jason Merrill <jason@redhat.com> PR c++/47068 diff --git a/gcc/testsuite/obj-c++.dg/property/at-property-deprecated-1.mm b/gcc/testsuite/obj-c++.dg/property/at-property-deprecated-1.mm index 1bcb288..2cf4dee 100644 --- a/gcc/testsuite/obj-c++.dg/property/at-property-deprecated-1.mm +++ b/gcc/testsuite/obj-c++.dg/property/at-property-deprecated-1.mm @@ -29,8 +29,8 @@ int main (void) { MyRootClass *object = [[MyRootClass alloc] init]; - object.a = 40; /* { dg-warning ".a. is deprecated .declared at " } */ - if (object.a != 40) /* { dg-warning ".a. is deprecated .declared at " } */ + object.a = 40; /* { dg-warning "is deprecated" } */ + if (object.a != 40) /* { dg-warning "is deprecated" } */ abort (); return (0); diff --git a/gcc/testsuite/obj-c++.dg/property/at-property-deprecated-2.mm b/gcc/testsuite/obj-c++.dg/property/at-property-deprecated-2.mm new file mode 100644 index 0000000..d2901a5 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/at-property-deprecated-2.mm @@ -0,0 +1,25 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ +/* { dg-do compile } */ + +/* Test that deprecation warnings are produced when a setter/getter of + a @property is used directly. */ + +#include <objc/objc.h> + +@interface MyClass +{ + Class isa; + int variable; +} +@property (assign, nonatomic) int property __attribute__ ((deprecated)); +@end + +void foo (void) +{ + MyClass *object = nil; + + if ([object property] > 0) /* { dg-warning "is deprecated" } */ + { + [object setProperty: 43]; /* { dg-warning "is deprecated" } */ + } +} diff --git a/gcc/testsuite/obj-c++.dg/property/dotsyntax-deprecated-1.mm b/gcc/testsuite/obj-c++.dg/property/dotsyntax-deprecated-1.mm new file mode 100644 index 0000000..ad627a8 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/dotsyntax-deprecated-1.mm @@ -0,0 +1,41 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ +/* { dg-do compile } */ + +/* Test the 'dot syntax' with deprecated methods. */ + +#include <objc/objc.h> + +@interface MyClass +{ + Class isa; +} ++ (int) classCount __attribute__ ((deprecated)); ++ (void) setClassCount: (int)value __attribute__ ((deprecated)); + +- (int) count __attribute__ ((deprecated)); +- (void) setCount: (int)value __attribute__ ((deprecated)); + +- (int) classCount2; +- (void) setClassCount2: (int)value; + +- (int) count2; +- (void) setCount2: (int)value; +@end + +void foo (void) +{ + MyClass *object = nil; + + + if (object.count > 0) /* { dg-warning "is deprecated" } */ + object.count = 20; /* { dg-warning "is deprecated" } */ + + if (MyClass.classCount < -7) /* { dg-warning "is deprecated" } */ + MyClass.classCount = 11; /* { dg-warning "is deprecated" } */ + + if (object.classCount2 > 0) + object.classCount2 = 19; + + if (object.count2 < -7) + object.count2 = 74; +} diff --git a/gcc/testsuite/objc.dg/property/at-property-deprecated-1.m b/gcc/testsuite/objc.dg/property/at-property-deprecated-1.m index c38854f..e520477 100644 --- a/gcc/testsuite/objc.dg/property/at-property-deprecated-1.m +++ b/gcc/testsuite/objc.dg/property/at-property-deprecated-1.m @@ -29,8 +29,8 @@ int main (void) { MyRootClass *object = [[MyRootClass alloc] init]; - object.a = 40; /* { dg-warning ".a. is deprecated .declared at " } */ - if (object.a != 40) /* { dg-warning ".a. is deprecated .declared at " } */ + object.a = 40; /* { dg-warning "is deprecated" } */ + if (object.a != 40) /* { dg-warning "is deprecated" } */ abort (); return 0; diff --git a/gcc/testsuite/objc.dg/property/at-property-deprecated-2.m b/gcc/testsuite/objc.dg/property/at-property-deprecated-2.m new file mode 100644 index 0000000..d2901a5 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/at-property-deprecated-2.m @@ -0,0 +1,25 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ +/* { dg-do compile } */ + +/* Test that deprecation warnings are produced when a setter/getter of + a @property is used directly. */ + +#include <objc/objc.h> + +@interface MyClass +{ + Class isa; + int variable; +} +@property (assign, nonatomic) int property __attribute__ ((deprecated)); +@end + +void foo (void) +{ + MyClass *object = nil; + + if ([object property] > 0) /* { dg-warning "is deprecated" } */ + { + [object setProperty: 43]; /* { dg-warning "is deprecated" } */ + } +} diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-deprecated-1.m b/gcc/testsuite/objc.dg/property/dotsyntax-deprecated-1.m new file mode 100644 index 0000000..ad627a8 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/dotsyntax-deprecated-1.m @@ -0,0 +1,41 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */ +/* { dg-do compile } */ + +/* Test the 'dot syntax' with deprecated methods. */ + +#include <objc/objc.h> + +@interface MyClass +{ + Class isa; +} ++ (int) classCount __attribute__ ((deprecated)); ++ (void) setClassCount: (int)value __attribute__ ((deprecated)); + +- (int) count __attribute__ ((deprecated)); +- (void) setCount: (int)value __attribute__ ((deprecated)); + +- (int) classCount2; +- (void) setClassCount2: (int)value; + +- (int) count2; +- (void) setCount2: (int)value; +@end + +void foo (void) +{ + MyClass *object = nil; + + + if (object.count > 0) /* { dg-warning "is deprecated" } */ + object.count = 20; /* { dg-warning "is deprecated" } */ + + if (MyClass.classCount < -7) /* { dg-warning "is deprecated" } */ + MyClass.classCount = 11; /* { dg-warning "is deprecated" } */ + + if (object.classCount2 > 0) + object.classCount2 = 19; + + if (object.count2 < -7) + object.count2 = 74; +} |