public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] Hybrid Morello: Simplify how we apply the __capability type attribute
@ 2022-05-05 12:07 Matthew Malcomson
0 siblings, 0 replies; only message in thread
From: Matthew Malcomson @ 2022-05-05 12:07 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:0b964be7c94b5784ce5313348051b8205b6f7187
commit 0b964be7c94b5784ce5313348051b8205b6f7187
Author: Stam Markianos-Wright <stam.markianos-wright@arm.com>
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:
<type> *** __capability <variable>;
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 -> <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 <stdio.h>
-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. */
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-05-05 12:07 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-05 12:07 [gcc(refs/vendors/ARM/heads/morello)] Hybrid Morello: Simplify how we apply the __capability type attribute Matthew Malcomson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).