From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2049) id 0B2C73856270; Thu, 5 May 2022 12:07:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0B2C73856270 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Matthew Malcomson To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/vendors/ARM/heads/morello)] Hybrid Morello: Simplify how we apply the __capability type attribute X-Act-Checkin: gcc X-Git-Author: Stam Markianos-Wright X-Git-Refname: refs/vendors/ARM/heads/morello X-Git-Oldrev: 07070a5388ca6a76e81d17da460f57b30afe7218 X-Git-Newrev: 0b964be7c94b5784ce5313348051b8205b6f7187 Message-Id: <20220505120722.0B2C73856270@sourceware.org> Date: Thu, 5 May 2022 12:07:22 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 May 2022 12:07:22 -0000 https://gcc.gnu.org/g:0b964be7c94b5784ce5313348051b8205b6f7187 commit 0b964be7c94b5784ce5313348051b8205b6f7187 Author: Stam Markianos-Wright Date: Mon Mar 21 23:04:27 2022 +0000 Hybrid Morello: Simplify how we apply the __capability type attribute This rectifies a mistake found in previous commit: fa7cfda The ATTR_FLAG_CHERI_INNER_APPLY applies to the sequence of cdk_pointer-s seen by grokdeclarator in the front-end, so given a type like: *** __capability ; This will be processed with the following sequence: cdk_pointer -> cdk_pointer -> cdk_pointer -> cdk_attribute and so when the attribute is handled, we want to apply __capability to the final cdk_pointer that was seen. However, in three representation this needs to be built as: __capability POINTER_TYPE -> POINTER_TYPE -> POINTER_TYPE -> Previously we would apply __capability to the final POINTER_TYPE, which was incorrect. Now we simply always apply to the first POINTER_TYPE that is seen in the loop. Secondly, when processing the deprecated way using __capability in declerations, e.g.: char __capability * x , *y ; char __capability * x2, ** __capability y2; (where the __capability that preceded the first `*` is seen as part of the type and apples to both x,y and x2,y2) we can get rid of the ATTR_FLAG_CHERI_INNER_APPLY flag and simplify the handling and with separate call from grokdeclarator. Diff: --- gcc/c-family/c-attribs.c | 88 ++++---------- gcc/c/c-decl.c | 130 ++++++++++++--------- gcc/c/c-parser.c | 6 +- .../aarch64/capability_attribute_invalid.c | 4 +- .../morello/capability_attribute_errors_1.c | 95 ++++++++------- .../aarch64/morello/capability_attribute_uses.c | 17 ++- .../morello/capability_attribute_warnings_1.c | 48 ++++---- gcc/tree-core.h | 1 - 8 files changed, 191 insertions(+), 198 deletions(-) diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index 5981e2ac477..67aaaa2b90f 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -798,78 +798,30 @@ handle_cheri_no_provenance_attribute (tree *node, tree name, } static tree -handle_cheri_capability_attribute (tree *node, tree ARG_UNUSED (name), - tree ARG_UNUSED (args), - int flags, bool *no_add_attrs) +handle_cheri_capability_attribute (tree *node, tree, tree, int, + bool *no_add_attrs) { *no_add_attrs = true; - if (targetm.capability_mode ().exists ()) - { - /* Scan down the tree *node and find how many - POINTER_TYPE_P nodes there are in the chain. */ - int capability_pointer_depth = 1, c = 1; - tree temp_tree = *node; - - bool found = false; - while (temp_tree) - { - /* MORELLO TODO: Here we could also use POINTER_TYPE_P, but that also - includes REFERENCE_TYPE which would then need a call to - `build_reference_type_for_mode`. I have not included this for now - but it may be needed in the future for C++ frontend support. */ - if (TREE_CODE (temp_tree) == POINTER_TYPE) - { - /* Find at what pointer depth we want to apply the __capability - attribute and store it in capability_pointer_depth: - 1) If given flag ATTR_FLAG_CHERI_INNER_APPLY, that - depth is the always the deepest one in the chain (always - update capability_pointer_depth from counter c). - 2) If no ATTR_FLAG_CHERI_INNER_APPLY flag has been given, - apply to the first first POINTER_TYPE in the chain. */ - if (flags & ATTR_FLAG_CHERI_INNER_APPLY) - { - capability_pointer_depth = c; - found = true; - } - else - { - if (found == false) - capability_pointer_depth = c; - found = true; - } - } - c++; - temp_tree = TREE_TYPE (temp_tree); - } - - if (!found) - { - error_at (input_location, "__capability only applies to pointers"); - return NULL_TREE; - } - - /* Now get a pointer to the tree in the *node chain given by - capability_pointer_depth and assert that it is correctly a - POINTER_TYPE_P. */ - tree *treetoedit = node; - for (int i = 1; i < capability_pointer_depth; i++) - treetoedit = &TREE_TYPE (*treetoedit); - gcc_assert (TREE_CODE (*treetoedit) == POINTER_TYPE); - - tree attrs = tree_cons (get_identifier ("cheri_capability"), NULL_TREE, - TYPE_ATTRIBUTES (*treetoedit)); - - /* Call build_pointer_type_for_mode to create a Capability Pointer - to whatever is being referenced by (*treetoedit). Then use - build_type_attribute_qual_variant to reapply the qualifiers and - attributes of the original pointer type. */ - auto quals = TYPE_QUALS (*treetoedit); - (*treetoedit) = build_type_attribute_qual_variant (*treetoedit, attrs, - quals); + if (!targetm.capability_mode ().exists ()) + error_at (input_location, "%<__capability%> attribute is not supported for" + "this architecture"); + else if (TREE_CODE (*node) != POINTER_TYPE) + error_at (input_location, "%<__capability%> only applies to pointers"); + else if (!capability_type_p (*node)) + { + /* MORELLO TODO: Here we could also use POINTER_TYPE_P, but that also + includes REFERENCE_TYPE which would then need a call to + `build_reference_type_for_mode`. I have not included this for now + but it may be needed in the future for C++ frontend support. */ + tree attrs = tree_cons (get_identifier ("cheri_capability"), + NULL_TREE, TYPE_ATTRIBUTES (*node)); + + /* Use build_type_attribute_qual_variant to reapply the + qualifiers and attributes of the original pointer type. */ + auto quals = TYPE_QUALS (*node); + (*node) = build_type_attribute_qual_variant (*node, attrs, quals); } - else - error ("__capability attribute is not supported for this architecture"); return NULL_TREE; } diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 2f63317ec4c..0c6722d95e8 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -5001,37 +5001,6 @@ c_decl_attributes (tree *node, tree attributes, int flags) return decl_attributes (node, attributes, flags, last_decl); } -static void -verify_cheri_capability_attribute_use (tree type, - int indirection_levels_in_declarator, - int capability_levels_in_declarator) -{ - /* Check the contents of the declspecs->type to detect the base type's level - of pointer indirection. */ - int indirection_levels_in_type = 0; - while (type) - { - if (TREE_CODE (type) == POINTER_TYPE) - indirection_levels_in_type++; - type = TREE_TYPE (type); - } - - /* Error as ambigous if: - There are more than 2 unmatch pointer indirections to the right - of the __capability attribute. - or: - The actual type given contains 2 or more pointer indirections. */ - if ((indirection_levels_in_declarator - - capability_levels_in_declarator >= 2 - && indirection_levels_in_type == 0) - || indirection_levels_in_type >=2) - error_at (input_location, "use of __capability is ambiguous"); - else if (indirection_levels_in_type == 0) - warning_at (input_location, OPT_Wdeprecated_declarations, - "use of __capability before the pointer type " - "is deprecated"); -} - /* Decode a declarator in an ordinary declaration or data definition. This is called as soon as the type information and variable name have been parsed, before parsing the initializer if any. @@ -6066,8 +6035,6 @@ grokdeclarator (const struct c_declarator *declarator, bool expr_const_operands_dummy; enum c_declarator_kind first_non_attr_kind; unsigned int alignas_align = 0; - int indirection_levels_in_declarator = 0; - int capability_levels_in_declarator = 0; if (TREE_CODE (type) == ERROR_MARK) return error_mark_node; @@ -6346,6 +6313,19 @@ grokdeclarator (const struct c_declarator *declarator, } } + /* Check if the cheri_capability attribute is in decl_attrs. If it is, then + we have a deprecated use of the __capability type attribute before the + `*` pointer indirection. For now, this is still supported. */ + bool deprecated_capability_attribute_use = false; + int deprecated_capability_uses = 0; + if (lookup_attribute ("cheri_capability", *decl_attrs)) + { + deprecated_capability_attribute_use = true; + /* Remove the __capability attribute from the decl attributes. */ + (*decl_attrs) = remove_attribute ("cheri_capability", + *decl_attrs); + } + /* Now figure out the structure of the declarator proper. Descend through it, creating more complex types, until we reach the declared identifier (or NULL_TREE, in an absolute declarator). @@ -6356,8 +6336,53 @@ grokdeclarator (const struct c_declarator *declarator, form and then the qualified form is created with TYPE_MAIN_VARIANT pointing to the unqualified form. */ - while (declarator && declarator->kind != cdk_id) + for (;;) { + /* For capability architectures that use the __capability attribute, + we need an additional check at the start to process the "deprecated" + use of the attribute before a `*`. In that case, the type attribute + is part of decl_attrs, not in the declarator, so it would not be + processed by this loop as a cdk_attrs. Hence, it needs to be + applied separately. */ + if (deprecated_capability_attribute_use + && POINTER_TYPE_P (type) + && (!declarator || declarator->kind != cdk_attrs)) + { + + /* When encoutering the first valid POINTER_TYPE, attempt to apply + the __capability attribute. */ + if (deprecated_capability_uses == 0) + { + /* Silently discard the attribute if the POINTER_TYPE is already + a capability. This happens when it has already been turned + into a capability by a valid use of the attribute, e.g.: + `int __capability * __capability x; */ + if (!capability_type_p (type)) + { + tree attr_name = get_identifier ("cheri_capability"); + tree new_attrs = tree_cons (attr_name, NULL_TREE, + returned_attrs); + returned_attrs = decl_attributes (&type, new_attrs, 0); + } + deprecated_capability_uses = 1; + + /* Raise the "deprecated declaration" warning, but only if the + original type was not a POINTER_TYPE_P typedef and regardless of + if the attribute was applied or skipped. */ + if (!POINTER_TYPE_P (declspecs->type)) + warning_at (input_location, OPT_Wdeprecated_declarations, + "use of %<__capability%> before the pointer type " + "is deprecated"); + } + /* On later iterations, simply count the number of non-capability + POINTER_TYPEs. */ + else if (!capability_type_p (type)) + deprecated_capability_uses++; + } + + if (!declarator || declarator->kind == cdk_id) + break; + if (type == error_mark_node) { declarator = declarator->declarator; @@ -6423,11 +6448,6 @@ grokdeclarator (const struct c_declarator *declarator, attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT; } - if (lookup_attribute ("cheri_capability", attrs)) - { - capability_levels_in_declarator++; - attr_flags |= (int) ATTR_FLAG_CHERI_INNER_APPLY; - } attrs = c_warn_type_attributes (attrs); returned_attrs = decl_attributes (&type, chainon (returned_attrs, attrs), @@ -6917,7 +6937,6 @@ grokdeclarator (const struct c_declarator *declarator, } case cdk_pointer: { - indirection_levels_in_declarator++; /* Merge any constancy or volatility into the target type for the pointer. */ if ((type_quals & TYPE_QUAL_ATOMIC) @@ -7005,11 +7024,10 @@ grokdeclarator (const struct c_declarator *declarator, declarator = declarator->declarator; if (test_fake_hybrid ()) { - capability_levels_in_declarator++; tree attr_name = get_identifier ("cheri_capability"); // tree attr_args = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); tree new_attrs = tree_cons (attr_name, NULL_TREE, returned_attrs); - returned_attrs = decl_attributes (&type, new_attrs, ATTR_FLAG_CHERI_INNER_APPLY); + returned_attrs = decl_attributes (&type, new_attrs, 0); } break; } @@ -7018,16 +7036,24 @@ grokdeclarator (const struct c_declarator *declarator, } } - /* If one of initial the decl_attrs given is the cheri_capability attribute, - verify for unambiguous use of the attribute. */ - if (lookup_attribute ("cheri_capability", *decl_attrs)) - verify_cheri_capability_attribute_use (declspecs->type, - indirection_levels_in_declarator, - capability_levels_in_declarator); - - *decl_attrs = chainon (returned_attrs, *decl_attrs); - *decl_attrs = chainon (decl_id_attrs, *decl_attrs); - + /* If after the above loop we get here and haven't applied the "deprecated" + __capability attribute then it was either on a POINTER_TYPE_P where all + indirection levels were already capabilities, or on a non-pointer type, + in which case raise an error. */ + if (deprecated_capability_attribute_use + && deprecated_capability_uses == 0) + error_at (input_location, "%<__capability%> only applies to pointers"); + + /* If we had been given a `deprecated_capability_attribute_use` and applied + it to the decl, but: + - There are more than 1 `*` non-pointer indirections to the right of the + __capability attribute. + - The original type was not a POINTER_TYPE_P typedef (if it was, + the __capability would apply inside the typedef). */ + if (deprecated_capability_attribute_use + && deprecated_capability_uses > 1 + && !POINTER_TYPE_P (declspecs->type)) + error_at (input_location, "use of %<__capability%> is ambiguous"); /* Now TYPE has the actual type, apart from any qualifiers in TYPE_QUALS. */ diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 8523c1b3b0c..70b267775f1 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -2201,7 +2201,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, if (lookup_attribute ("cheri_capability", postfix_attrs)) { error_at (here, - "__capability type specifier must" + "%<__capability%> type specifier must" " precede the declarator"); c_parser_skip_to_end_of_block_or_statement (parser); return; @@ -3657,7 +3657,7 @@ c_parser_struct_declaration (c_parser *parser) postfix_attrs = c_parser_gnu_attributes (parser); if (lookup_attribute ("cheri_capability", postfix_attrs)) - c_parser_error (parser, "__capability type specifier must" + c_parser_error (parser, "%<__capability%> type specifier must" " precede the declarator"); d = grokfield (c_parser_peek_token (parser)->location, @@ -4433,7 +4433,7 @@ c_parser_parameter_declaration (c_parser *parser, tree attrs, if (lookup_attribute ("cheri_capability", postfix_attrs)) { - error ("__capability type specifier must" + error ("%<__capability%> type specifier must" " precede the declarator"); c_parser_skip_to_end_of_parameter (parser); return NULL; diff --git a/gcc/testsuite/gcc.target/aarch64/capability_attribute_invalid.c b/gcc/testsuite/gcc.target/aarch64/capability_attribute_invalid.c index 647a7c9d6ef..f679c7cb1f2 100644 --- a/gcc/testsuite/gcc.target/aarch64/capability_attribute_invalid.c +++ b/gcc/testsuite/gcc.target/aarch64/capability_attribute_invalid.c @@ -4,5 +4,5 @@ is conditionally enabled on having a capability type enabled: targetm.capability_mode (), so in the first case we do ugly-error instead of gracefully-error. */ int * __capability var1; /* { dg-error "" } */ -int * __attribute__((__cheri_capability__)) var2; /* { dg-error "__capability attribute is not supported for this architecture" } */ -int * __attribute__((cheri_capability)) var3; /* { dg-error "__capability attribute is not supported for this architecture" } */ +int * __attribute__((__cheri_capability__)) var2; /* { dg-error "'__capability' attribute is not supported for this architecture" } */ +int * __attribute__((cheri_capability)) var3; /* { dg-error "'__capability' attribute is not supported for this architecture" } */ diff --git a/gcc/testsuite/gcc.target/aarch64/morello/capability_attribute_errors_1.c b/gcc/testsuite/gcc.target/aarch64/morello/capability_attribute_errors_1.c index 555ee5356d0..2de8c2d0dab 100644 --- a/gcc/testsuite/gcc.target/aarch64/morello/capability_attribute_errors_1.c +++ b/gcc/testsuite/gcc.target/aarch64/morello/capability_attribute_errors_1.c @@ -1,75 +1,86 @@ /* { dg-do compile { target aarch64*-*-* } } */ +/* { dg-skip-if "" { *-*-* } { "-mabi=purecap" "-mfake-capability" } { "" } } */ /* Error on non-pointers. */ -int __capability var1; /* { dg-error "__capability only applies to pointers" } */ -/* { dg-warning "use of __capability before the pointer type is deprecated" "" { target *-*-* } .-1 } */ -__capability int var2; /* { dg-error "__capability only applies to pointers" } */ -/* { dg-warning "use of __capability before the pointer type is deprecated" "" { target *-*-* } .-1 } */ -int var3 __capability; /* { dg-error "__capability type specifier must precede the declarator" } */ -char __capability string1[] = "abcdef" ; /* { dg-error "__capability only applies to pointers" } */ -/* { dg-warning "use of __capability before the pointer type is deprecated" "" { target *-*-* } .-1 } */ -void f1 (int __capability x); /* { dg-error "__capability only applies to pointers" } */ -/* { dg-warning "use of __capability before the pointer type is deprecated" "" { target *-*-* } .-1 } */ -void __capability f2 (); /* { dg-error "__capability only applies to pointers" } */ -/* { dg-warning "use of __capability before the pointer type is deprecated" "" { target *-*-* } .-1 } */ -int __capability f3 (); /* { dg-error "__capability only applies to pointers" } */ -/* { dg-warning "use of __capability before the pointer type is deprecated" "" { target *-*-* } .-1 } */ +int __capability var1; /* { dg-error "'__capability' only applies to pointers" } */ +__capability int var2; /* { dg-error "'__capability' only applies to pointers" } */ +int var3 __capability; /* { dg-error "'__capability' type specifier must precede the declarator" } */ +char __capability string1[] = "abcdef" ; /* { dg-error "'__capability' only applies to pointers" } */ +void f1 (int __capability x); /* { dg-error "'__capability' only applies to pointers" } */ +void __capability f2 (); /* { dg-error "'__capability' only applies to pointers" } */ +int __capability f3 (); /* { dg-error "'__capability' only applies to pointers" } */ -typedef int __capability noncapptr; /* { dg-error "__capability only applies to pointers" } */ -/* { dg-warning "use of __capability before the pointer type is deprecated" "" { target *-*-* } .-1 } */ +typedef int __capability noncapptr; /* { dg-error "'__capability' only applies to pointers" } */ /* Improper ordering: Error cases. */ -int * var4 __capability ; /* { dg-error "__capability type specifier must precede the declarator" } */ -int *var5 __capability; /* { dg-error "__capability type specifier must precede the declarator" } */ -int* var6 __capability; /* { dg-error "__capability type specifier must precede the declarator" } */ -int __capability **var7; /* { dg-error "use of __capability is ambiguous" } */ -__capability int ** var8; /* { dg-error "use of __capability is ambiguous" } */ -int __capability ** var9; /* { dg-error "use of __capability is ambiguous" } */ +int * var4 __capability ; /* { dg-error "'__capability' type specifier must precede the declarator" } */ +int *var5 __capability; /* { dg-error "'__capability' type specifier must precede the declarator" } */ +int* var6 __capability; /* { dg-error "'__capability' type specifier must precede the declarator" } */ +int __capability **var7; /* { dg-error "use of '__capability' is ambiguous" } */ +/* { dg-warning "use of '__capability' before the pointer type is deprecated" "" { target *-*-* } .-1 } */ +__capability int ** var8; /* { dg-error "use of '__capability' is ambiguous" } */ +/* { dg-warning "use of '__capability' before the pointer type is deprecated" "" { target *-*-* } .-1 } */ +int __capability ** var9; /* { dg-error "use of '__capability' is ambiguous" } */ +/* { dg-warning "use of '__capability' before the pointer type is deprecated" "" { target *-*-* } .-1 } */ +__capability int *__capability **z91; /* { dg-error "use of '__capability' is ambiguous" } */ +/* { dg-warning "use of '__capability' before the pointer type is deprecated" "" { target *-*-* } .-1 } */ +__capability int *__capability **z92; /* { dg-error "use of '__capability' is ambiguous" } */ +/* { dg-warning "use of '__capability' before the pointer type is deprecated" "" { target *-*-* } .-1 } */ +__capability int *__capability ***z93; /* { dg-error "use of '__capability' is ambiguous" } */ +/* { dg-warning "use of '__capability' before the pointer type is deprecated" "" { target *-*-* } .-1 } */ +__capability int *__capability ***z94; /* { dg-error "use of '__capability' is ambiguous" } */ +/* { dg-warning "use of '__capability' before the pointer type is deprecated" "" { target *-*-* } .-1 } */ +__capability int *__capability **__capability z1;/* { dg-error "use of '__capability' is ambiguous" } */ +/* { dg-warning "use of '__capability' before the pointer type is deprecated" "" { target *-*-* } .-1 } */ -__capability int * __capability * var10; /* { dg-error "use of __capability is ambiguous" "" { xfail *-*-* } } */ -/* { dg-warning "use of __capability before the pointer type is deprecated" "" { target *-*-* } .-1 } */ -int __capability * __capability * var11; /* { dg-error "use of __capability is ambiguous" "" { xfail *-*-* } } */ -/* { dg-warning "use of __capability before the pointer type is deprecated" "" { target *-*-* } .-1 } */ +__capability int * __capability * var10; /* { dg-error "use of '__capability' is ambiguous" } */ +/* { dg-warning "use of '__capability' before the pointer type is deprecated" "" { target *-*-* } .-1 } */ +int __capability * __capability * var11; /* { dg-error "use of '__capability' is ambiguous" } */ +/* { dg-warning "use of '__capability' before the pointer type is deprecated" "" { target *-*-* } .-1 } */ /* Adding attribute to a function. Improper ordering: Error cases. */ -void *f4 __capability (void); /* { dg-error "__capability type specifier must precede the declarator" } */ -void (*f5) __capability (void); /* { dg-error "__capability type specifier must precede the declarator" } */ -void* f6 __capability (void); /* { dg-error "__capability type specifier must precede the declarator" } */ -int *f7 __capability (void); /* { dg-error "__capability type specifier must precede the declarator" } */ -int* f8 __capability (void); /* { dg-error "__capability type specifier must precede the declarator" } */ -int* f9 (void) __capability; /* { dg-error "__capability type specifier must precede the declarator" } */ +void *f4 __capability (void); /* { dg-error "'__capability' type specifier must precede the declarator" } */ +void (*f5) __capability (void); /* { dg-error "'__capability' type specifier must precede the declarator" } */ +void* f6 __capability (void); /* { dg-error "'__capability' type specifier must precede the declarator" } */ +int *f7 __capability (void); /* { dg-error "'__capability' type specifier must precede the declarator" } */ +int* f8 __capability (void); /* { dg-error "'__capability' type specifier must precede the declarator" } */ +int* f9 (void) __capability; /* { dg-error "'__capability' type specifier must precede the declarator" } */ /* Adding attribute to a function parameter. Improper ordering: Error cases. */ -void f10 (int* var12 __capability);/* { dg-error "__capability type specifier must precede the declarator" } */ -void f11 (int *var13 __capability);/* { dg-error "__capability type specifier must precede the declarator" } */ -void f12 (int __capability ** var14); /* { dg-error "use of __capability is ambiguous" } */ -void f13 (__capability int ** var15); /* { dg-error "use of __capability is ambiguous" } */ +void f10 (int* var12 __capability);/* { dg-error "'__capability' type specifier must precede the declarator" } */ +void f11 (int *var13 __capability);/* { dg-error "'__capability' type specifier must precede the declarator" } */ +void f12 (int __capability ** var14); /* { dg-error "use of '__capability' is ambiguous" } */ +/* { dg-warning "use of '__capability' before the pointer type is deprecated" "" { target *-*-* } .-1 } */ +void f13 (__capability int ** var15); /* { dg-error "use of '__capability' is ambiguous" } */ +/* { dg-warning "use of '__capability' before the pointer type is deprecated" "" { target *-*-* } .-1 } */ /* Putting int* in a typedef... */ typedef int* intptr; -intptr var16 __capability; /* { dg-error "__capability type specifier must precede the declarator" } */ -intptr* var17 __capability; /* { dg-error "__capability type specifier must precede the declarator" } */ +intptr var16 __capability; /* { dg-error "'__capability' type specifier must precede the declarator" } */ +intptr* var17 __capability; /* { dg-error "'__capability' type specifier must precede the declarator" } */ /* Putting int*__capability in a typedef... */ typedef int * __capability intptr2; -intptr2* var18 __capability; /* { dg-error "__capability type specifier must precede the declarator" } */ +intptr2* var18 __capability; /* { dg-error "'__capability' type specifier must precede the declarator" } */ /* Try putting pointers in a struct. */ struct cheri_object1 { - void *var19 __capability, *var20; /* { dg-error "__capability type specifier must precede the declarator" } */ + void *var19 __capability, *var20; /* { dg-error "'__capability' type specifier must precede the declarator" } */ }; struct cheri_object2 { - void * var19, *var20 __capability; /* { dg-error "__capability type specifier must precede the declarator" } */ + void * var19, *var20 __capability; /* { dg-error "'__capability' type specifier must precede the declarator" } */ }; struct cheri_object3 { int *var19; - int __capability ** var20; /* { dg-error "use of __capability is ambiguous" } */ + int __capability ** var20; /* { dg-error "use of '__capability' is ambiguous" } */ + /* { dg-warning "use of '__capability' before the pointer type is deprecated" "" { target *-*-* } .-1 } */ }; struct cheri_object4 { int *var19; - __capability int **var20; /* { dg-error "use of __capability is ambiguous" } */ + __capability int **var20; /* { dg-error "use of '__capability' is ambiguous" } */ + /* { dg-warning "use of '__capability' before the pointer type is deprecated" "" { target *-*-* } .-1 } */ }; diff --git a/gcc/testsuite/gcc.target/aarch64/morello/capability_attribute_uses.c b/gcc/testsuite/gcc.target/aarch64/morello/capability_attribute_uses.c index 404ffb8d12f..0d8ff01fa55 100644 --- a/gcc/testsuite/gcc.target/aarch64/morello/capability_attribute_uses.c +++ b/gcc/testsuite/gcc.target/aarch64/morello/capability_attribute_uses.c @@ -1,11 +1,11 @@ -/* { dg-do run { target aarch64*-*-* } } */ +/* { dg-do compile { target aarch64*-*-* } } */ /* { dg-additional-options "-Wno-declaration-after-statement" } */ #include -char* __capability stringpointer = "abcdef"; char * __capability returncapabilitytest () { + char* __capability stringpointer = "abcdef"; char *__capability arraystart; arraystart = stringpointer; return arraystart; @@ -33,6 +33,8 @@ int** __capability var11; int * __capability * __capability var12; int * __capability *var13; void * __capability * __capability var14, ** __capability var15; +int * __capability *__capability * __capability var24; +int **** __capability var25; /* Putting int* in a typedef... */ typedef int* intptr; @@ -44,8 +46,13 @@ intptr* __capability * var20; intptr __capability ** var21; intptr __capability ** __capability var22; intptr __capability *__capability * __capability var23; -int * __capability *__capability * __capability var24; -int **** __capability var25; + +/* Putting int* in a typedef should also support the "deprecated" use. */ +__capability intptr z13; +__capability intptr __capability z14; +__capability intptr * __capability z15; +__capability intptr *z16; +__capability intptr ***z17; /* Putting int*__capability in a typedef... */ typedef int * __capability intptr2; @@ -84,6 +91,8 @@ char *__attribute__((__cheri_capability__, __used__)) attrtestvar4; /* And a quick runtime test. */ int main() { + char* __capability stringpointer = "abcdef"; + /* Simple pass a capability address to a function. */ passcapabilitytest (stringpointer); diff --git a/gcc/testsuite/gcc.target/aarch64/morello/capability_attribute_warnings_1.c b/gcc/testsuite/gcc.target/aarch64/morello/capability_attribute_warnings_1.c index 0efc1c8cb2a..46c782d9a34 100644 --- a/gcc/testsuite/gcc.target/aarch64/morello/capability_attribute_warnings_1.c +++ b/gcc/testsuite/gcc.target/aarch64/morello/capability_attribute_warnings_1.c @@ -1,46 +1,42 @@ /* { dg-do compile { target aarch64*-*-* } } */ +/* { dg-skip-if "" { *-*-* } { "-mabi=purecap" "-mfake-capability" } { "" } } */ /* Improper ordering: Warning cases. */ -int __capability *var1; /* { dg-warning "use of __capability before the pointer type is deprecated" } */ -__capability int *var2; /* { dg-warning "use of __capability before the pointer type is deprecated" } */ -__capability int ** __capability var3; /* { dg-warning "use of __capability before the pointer type is deprecated" } */ -__capability void *var4, *var5; /* { dg-warning "use of __capability before the pointer type is deprecated" } */ -void __capability *var6, *var7; /* { dg-warning "use of __capability before the pointer type is deprecated" } */ -void *var8, __capability *var9; /* { dg-warning "use of __capability before the pointer type is deprecated" } */ +int __capability *var1; /* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ +__capability int *var2; /* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ +__capability int ** __capability var3; /* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ +__capability void *var4, *var5; /* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ +void __capability *var6, *var7; /* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ +void *var8, __capability *var9; /* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ +__capability int **__capability z2;/* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ +__capability int *__capability z3; /* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ /* Adding attribute to a function. Improper ordering: Warning cases. */ -__capability void *f1 (void);/* { dg-warning "use of __capability before the pointer type is deprecated" } */ -__capability void* f2 (void);/* { dg-warning "use of __capability before the pointer type is deprecated" } */ -void __capability *f3 (void);/* { dg-warning "use of __capability before the pointer type is deprecated" } */ -__capability int *f4 (void);/* { dg-warning "use of __capability before the pointer type is deprecated" } */ -__capability int* f5 (void);/* { dg-warning "use of __capability before the pointer type is deprecated" } */ -__capability int (*f6) (void); /* { dg-warning "use of __capability before the pointer type is deprecated" } */ -int __capability *f7 (void); /* { dg-warning "use of __capability before the pointer type is deprecated" } */ +__capability void *f1 (void);/* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ +__capability void* f2 (void);/* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ +void __capability *f3 (void);/* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ +__capability int *f4 (void);/* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ +__capability int* f5 (void);/* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ +__capability int (*f6) (void); /* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ +int __capability *f7 (void); /* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ /* Adding attribute to a function parameter. Improper ordering: Warning cases. */ -void f14 (int __capability *var10); /* { dg-warning "use of __capability before the pointer type is deprecated" } */ -void f15 (int __capability* var11); /* { dg-warning "use of __capability before the pointer type is deprecated" } */ -void f16 (__capability int *var12); /* { dg-warning "use of __capability before the pointer type is deprecated" } */ - -/* Putting int* in a typedef... */ -typedef int* intptr; -__capability intptr var13; /* { dg-warning "use of __capability before the pointer type is deprecated" "" { xfail *-*-* } } */ -__capability intptr __capability var14; /* { dg-warning "use of __capability before the pointer type is deprecated" "" { xfail *-*-* } } */ -__capability intptr * __capability var15; /* { dg-warning "use of __capability before the pointer type is deprecated" "" { xfail *-*-* } } */ -__capability intptr *var16; /* { dg-warning "use of __capability before the pointer type is deprecated" "" { xfail *-*-* } } */ +void f14 (int __capability *var10); /* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ +void f15 (int __capability* var11); /* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ +void f16 (__capability int *var12); /* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ /* Putting improper ordering : int __capability * in a typedef... */ -typedef int __capability *i_p; /* { dg-warning "use of __capability before the pointer type is deprecated" } */ +typedef int __capability *i_p; /* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ i_p g8; /* Try putting pointers in a struct. */ struct cheri_object1 { - __capability void *var17, *var18; /* { dg-warning "use of __capability before the pointer type is deprecated" } */ + __capability void *var17, *var18; /* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ }; struct cheri_object2 { - void __capability *var17, *var18; /* { dg-warning "use of __capability before the pointer type is deprecated" } */ + void __capability *var17, *var18; /* { dg-warning "use of '__capability' before the pointer type is deprecated" } */ }; /* This seems to be a generic parser error with the handling of type attributes in general? diff --git a/gcc/tree-core.h b/gcc/tree-core.h index b03d7164c08..7f90eec095c 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -865,7 +865,6 @@ enum attribute_flags { ATTR_FLAG_BUILT_IN = 16, /* A given attribute has been parsed as a C++-11 attribute. */ ATTR_FLAG_CXX11 = 32, - ATTR_FLAG_CHERI_INNER_APPLY = 64 }; /* Types used to represent sizes. */