diff options
author | Iain Sandoe <iain@sandoe.co.uk> | 2020-10-25 19:33:07 +0000 |
---|---|---|
committer | Iain Sandoe <iain@sandoe.co.uk> | 2020-11-13 10:40:54 +0000 |
commit | 5e28fca09c9c72bf5631efd0f0b06d52b0ebdb4d (patch) | |
tree | 668279298b8873e58c7ba3f20beb014d30666351 /gcc/c-family | |
parent | 64f191b152cb1df0e108a91880cb415e413bad56 (diff) | |
download | gcc-5e28fca09c9c72bf5631efd0f0b06d52b0ebdb4d.zip gcc-5e28fca09c9c72bf5631efd0f0b06d52b0ebdb4d.tar.gz gcc-5e28fca09c9c72bf5631efd0f0b06d52b0ebdb4d.tar.bz2 |
C-Family, Objective-C : Implement Objective-C nullability Part 1[PR90707].
This part of the implementation covers property nullability attributes
and includes the changes to common code. Follow-on changes will be needed
to cover Objective-C method definitions, but those are expected to be
local to the Objective-C front end.
The basis of the implementation is to translate the Objective-C-specific
keywords into an attribute (objc_nullability) which has the required
states to carry the attribute markup.
We introduce the keywords, and these are parsed and validated in the same
manner as other property attributes. The resulting value is attached to
the property as an objc_nullability attribute.
gcc/c-family/ChangeLog:
PR objc/90707
* c-common.c (c_common_reswords): null_unspecified, nullable,
nonnull, null_resettable: New keywords.
* c-common.h (enum rid): RID_NULL_UNSPECIFIED, RID_NULLABLE,
RID_NONNULL, RID_NULL_RESETTABLE: New.
(OBJC_IS_PATTR_KEYWORD): Include nullability keywords in the
ranges accepted for property attributes.
* c-attribs.c (handle_objc_nullability_attribute): New.
* c-objc.h (enum objc_property_attribute_group): Add
OBJC_PROPATTR_GROUP_NULLABLE.
(enum objc_property_attribute_kind):Add
OBJC_PROPERTY_ATTR_NULL_UNSPECIFIED, OBJC_PROPERTY_ATTR_NULLABLE,
OBJC_PROPERTY_ATTR_NONNULL, OBJC_PROPERTY_ATTR_NULL_RESETTABLE.
gcc/objc/ChangeLog:
PR objc/90707
* objc-act.c (objc_prop_attr_kind_for_rid): Handle nullability.
(objc_add_property_declaration): Handle nullability attributes.
Check that these are applicable to the property type.
* objc-act.h (enum objc_property_nullability): New.
gcc/testsuite/ChangeLog:
PR objc/90707
* obj-c++.dg/property/at-property-4.mm: Add basic nullability
tests.
* objc.dg/property/at-property-4.m: Likewise.
* obj-c++.dg/attributes/nullability-00.mm: New test.
* obj-c++.dg/property/nullability-00.mm: New test.
* objc.dg/attributes/nullability-00.m: New test.
* objc.dg/property/nullability-00.m: New test.
gcc/ChangeLog:
PR objc/90707
* doc/extend.texi: Document the objc_nullability attribute.
Diffstat (limited to 'gcc/c-family')
-rw-r--r-- | gcc/c-family/c-attribs.c | 49 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 6 | ||||
-rw-r--r-- | gcc/c-family/c-common.h | 7 | ||||
-rw-r--r-- | gcc/c-family/c-objc.h | 5 |
4 files changed, 66 insertions, 1 deletions
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index 24bcd70..abdc32e 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -159,6 +159,7 @@ static tree handle_patchable_function_entry_attribute (tree *, tree, tree, static tree handle_copy_attribute (tree *, tree, tree, int, bool *); static tree handle_nsobject_attribute (tree *, tree, tree, int, bool *); static tree handle_objc_root_class_attribute (tree *, tree, tree, int, bool *); +static tree handle_objc_nullability_attribute (tree *, tree, tree, int, bool *); /* Helper to define attribute exclusions. */ #define ATTR_EXCL(name, function, type, variable) \ @@ -516,6 +517,8 @@ const struct attribute_spec c_common_attribute_table[] = handle_nsobject_attribute, NULL }, { "objc_root_class", 0, 0, true, false, false, false, handle_objc_root_class_attribute, NULL }, + { "objc_nullability", 1, 1, true, false, false, false, + handle_objc_nullability_attribute, NULL }, { NULL, 0, 0, false, false, false, false, NULL, NULL } }; @@ -5182,6 +5185,52 @@ handle_objc_root_class_attribute (tree */*node*/, tree name, tree /*args*/, return NULL_TREE; } +/* Handle an "objc_nullability" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_objc_nullability_attribute (tree *node, tree name, tree args, + int /*flags*/, + bool *no_add_attrs) +{ + *no_add_attrs = true; + + tree type = TREE_TYPE (*node); + if (TREE_CODE (*node) == FUNCTION_DECL) + type = TREE_TYPE (type); + + if (type && !POINTER_TYPE_P (type)) + { + error ("%qE cannot be applied to non-pointer type %qT", name, type); + return NULL_TREE; + } + + /* We accept objc_nullability() with a single argument. + string: "unspecified", "nullable", "nonnull" or "resettable" + integer: 0 and 3 where the values have the same meaning as + the strings. */ + tree val = TREE_VALUE (args); + if (TREE_CODE (val) == INTEGER_CST) + { + val = default_conversion (val); + if (!tree_fits_uhwi_p (val) || tree_to_uhwi (val) > 3) + error ("%qE attribute argument %qE is not an integer constant" + " between 0 and 3", name, val); + else + *no_add_attrs = false; /* OK */ + } + else if (TREE_CODE (val) == STRING_CST + && (strcmp (TREE_STRING_POINTER (val), "nullable") == 0 + || strcmp (TREE_STRING_POINTER (val), "nonnull") == 0 + || strcmp (TREE_STRING_POINTER (val), "unspecified") == 0 + || strcmp (TREE_STRING_POINTER (val), "resettable") == 0)) + *no_add_attrs = false; /* OK */ + else if (val != error_mark_node) + error ("%qE attribute argument %qE is not recognised", name, val); + + return NULL_TREE; +} + /* Attempt to partially validate a single attribute ATTR as if it were to be applied to an entity OPER. */ diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 29508bc..ab7f642 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -580,6 +580,12 @@ const struct c_common_resword c_common_reswords[] = { "readwrite", RID_READWRITE, D_OBJC }, { "retain", RID_RETAIN, D_OBJC }, { "setter", RID_SETTER, D_OBJC }, + /* These are Objective C implementation of nullability, accepted only in + specific contexts. */ + { "null_unspecified", RID_NULL_UNSPECIFIED, D_OBJC }, + { "nullable", RID_NULLABLE, D_OBJC }, + { "nonnull", RID_NONNULL, D_OBJC }, + { "null_resettable", RID_NULL_RESETTABLE, D_OBJC }, }; const unsigned int num_c_common_reswords = diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index f470974..3c50897 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -87,6 +87,11 @@ enum rid RID_ASSIGN, RID_RETAIN, RID_COPY, RID_PROPATOMIC, RID_NONATOMIC, + /* ObjC nullability support keywords that also can appear in the + property attribute context. These values should remain contiguous + with the other property attributes. */ + RID_NULL_UNSPECIFIED, RID_NULLABLE, RID_NONNULL, RID_NULL_RESETTABLE, + /* C (reserved and imaginary types not implemented, so any use is a syntax error) */ RID_IMAGINARY, @@ -264,7 +269,7 @@ enum rid RID_FIRST_PQ = RID_IN, RID_LAST_PQ = RID_ONEWAY, RID_FIRST_PATTR = RID_GETTER, - RID_LAST_PATTR = RID_NONATOMIC + RID_LAST_PATTR = RID_NULL_RESETTABLE }; #define OBJC_IS_AT_KEYWORD(rid) \ diff --git a/gcc/c-family/c-objc.h b/gcc/c-family/c-objc.h index 9414aec..4b50260 100644 --- a/gcc/c-family/c-objc.h +++ b/gcc/c-family/c-objc.h @@ -44,6 +44,7 @@ enum objc_property_attribute_group OBJC_PROPATTR_GROUP_READWRITE, OBJC_PROPATTR_GROUP_ASSIGN, OBJC_PROPATTR_GROUP_ATOMIC, + OBJC_PROPATTR_GROUP_NULLABLE, OBJC_PROPATTR_GROUP_CLASS, OBJC_PROPATTR_GROUP_MAX }; @@ -60,6 +61,10 @@ enum objc_property_attribute_kind OBJC_PROPERTY_ATTR_COPY = ( 7 << 8)|OBJC_PROPATTR_GROUP_ASSIGN, OBJC_PROPERTY_ATTR_ATOMIC = ( 8 << 8)|OBJC_PROPATTR_GROUP_ATOMIC, OBJC_PROPERTY_ATTR_NONATOMIC = ( 9 << 8)|OBJC_PROPATTR_GROUP_ATOMIC, + OBJC_PROPERTY_ATTR_NULL_UNSPECIFIED = (12 << 8)|OBJC_PROPATTR_GROUP_NULLABLE, + OBJC_PROPERTY_ATTR_NULLABLE = (13 << 8)|OBJC_PROPATTR_GROUP_NULLABLE, + OBJC_PROPERTY_ATTR_NONNULL = (14 << 8)|OBJC_PROPATTR_GROUP_NULLABLE, + OBJC_PROPERTY_ATTR_NULL_RESETTABLE = (15 << 8)|OBJC_PROPATTR_GROUP_NULLABLE, OBJC_PROPERTY_ATTR_CLASS = (16 << 8)|OBJC_PROPATTR_GROUP_CLASS, OBJC_PROPERTY_ATTR_MAX = (255 << 8|OBJC_PROPATTR_GROUP_MAX) }; |