From bb93020ff852fb159bc329bbaea12a33a4ef6761 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Sat, 24 Oct 2020 09:48:44 +0100 Subject: Objective-C : Implement SEL as a built-in typedef. The reference implementation for Objective-C provides the SEL typedef (although it is also available from ). gcc/objc/ChangeLog: * objc-act.c (synth_module_prologue): Get the SEL identifier. * objc-act.h (enum objc_tree_index): Add OCTI_SEL_NAME. (objc_selector_name): New. (SEL_TYPEDEF_NAME): New. * objc-gnu-runtime-abi-01.c (gnu_runtime_01_initialize): Initialize SEL typedef. * objc-next-runtime-abi-01.c (next_runtime_01_initialize): Likewise. * objc-next-runtime-abi-02.c gcc/testsuite/ChangeLog: * obj-c++.dg/SEL-typedef.mm: New test. * objc.dg/SEL-typedef.m: New test. --- gcc/objc/objc-act.c | 1 + gcc/objc/objc-act.h | 3 +++ gcc/objc/objc-gnu-runtime-abi-01.c | 7 +++++++ gcc/objc/objc-next-runtime-abi-01.c | 7 +++++++ gcc/objc/objc-next-runtime-abi-02.c | 7 +++++++ 5 files changed, 25 insertions(+) (limited to 'gcc/objc') diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 31a2cf3..0393bc4 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -2954,6 +2954,7 @@ synth_module_prologue (void) objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME); objc_instancetype_name = get_identifier (INSTANCE_TYPEDEF_NAME); objc_class_name = get_identifier (CLASS_TYPEDEF_NAME); + objc_selector_name = get_identifier (SEL_TYPEDEF_NAME); /* Declare the 'id', 'instancetype' and 'Class' typedefs. */ type = lang_hooks.decls.pushdecl (build_decl (input_location, diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h index 913e152..db71b6a 100644 --- a/gcc/objc/objc-act.h +++ b/gcc/objc/objc-act.h @@ -371,6 +371,7 @@ enum objc_tree_index OCTI_ID_NAME, OCTI_INSTANCETYPE_NAME, OCTI_CLASS_NAME, + OCTI_SEL_NAME, OCTI_CNST_STR_ID, OCTI_CNST_STR_TYPE, OCTI_CNST_STR_GLOB_ID, @@ -576,6 +577,7 @@ extern GTY(()) tree objc_global_trees[OCTI_MAX]; #define objc_object_name objc_global_trees[OCTI_ID_NAME] #define objc_instancetype_name objc_global_trees[OCTI_INSTANCETYPE_NAME] #define objc_class_name objc_global_trees[OCTI_CLASS_NAME] +#define objc_selector_name objc_global_trees[OCTI_SEL_NAME] /* Constant string classes. */ #define constant_string_id objc_global_trees[OCTI_CNST_STR_ID] @@ -614,6 +616,7 @@ extern GTY(()) tree objc_global_trees[OCTI_MAX]; #define OBJECT_TYPEDEF_NAME "id" #define INSTANCE_TYPEDEF_NAME "instancetype" #define CLASS_TYPEDEF_NAME "Class" +#define SEL_TYPEDEF_NAME "SEL" #define TAG_OBJECT "objc_object" #define TAG_CLASS "objc_class" diff --git a/gcc/objc/objc-gnu-runtime-abi-01.c b/gcc/objc/objc-gnu-runtime-abi-01.c index 25c0e01..ac9a862 100644 --- a/gcc/objc/objc-gnu-runtime-abi-01.c +++ b/gcc/objc/objc-gnu-runtime-abi-01.c @@ -208,6 +208,13 @@ static void gnu_runtime_01_initialize (void) type = build_qualified_type (type, TYPE_QUAL_CONST); objc_selector_type = build_pointer_type (type); + /* SEL typedef. */ + type = lang_hooks.decls.pushdecl (build_decl (input_location, + TYPE_DECL, + objc_selector_name, + objc_selector_type)); + TREE_NO_WARNING (type) = 1; + /* typedef id (*IMP)(id, SEL, ...); */ ftype = build_varargs_function_type_list (objc_object_type, objc_object_type, diff --git a/gcc/objc/objc-next-runtime-abi-01.c b/gcc/objc/objc-next-runtime-abi-01.c index 233d89e..7fc449b 100644 --- a/gcc/objc/objc-next-runtime-abi-01.c +++ b/gcc/objc/objc-next-runtime-abi-01.c @@ -277,6 +277,13 @@ static void next_runtime_01_initialize (void) objc_selector_type = build_pointer_type (xref_tag (RECORD_TYPE, get_identifier (TAG_SELECTOR))); + /* SEL typedef. */ + type = lang_hooks.decls.pushdecl (build_decl (input_location, + TYPE_DECL, + objc_selector_name, + objc_selector_type)); + TREE_NO_WARNING (type) = 1; + build_v1_class_template (); build_super_template (); build_v1_protocol_template (); diff --git a/gcc/objc/objc-next-runtime-abi-02.c b/gcc/objc/objc-next-runtime-abi-02.c index d7812ff..f3c285a 100644 --- a/gcc/objc/objc-next-runtime-abi-02.c +++ b/gcc/objc/objc-next-runtime-abi-02.c @@ -374,6 +374,13 @@ static void next_runtime_02_initialize (void) objc_selector_type = build_pointer_type (xref_tag (RECORD_TYPE, get_identifier (TAG_SELECTOR))); + /* SEL typedef. */ + type = lang_hooks.decls.pushdecl (build_decl (input_location, + TYPE_DECL, + objc_selector_name, + objc_selector_type)); + TREE_NO_WARNING (type) = 1; + /* IMP : id (*) (id, _message_ref_t*, ...) SUPER_IMP : id (*) ( super_t*, _super_message_ref_t*, ...) objc_v2_selector_type. */ -- cgit v1.1 From 88ce3d5fbb948cc600800b15f4ca774a0ce8e7a7 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Mon, 2 Nov 2020 20:53:00 +0000 Subject: Daily bump. --- gcc/objc/ChangeLog | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'gcc/objc') diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index f69d2d7..4ddee9c 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,15 @@ +2020-11-01 Iain Sandoe + + * objc-act.c (synth_module_prologue): Get the SEL identifier. + * objc-act.h (enum objc_tree_index): Add OCTI_SEL_NAME. + (objc_selector_name): New. + (SEL_TYPEDEF_NAME): New. + * objc-gnu-runtime-abi-01.c + (gnu_runtime_01_initialize): Initialize SEL typedef. + * objc-next-runtime-abi-01.c + (next_runtime_01_initialize): Likewise. + * objc-next-runtime-abi-02.c + 2020-10-11 Iain Sandoe * objc-next-runtime-abi-02.c -- cgit v1.1 From 878cffbd9e6e1b138a6e0d362e7b29bc0a259940 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Sat, 31 Oct 2020 09:25:47 +0000 Subject: Objective-C++ : Fix ICE in potential_constant_expression_1. We cannot, as things stand, handle Objective-C tree codes in the switch and deal with this by calling out to a function that has a dummy version when Objective-C is not enabled. Because of the way the logic works (with a fall through to a 'sorry' in case of unhandled expressions), the function reports cases that are known to be unsuitable for constant exprs. The dummy function always reports 'false' and thus will fall through to the 'sorry'. gcc/c-family/ChangeLog: * c-objc.h (objc_non_constant_expr_p): New. * stub-objc.c (objc_non_constant_expr_p): New. gcc/cp/ChangeLog: * constexpr.c (potential_constant_expression_1): Handle expressions known to be non-constant for Objective-C. gcc/objc/ChangeLog: * objc-act.c (objc_non_constant_expr_p): New. --- gcc/objc/objc-act.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'gcc/objc') diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 0393bc4..c0d07ae 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -1720,7 +1720,6 @@ objc_build_class_component_ref (tree class_name, tree property_ident) } - /* This is used because we don't want to expose PROPERTY_REF to the C/C++ frontends. Maybe we should! */ bool @@ -1732,6 +1731,21 @@ objc_is_property_ref (tree node) return false; } +/* We use this to report tree codes that are known to be invalid in const- + expression contexts. */ +bool +objc_non_constant_expr_p (tree node) +{ + switch (TREE_CODE (node)) + { + default: + return false; + case MESSAGE_SEND_EXPR: + case PROPERTY_REF: + return true; + } +} + /* This function builds a setter call for a PROPERTY_REF (real, for a declared property, or artificial, for a dot-syntax accessor which is not corresponding to a property). 'lhs' must be a PROPERTY_REF -- cgit v1.1 From 35c125cb6ac47fa97aa5ee22f987a38e63adad08 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 5 Nov 2020 00:16:36 +0000 Subject: Daily bump. --- gcc/objc/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gcc/objc') diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 4ddee9c..a225e64 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,7 @@ +2020-11-04 Iain Sandoe + + * objc-act.c (objc_non_constant_expr_p): New. + 2020-11-01 Iain Sandoe * objc-act.c (synth_module_prologue): Get the SEL identifier. -- cgit v1.1 From 9a34a5cce6b50fc3527e7c7ab356808ed435883c Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Sat, 31 Oct 2020 20:53:34 +0000 Subject: Objective-C/C++ (parsers) : Update @property attribute parsing. At present, we are missing parsing and checking for around half of the property attributes in use. The existing ad hoc scheme for the parser's communication with the Objective C validation is not suitable for extending to cover all the missing cases. Additionally: 1/ We were declaring errors in two cases that the reference implementation warns (or is silent). I've elected to warn for both those cases, (Wattributes) it could be that we should implement Wobjc-xxx-property warning masks (TODO). 2/ We were emitting spurious complaints about missing property attributes when these were not being parsed because we gave up on the first syntax error. 3/ The quality of the diagnostic locations was poor (that's true for much of Objective-C, we will have to improve it as we modernise areas). We continue to attempt to keep the code, warning and error output similar (preferably identical output) between the C and C++ front ends. The interface to the Objective-C-specific parts of the parsing is simplified to a vector of parsed (but not fully-checked) property attributes, this will simplify the addition of new attributes. gcc/c-family/ChangeLog: * c-objc.h (enum objc_property_attribute_group): New (enum objc_property_attribute_kind): New. (OBJC_PROPATTR_GROUP_MASK): New. (struct property_attribute_info): Small class encapsulating parser output from property attributes. (objc_prop_attr_kind_for_rid): New (objc_add_property_declaration): Simplify interface. * stub-objc.c (enum rid): Dummy type. (objc_add_property_declaration): Simplify interface. (objc_prop_attr_kind_for_rid): New. gcc/c/ChangeLog: * c-parser.c (c_parser_objc_at_property_declaration): Improve parsing fidelity. Associate better location info with @property attributes. Clean up the interface to objc_add_property_declaration (). gcc/cp/ChangeLog: * parser.c (cp_parser_objc_at_property_declaration): Improve parsing fidelity. Associate better location info with @property attributes. Clean up the interface to objc_add_property_declaration (). gcc/objc/ChangeLog: * objc-act.c (objc_prop_attr_kind_for_rid): New. (objc_add_property_declaration): Adjust to consume the parser output using a vector of parsed attributes. gcc/testsuite/ChangeLog: * obj-c++.dg/property/at-property-1.mm: Adjust expected diagnostics. * obj-c++.dg/property/at-property-29.mm: Likewise. * obj-c++.dg/property/at-property-4.mm: Likewise. * obj-c++.dg/property/property-neg-2.mm: Likewise. * objc.dg/property/at-property-1.m: Likewise. * objc.dg/property/at-property-29.m: Likewise. * objc.dg/property/at-property-4.m: Likewise. * objc.dg/property/at-property-5.m: Likewise. * objc.dg/property/property-neg-2.m: Likewise. --- gcc/objc/objc-act.c | 295 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 179 insertions(+), 116 deletions(-) (limited to 'gcc/objc') diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index c0d07ae..26cdedd 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -804,119 +804,74 @@ lookup_property (tree interface_type, tree property) return inter; } +/* This routine returns a PROPERTY_KIND for the front end RID code supplied. */ + +enum objc_property_attribute_kind +objc_prop_attr_kind_for_rid (enum rid prop_rid) +{ + switch (prop_rid) + { + default: return OBJC_PROPERTY_ATTR_UNKNOWN; + case RID_GETTER: return OBJC_PROPERTY_ATTR_GETTER; + case RID_SETTER: return OBJC_PROPERTY_ATTR_SETTER; + + case RID_READONLY: return OBJC_PROPERTY_ATTR_READONLY; + case RID_READWRITE: return OBJC_PROPERTY_ATTR_READWRITE; + + case RID_ASSIGN: return OBJC_PROPERTY_ATTR_ASSIGN; + case RID_RETAIN: return OBJC_PROPERTY_ATTR_RETAIN; + case RID_COPY: return OBJC_PROPERTY_ATTR_COPY; + + case RID_NONATOMIC: return OBJC_PROPERTY_ATTR_NONATOMIC; + + } +} + /* This routine is called by the parser when a @property... declaration is found. 'decl' is the declaration of the property (type/identifier), and the other arguments represent property attributes that may have been specified in the Objective-C declaration. 'parsed_property_readonly' is 'true' if the attribute 'readonly' was specified, and 'false' if not; similarly for the - other bool parameters. 'parsed_property_getter_ident' is NULL_TREE + other bool parameters. 'property_getter_ident' is NULL_TREE if the attribute 'getter' was not specified, and is the identifier corresponding to the specified getter if it was; similarly for - 'parsed_property_setter_ident'. */ + 'property_setter_ident'. */ void objc_add_property_declaration (location_t location, tree decl, - bool parsed_property_readonly, bool parsed_property_readwrite, - bool parsed_property_assign, bool parsed_property_retain, - bool parsed_property_copy, bool parsed_property_nonatomic, - tree parsed_property_getter_ident, tree parsed_property_setter_ident) + vec& prop_attr_list) { - tree property_decl; - tree x; - /* 'property_readonly' and 'property_assign_semantics' are the final - attributes of the property after all parsed attributes have been - considered (eg, if we parsed no 'readonly' and no 'readwrite', ie - parsed_property_readonly = false and parsed_property_readwrite = - false, then property_readonly will be false because the default - is readwrite). */ - bool property_readonly = false; - objc_property_assign_semantics property_assign_semantics = OBJC_PROPERTY_ASSIGN; - bool property_extension_in_class_extension = false; - if (flag_objc1_only) - error_at (input_location, "%<@property%> is not available in Objective-C 1.0"); - - if (parsed_property_readonly && parsed_property_readwrite) - { - error_at (location, "% attribute conflicts with % attribute"); - /* In case of conflicting attributes (here and below), after - producing an error, we pick one of the attributes and keep - going. */ - property_readonly = false; - } - else - { - if (parsed_property_readonly) - property_readonly = true; - - if (parsed_property_readwrite) - property_readonly = false; - } - - if (parsed_property_readonly && parsed_property_setter_ident) - { - error_at (location, "% attribute conflicts with % attribute"); - property_readonly = false; - } - - if (parsed_property_assign && parsed_property_retain) - { - error_at (location, "% attribute conflicts with % attribute"); - property_assign_semantics = OBJC_PROPERTY_RETAIN; - } - else if (parsed_property_assign && parsed_property_copy) - { - error_at (location, "% attribute conflicts with % attribute"); - property_assign_semantics = OBJC_PROPERTY_COPY; - } - else if (parsed_property_retain && parsed_property_copy) - { - error_at (location, "% attribute conflicts with % attribute"); - property_assign_semantics = OBJC_PROPERTY_COPY; - } - else - { - if (parsed_property_assign) - property_assign_semantics = OBJC_PROPERTY_ASSIGN; - - if (parsed_property_retain) - property_assign_semantics = OBJC_PROPERTY_RETAIN; - - if (parsed_property_copy) - property_assign_semantics = OBJC_PROPERTY_COPY; - } + /* FIXME: we probably ought to bail out at this point. */ + error_at (location, "%<@property%> is not available in Objective-C 1.0"); + /* We must be in an interface, category, or protocol. */ if (!objc_interface_context) { - error_at (location, "property declaration not in @interface or @protocol context"); + error_at (location, "property declaration not in %<@interface%>," + " %<@protocol%> or % context"); return; } - /* At this point we know that we are either in an interface, a - category, or a protocol. */ + /* Do some spot-checks for the most obvious invalid cases. */ + + gcc_checking_assert (decl && TREE_CODE (decl) == FIELD_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) + if (decl && !DECL_NAME (decl)) { - error_at (location, "invalid property declaration"); + error_at (location, "properties must be named"); return; } - /* Do some spot-checks for the most obvious invalid types. */ - + location_t decl_loc = DECL_SOURCE_LOCATION (decl); + decl_loc = make_location (decl_loc, location, decl_loc); if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) { - error_at (location, "property cannot be an array"); + error_at (decl_loc, "property cannot be an array"); return; } - /* 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)) + if (DECL_C_BIT_FIELD (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 @@ -925,10 +880,110 @@ objc_add_property_declaration (location_t location, tree decl, and arguments of functions cannot be bitfields). The underlying instance variable could be a bitfield, but that is a different matter. */ - error_at (location, "property cannot be a bit-field"); + error_at (decl_loc, "property cannot be a bit-field"); return; } -#endif + + /* The final results of parsing the (growing number) of property + attributes. */ + property_attribute_info *attrs[OBJC_PROPATTR_GROUP_MAX] = { nullptr }; + + tree property_getter_ident = NULL_TREE; + tree property_setter_ident = NULL_TREE; + for (unsigned pn = 0; pn < prop_attr_list.length (); ++pn) + { + if (prop_attr_list[pn]->parse_error) + continue; /* Ignore attributes known to be wrongly parsed. */ + + switch (int g = (int) prop_attr_list[pn]->group()) + { + case OBJC_PROPATTR_GROUP_UNKNOWN: + continue; + case OBJC_PROPATTR_GROUP_SETTER: + case OBJC_PROPATTR_GROUP_GETTER: + if (attrs[g]) + { + warning_at (prop_attr_list[pn]->prop_loc, OPT_Wattributes, + "multiple property %qE methods specified, the latest" + " one will be used", attrs[g]->name); + inform (attrs[g]->prop_loc, "previous specification"); + } + attrs[g] = prop_attr_list[pn]; + if (g == OBJC_PROPATTR_GROUP_SETTER) + property_setter_ident = attrs[g]->ident; + else + property_getter_ident = attrs[g]->ident; + continue; + default: + { + if (!attrs[g]) + ; + else if (attrs[g]->prop_kind != prop_attr_list[pn]->prop_kind) + { + error_at (prop_attr_list[pn]->prop_loc, + "%qE attribute conflicts with %qE attribute", + prop_attr_list[pn]->name, attrs[g]->name); + inform (attrs[g]->prop_loc, "%qE specified here", + attrs[g]->name ); + } + else + { + warning_at (prop_attr_list[pn]->prop_loc, OPT_Wattributes, + "duplicate %qE attribute", attrs[g]->name); + inform (attrs[g]->prop_loc, "first specified here"); + } + attrs[g] = prop_attr_list[pn]; + } + continue; + } + } + + /* The defaults for atomicity (atomic) and write-ability (readwrite) apply + even if the user provides no specified attributes. */ + bool property_nonatomic = false; + bool property_readonly = false; + + /* Set the values from any specified by the user; these are easy, only two + states. */ + if (attrs[OBJC_PROPATTR_GROUP_ATOMIC]) + property_nonatomic = attrs[OBJC_PROPATTR_GROUP_ATOMIC]->prop_kind + == OBJC_PROPERTY_ATTR_NONATOMIC; + + if (attrs[OBJC_PROPATTR_GROUP_READWRITE]) + property_readonly = attrs[OBJC_PROPATTR_GROUP_READWRITE]->prop_kind + == OBJC_PROPERTY_ATTR_READONLY; + + /* One can't set a readonly value; we issue an error, but force the property + to readwrite as well. */ + if (property_readonly && property_setter_ident) + { + error_at (attrs[OBJC_PROPATTR_GROUP_READWRITE]->prop_loc, "%" + " attribute conflicts with % attribute"); + gcc_checking_assert (attrs[OBJC_PROPATTR_GROUP_SETTER]); + inform (attrs[OBJC_PROPATTR_GROUP_SETTER]->prop_loc, "%" + " specified here"); + property_readonly = false; + } + + /* Assign semantics is a tri-state property, and also needs some further + checking against the object type. */ + objc_property_assign_semantics property_assign_semantics + = OBJC_PROPERTY_ASSIGN; + + if (attrs[OBJC_PROPATTR_GROUP_ASSIGN]) + { + if (attrs[OBJC_PROPATTR_GROUP_ASSIGN]->prop_kind + == OBJC_PROPERTY_ATTR_ASSIGN) + property_assign_semantics = OBJC_PROPERTY_ASSIGN; + else if (attrs[OBJC_PROPATTR_GROUP_ASSIGN]->prop_kind + == OBJC_PROPERTY_ATTR_RETAIN) + property_assign_semantics = OBJC_PROPERTY_RETAIN; + else if (attrs[OBJC_PROPATTR_GROUP_ASSIGN]->prop_kind + == OBJC_PROPERTY_ATTR_COPY) + property_assign_semantics = OBJC_PROPERTY_COPY; + else + gcc_unreachable (); + } /* TODO: Check that the property type is an Objective-C object or a "POD". */ @@ -950,69 +1005,77 @@ objc_add_property_declaration (location_t location, tree decl, for non-{Objective-C objects}, and to 'retain' for Objective-C objects. But that would break compatibility with other compilers. */ - if (!parsed_property_assign && !parsed_property_retain && !parsed_property_copy) + if (!attrs[OBJC_PROPATTR_GROUP_ASSIGN]) { /* Use 'false' so we do not warn for Class objects. */ if (objc_type_valid_for_messaging (TREE_TYPE (decl), false)) { - warning_at (location, - 0, - "object property %qD has no %, % or % attribute; assuming %", - decl); - inform (location, - "% can be unsafe for Objective-C objects; please state explicitly if you need it"); + warning_at (decl_loc, 0, "object property %qD has no %," + " % or % attribute; assuming" + " %", decl); + inform (decl_loc, "% can be unsafe for Objective-C" + " objects; please state explicitly if you need it"); } } } - if (property_assign_semantics == OBJC_PROPERTY_RETAIN - && !objc_type_valid_for_messaging (TREE_TYPE (decl), true)) - error_at (location, "% attribute is only valid for Objective-C objects"); + /* Some attributes make no sense unless applied to an Objective-C object. */ + bool prop_objc_object_p + = objc_type_valid_for_messaging (TREE_TYPE (decl), true); + if (!prop_objc_object_p) + { + tree p_name = NULL_TREE; + if (property_assign_semantics == OBJC_PROPERTY_RETAIN + || property_assign_semantics == OBJC_PROPERTY_COPY) + p_name = attrs[OBJC_PROPATTR_GROUP_ASSIGN]->name; - if (property_assign_semantics == OBJC_PROPERTY_COPY - && !objc_type_valid_for_messaging (TREE_TYPE (decl), true)) - error_at (location, "% attribute is only valid for Objective-C objects"); + if (p_name) + error_at (decl_loc, "%qE attribute is only valid for Objective-C" + " objects", p_name); + } /* Now determine the final property getter and setter names. They will be stored in the PROPERTY_DECL, from which they'll always be extracted and used. */ /* Adjust, or fill in, setter and getter names. We overwrite the - parsed_property_setter_ident and parsed_property_getter_ident + property_setter_ident and property_getter_ident with the final setter and getter identifiers that will be used. */ - if (parsed_property_setter_ident) + if (property_setter_ident) { /* The setter should be terminated by ':', but the parser only gives us an identifier without ':'. So, we need to add ':' at the end. */ - const char *parsed_setter = IDENTIFIER_POINTER (parsed_property_setter_ident); + const char *parsed_setter = IDENTIFIER_POINTER (property_setter_ident); size_t length = strlen (parsed_setter); char *final_setter = (char *)alloca (length + 2); sprintf (final_setter, "%s:", parsed_setter); - parsed_property_setter_ident = get_identifier (final_setter); + property_setter_ident = get_identifier (final_setter); } else { if (!property_readonly) - parsed_property_setter_ident = get_identifier (objc_build_property_setter_name + property_setter_ident = get_identifier (objc_build_property_setter_name (DECL_NAME (decl))); } - if (!parsed_property_getter_ident) - parsed_property_getter_ident = DECL_NAME (decl); + if (!property_getter_ident) + property_getter_ident = DECL_NAME (decl); /* Check for duplicate property declarations. We first check the immediate context for a property with the same name. Any such declarations are an error, unless this is a class extension and we are extending a property from readonly to readwrite. */ + bool property_extension_in_class_extension = false; + tree x = NULL_TREE; for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x)) { if (PROPERTY_NAME (x) == DECL_NAME (decl)) { if (objc_in_class_extension - && property_readonly == 0 + && !property_readonly && PROPERTY_READONLY (x) == 1) { /* This is a class extension, and we are extending an @@ -1087,7 +1150,7 @@ objc_add_property_declaration (location_t location, tree decl, types, or it is compatible. */ location_t original_location = DECL_SOURCE_LOCATION (x); - if (PROPERTY_NONATOMIC (x) != parsed_property_nonatomic) + if (PROPERTY_NONATOMIC (x) != property_nonatomic) { warning_at (location, 0, "% attribute of property %qD conflicts with " @@ -1098,7 +1161,7 @@ objc_add_property_declaration (location_t location, tree decl, return; } - if (PROPERTY_GETTER_NAME (x) != parsed_property_getter_ident) + if (PROPERTY_GETTER_NAME (x) != property_getter_ident) { warning_at (location, 0, "% attribute of property %qD conflicts with " @@ -1112,7 +1175,7 @@ objc_add_property_declaration (location_t location, tree decl, /* We can only compare the setter names if both the old and new property have a setter. */ if (!property_readonly && !PROPERTY_READONLY(x)) { - if (PROPERTY_SETTER_NAME (x) != parsed_property_setter_ident) + if (PROPERTY_SETTER_NAME (x) != property_setter_ident) { warning_at (location, 0, "% attribute of property %qD conflicts with " @@ -1190,13 +1253,13 @@ objc_add_property_declaration (location_t location, tree decl, if (property_extension_in_class_extension) { PROPERTY_READONLY (x) = 0; - PROPERTY_SETTER_NAME (x) = parsed_property_setter_ident; + PROPERTY_SETTER_NAME (x) = property_setter_ident; return; } } /* Create a PROPERTY_DECL node. */ - property_decl = make_node (PROPERTY_DECL); + tree property_decl = make_node (PROPERTY_DECL); /* Copy the basic information from the original decl. */ TREE_TYPE (property_decl) = TREE_TYPE (decl); @@ -1205,10 +1268,10 @@ objc_add_property_declaration (location_t location, tree decl, /* Add property-specific information. */ PROPERTY_NAME (property_decl) = DECL_NAME (decl); - PROPERTY_GETTER_NAME (property_decl) = parsed_property_getter_ident; - PROPERTY_SETTER_NAME (property_decl) = parsed_property_setter_ident; + PROPERTY_GETTER_NAME (property_decl) = property_getter_ident; + PROPERTY_SETTER_NAME (property_decl) = property_setter_ident; PROPERTY_READONLY (property_decl) = property_readonly; - PROPERTY_NONATOMIC (property_decl) = parsed_property_nonatomic; + PROPERTY_NONATOMIC (property_decl) = property_nonatomic; PROPERTY_ASSIGN_SEMANTICS (property_decl) = property_assign_semantics; PROPERTY_IVAR_NAME (property_decl) = NULL_TREE; PROPERTY_DYNAMIC (property_decl) = 0; -- cgit v1.1 From 6e8e1036f79e575fbe1eda57957158291c12f195 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Sun, 25 Oct 2020 17:34:29 +0000 Subject: Objective-C/C++ : Allow visibility prefix attributes on interfaces. This passes visibiliy through without warning (so that, for example, __attribute__((__visibility("default"))) does not result in any diagnostic). gcc/objc/ChangeLog: * objc-act.c (start_class): Accept visibility attributes without warning. --- gcc/objc/objc-act.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'gcc/objc') diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 26cdedd..68d829f 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -7013,12 +7013,14 @@ start_class (enum tree_code code, tree class_name, tree super_name, tree name = TREE_PURPOSE (attribute); /* TODO: Document what the objc_exception attribute is/does. */ - /* We handle the 'deprecated' and (undocumented) 'objc_exception' - attributes. */ + /* We handle the 'deprecated', 'visibility' and (undocumented) + 'objc_exception' attributes. */ if (is_attribute_p ("deprecated", name)) TREE_DEPRECATED (klass) = 1; else if (is_attribute_p ("objc_exception", name)) CLASS_HAS_EXCEPTION_ATTR (klass) = 1; + else if (is_attribute_p ("visibility", name)) + ; else /* Warn about and ignore all others for now, but store them. */ warning (OPT_Wattributes, "%qE attribute directive ignored", name); -- cgit v1.1 From 44cab2d8fd777450953ee1c1dfeba6f67db13869 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 7 Nov 2020 00:16:39 +0000 Subject: Daily bump. --- gcc/objc/ChangeLog | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'gcc/objc') diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index a225e64..3fc8414 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,14 @@ +2020-11-06 Iain Sandoe + + * objc-act.c (start_class): Accept visibility attributes + without warning. + +2020-11-06 Iain Sandoe + + * objc-act.c (objc_prop_attr_kind_for_rid): New. + (objc_add_property_declaration): Adjust to consume the + parser output using a vector of parsed attributes. + 2020-11-04 Iain Sandoe * objc-act.c (objc_non_constant_expr_p): New. -- cgit v1.1 From 0c30bf43eb2325caa4cb32a697ac1127c15205d7 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Sat, 24 Oct 2020 15:51:46 +0100 Subject: Objective-C : Implement NSObject attribute. This attribute allows pointers to be marked as pointers to an NSObject-compatible object. This allows for additional checking of assignment etc. when refering to pointers to opaque types. gcc/c-family/ChangeLog: * c-attribs.c (handle_nsobject_attribute): New. * c.opt: Add WNSObject-attribute. gcc/objc/ChangeLog: * objc-act.c (objc_compare_types): Handle NSObject type attributes. (objc_type_valid_for_messaging): Likewise. gcc/testsuite/ChangeLog: * obj-c++.dg/attributes/nsobject-01.mm: New test. * objc.dg/attributes/nsobject-01.m: New test. --- gcc/objc/objc-act.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'gcc/objc') diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 68d829f..8be4bea 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -2476,9 +2476,14 @@ objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee) if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp)) return false; + tree ltyp_attr, rtyp_attr; do { - ltyp = TREE_TYPE (ltyp); /* Remove indirections. */ + /* Remove indirections, but keep the type attributes from the innermost + pointer type, to check for NSObject. */ + ltyp_attr = TYPE_ATTRIBUTES (ltyp); + ltyp = TREE_TYPE (ltyp); + rtyp_attr = TYPE_ATTRIBUTES (rtyp); rtyp = TREE_TYPE (rtyp); } while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp)); @@ -2523,17 +2528,23 @@ objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee) return true; } + /* We might have void * with NSObject type attr. */ + bool l_NSObject_p = ltyp_attr && lookup_attribute ("NSObject", ltyp_attr); + bool r_NSObject_p = rtyp_attr && lookup_attribute ("NSObject", rtyp_attr); + /* Past this point, we are only interested in ObjC class instances, - or 'id' or 'Class'. */ - if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE) + or 'id' or 'Class' (except if the user applied the NSObject type + attribute). */ + if ((TREE_CODE (ltyp) != RECORD_TYPE && !l_NSObject_p) + || (TREE_CODE (rtyp) != RECORD_TYPE && !r_NSObject_p)) return false; if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp) - && !TYPE_HAS_OBJC_INFO (ltyp)) + && !TYPE_HAS_OBJC_INFO (ltyp) && !l_NSObject_p) return false; if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp) - && !TYPE_HAS_OBJC_INFO (rtyp)) + && !TYPE_HAS_OBJC_INFO (rtyp) && !r_NSObject_p) return false; /* Past this point, we are committed to returning 'true' to the caller @@ -2567,12 +2578,15 @@ objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee) rcls = NULL_TREE; /* If either type is an unqualified 'id', we're done. This is because - an 'id' can be assigned to or from any type with no warnings. */ + an 'id' can be assigned to or from any type with no warnings. When + the pointer has NSObject attribute, consider that to be equivalent. */ if (argno != -5) { if ((!lproto && objc_is_object_id (ltyp)) || (!rproto && objc_is_object_id (rtyp))) return true; + if (l_NSObject_p || r_NSObject_p) + return true; } else { @@ -2580,7 +2594,7 @@ objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee) general type of object, hence if you try to specialize an 'NSArray *' (ltyp) property with an 'id' (rtyp) one, we need to warn. */ - if (!lproto && objc_is_object_id (ltyp)) + if (!lproto && (objc_is_object_id (ltyp) || l_NSObject_p)) return true; } @@ -8659,11 +8673,19 @@ objc_type_valid_for_messaging (tree type, bool accept_classes) if (!POINTER_TYPE_P (type)) return false; + /* We will check for an NSObject type attribute on the pointer if other + tests fail. */ + tree type_attr = TYPE_ATTRIBUTES (type); + /* Remove the pointer indirection; don't remove more than one otherwise we'd consider "NSObject **" a valid type for messaging, which it isn't. */ type = TREE_TYPE (type); + /* We allow void * to have an NSObject type attr. */ + if (VOID_TYPE_P (type) && type_attr) + return lookup_attribute ("NSObject", type_attr) != NULL_TREE; + if (TREE_CODE (type) != RECORD_TYPE) return false; @@ -8676,6 +8698,9 @@ objc_type_valid_for_messaging (tree type, bool accept_classes) if (TYPE_HAS_OBJC_INFO (type)) return true; + if (type_attr) + return lookup_attribute ("NSObject", type_attr) != NULL_TREE; + return false; } -- cgit v1.1 From 6f762481a21f211c03b6eda416b5d5737c3ed4b7 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Mon, 2 Nov 2020 21:12:38 +0000 Subject: Objective-C/C++ (C-family) : Add missing 'atomic' property attribute. This is the default, but it is still legal in user code and therefore we should handle it in parsing. Fix whitespace issues in the lines affected. gcc/c-family/ChangeLog: * c-common.c (c_common_reswords): Add 'atomic' property attribute. * c-common.h (enum rid): Add RID_PROPATOMIC for atomic property attributes. gcc/objc/ChangeLog: * objc-act.c (objc_prop_attr_kind_for_rid): Handle RID_PROPATOMIC. gcc/testsuite/ChangeLog: * obj-c++.dg/property/at-property-4.mm: Test atomic property attribute. * objc.dg/property/at-property-4.m: Likewise. --- gcc/objc/objc-act.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/objc') diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 8be4bea..2dad46a 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -822,6 +822,7 @@ objc_prop_attr_kind_for_rid (enum rid prop_rid) case RID_RETAIN: return OBJC_PROPERTY_ATTR_RETAIN; case RID_COPY: return OBJC_PROPERTY_ATTR_COPY; + case RID_PROPATOMIC: return OBJC_PROPERTY_ATTR_ATOMIC; case RID_NONATOMIC: return OBJC_PROPERTY_ATTR_NONATOMIC; } -- cgit v1.1 From 2da7ee050cf01c8c38cb20828a432921e6b9f5b7 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sun, 8 Nov 2020 00:16:31 +0000 Subject: Daily bump. --- gcc/objc/ChangeLog | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'gcc/objc') diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 3fc8414..00e81d9 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,14 @@ +2020-11-07 Iain Sandoe + + * objc-act.c (objc_prop_attr_kind_for_rid): Handle + RID_PROPATOMIC. + +2020-11-07 Iain Sandoe + + * objc-act.c (objc_compare_types): Handle NSObject type + attributes. + (objc_type_valid_for_messaging): Likewise. + 2020-11-06 Iain Sandoe * objc-act.c (start_class): Accept visibility attributes -- cgit v1.1 From b642fca1c31b2e2175e0860daf32b4ee0d918085 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Wed, 4 Nov 2020 23:52:12 +0000 Subject: Objective-C/C++ : Handle parsing @property 'class' attribute. This attribute states that a property is one manipulated by class methods (it requires a static variable and the setter and getter must be provided explicitly, they cannot be @synthesized). gcc/c-family/ChangeLog: * c-common.h (OBJC_IS_PATTR_KEYWORD): Add class to the list of keywords accepted in @property attribute contexts. * c-objc.h (enum objc_property_attribute_group): Add OBJC_PROPATTR_GROUP_CLASS. (enum objc_property_attribute_kind): Add OBJC_PROPERTY_ATTR_CLASS. gcc/cp/ChangeLog: * parser.c (cp_parser_objc_at_property_declaration): Handle class keywords in @property attribute context. gcc/objc/ChangeLog: * objc-act.c (objc_prop_attr_kind_for_rid): Handle class attribute. (objc_add_property_declaration): Likewise. * objc-act.h (PROPERTY_CLASS): Record class attribute state. gcc/testsuite/ChangeLog: * obj-c++.dg/property/at-property-4.mm: Test handling class attributes. * objc.dg/property/at-property-4.m: Likewise. --- gcc/objc/objc-act.c | 10 ++++++++++ gcc/objc/objc-act.h | 4 ++++ 2 files changed, 14 insertions(+) (limited to 'gcc/objc') diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 2dad46a..b9ed32d 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -825,6 +825,7 @@ objc_prop_attr_kind_for_rid (enum rid prop_rid) case RID_PROPATOMIC: return OBJC_PROPERTY_ATTR_ATOMIC; case RID_NONATOMIC: return OBJC_PROPERTY_ATTR_NONATOMIC; + case RID_CLASS: return OBJC_PROPERTY_ATTR_CLASS; } } @@ -986,6 +987,14 @@ objc_add_property_declaration (location_t location, tree decl, gcc_unreachable (); } + /* An attribute that indicates this property manipulates a class variable. + In this case, both the variable and the getter/setter must be provided + by the user. */ + bool property_class = false; + if (attrs[OBJC_PROPATTR_GROUP_CLASS]) + property_nonatomic = attrs[OBJC_PROPATTR_GROUP_CLASS]->prop_kind + == OBJC_PROPERTY_ATTR_CLASS; + /* TODO: Check that the property type is an Objective-C object or a "POD". */ @@ -1273,6 +1282,7 @@ objc_add_property_declaration (location_t location, tree decl, PROPERTY_SETTER_NAME (property_decl) = property_setter_ident; PROPERTY_READONLY (property_decl) = property_readonly; PROPERTY_NONATOMIC (property_decl) = property_nonatomic; + PROPERTY_CLASS (property_decl) = property_class; PROPERTY_ASSIGN_SEMANTICS (property_decl) = property_assign_semantics; PROPERTY_IVAR_NAME (property_decl) = NULL_TREE; PROPERTY_DYNAMIC (property_decl) = 0; diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h index db71b6a..5b0433f 100644 --- a/gcc/objc/objc-act.h +++ b/gcc/objc/objc-act.h @@ -137,6 +137,10 @@ enum objc_property_assign_semantics { #define PROPERTY_OPTIONAL(DECL) \ DECL_LANG_FLAG_5 (PROPERTY_DECL_CHECK (DECL)) +/* PROPERTY_CLASS can be 0 or 1. */ +#define PROPERTY_CLASS(DECL) \ + DECL_LANG_FLAG_6 (PROPERTY_DECL_CHECK (DECL)) + /* PROPERTY_REF. A PROPERTY_REF represents an 'object.property' expression. It is normally used for property access, but when the Objective-C 2.0 "dot-syntax" (object.component) is used -- cgit v1.1 From fb95de7a11b8ac438857a02aaa0e1e50e9613f90 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Mon, 9 Nov 2020 00:16:25 +0000 Subject: Daily bump. --- gcc/objc/ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'gcc/objc') diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 00e81d9..5bc41c6 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,10 @@ +2020-11-08 Iain Sandoe + + * objc-act.c (objc_prop_attr_kind_for_rid): Handle class + attribute. + (objc_add_property_declaration): Likewise. + * objc-act.h (PROPERTY_CLASS): Record class attribute state. + 2020-11-07 Iain Sandoe * objc-act.c (objc_prop_attr_kind_for_rid): Handle -- cgit v1.1