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).