public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] c: Fix hybrid null pointer to capability conversions
@ 2023-03-13 18:12 Alex Coplan
  0 siblings, 0 replies; only message in thread
From: Alex Coplan @ 2023-03-13 18:12 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:44079a7439fad52702678b4526bb60b90a577e7f

commit 44079a7439fad52702678b4526bb60b90a577e7f
Author: Alex Coplan <alex.coplan@arm.com>
Date:   Fri Mar 3 18:13:03 2023 +0000

    c: Fix hybrid null pointer to capability conversions
    
    Currently for e.g.:
    
    void * __capability f(void) { return (void *)0; }
    
    on hybrid Morello, we produce a DDC-derived capability:
    
    f:
            mrs     c0, DDC
            mov     x1, 0
            scvalue c0, c0, x1
            ret
    
    but we should follow LLVM in treating the null pointer constant
    (void *)0 as a special case and generate a proper null capability.
    This patch does that, and we now generate:
    
    f:
            mov     x0, xzr
            ret
    
    We also adjust the new warning in build_conditional_expr to avoid
    warning for this case (implicitly converting a non-capability null
    pointer constant to capability pointer type).

Diff:
---
 gcc/c-family/c-common.c                                 | 12 ++++++++++--
 gcc/c/c-typeck.c                                        | 17 ++++++++++++-----
 .../aarch64/morello/hybrid-cap-ptr-glob-init-errors.c   |  1 -
 .../gcc.target/aarch64/morello/hybrid-cond-expr.c       | 12 ++++++++++++
 gcc/testsuite/gcc.target/aarch64/morello/hybrid-null.c  | 12 ++++++++++++
 5 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index e0c7f18fd5d..3f83e5bf234 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -2689,8 +2689,16 @@ c_common_cap_from_ptr (tree type, tree ptr_expr)
     int_expr = c_fully_fold (int_expr, false, NULL);
 
   location_t loc = EXPR_LOCATION (int_expr);
-  tree ret = fold_build_replace_address_value_loc
-	       (loc, build_cap_global_data_get_loc (loc, type), int_expr);
+
+  tree ret;
+  if (integer_zerop (int_expr))
+    /* Converting from null pointer should give null capability.  */
+    ret = build_zero_cst (type);
+  else
+    {
+      ret = build_cap_global_data_get_loc (loc, type);
+      ret = fold_build_replace_address_value_loc (loc, ret, int_expr);
+    }
 
   return ret;
 }
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 998d1c469d6..9274f8b3509 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -5510,11 +5510,18 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
       if (capability_type_p (type1) != capability_type_p (type2))
 	{
 	  gcc_assert (capability_type_p (result_type));
-	  tree noncap_type = capability_type_p (type1) ? type2 : type1;
-	  location_t noncap_loc = (noncap_type == type2) ? op2_loc : op1_loc;
-	  warning_at (noncap_loc, OPT_Wcheri_implicit_pointer_conversion_to_cap,
-		      "converting non-capability type %qT to capability type "
-		      "%qT without an explicit cast", noncap_type, result_type);
+	  const bool cap1 = capability_type_p (type1);
+	  tree noncap_op = cap1 ? op2 : op1;
+	  if (!integer_zerop (noncap_op))
+	    {
+	      tree noncap_type = cap1 ? type2 : type1;
+	      location_t noncap_loc = cap1 ? op2_loc : op1_loc;
+	      warning_at (noncap_loc,
+			  OPT_Wcheri_implicit_pointer_conversion_to_cap,
+			  "converting non-capability type %qT to capability "
+			  "type %qT without an explicit cast",
+			   noncap_type, result_type);
+	    }
 	}
     }
   else if (code1 == POINTER_TYPE
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/hybrid-cap-ptr-glob-init-errors.c b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-cap-ptr-glob-init-errors.c
index eb44f11b037..c95fcb9baf6 100644
--- a/gcc/testsuite/gcc.target/aarch64/morello/hybrid-cap-ptr-glob-init-errors.c
+++ b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-cap-ptr-glob-init-errors.c
@@ -9,7 +9,6 @@ __intcap_t intcapvar;
 __uintcap_t uintcapvar;
 
 /* First test a number of simple assignments from something to a capability pointer.  */
-int * __capability a2 = (int *) 0; /* { dg-error "initializer element is not valid for capability type" } */
 int * __capability b2 = (int *) 1; /* { dg-error "initializer element is not valid for capability type" } */
 /* { dg-warning "converting non-capability pointer to capability pointer without an explicit cast" "" { target *-*-* } .-1 } */
 int * __capability c2 = (int *) x; /* { dg-warning "cast to pointer from integer of different size" } */
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/hybrid-cond-expr.c b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-cond-expr.c
index 4b7b0ad1161..02183ea1eb2 100644
--- a/gcc/testsuite/gcc.target/aarch64/morello/hybrid-cond-expr.c
+++ b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-cond-expr.c
@@ -126,3 +126,15 @@ void * __capability void7 (int x19, void * __capability p19, struct S2 * __capab
   return x19 ? p19 : &q19->a;
 }
 /* { dg-final { scan-tree-dump-times {return x19 == 0 \? \(void \* __capability\) &q19->a : p19;} 1 "original" } } */
+
+char * __capability null1 (int x20, char * __capability p20)
+{
+  return x20 ? p20 : (void *)0;
+}
+/* { dg-final { scan-tree-dump-times {return x20 != 0 \? p20 : 0B;} 1 "original" } } */
+
+char * __capability null2 (int x21, char * __capability p21)
+{
+  return x21 ? (void *)0 : p21;
+}
+/* { dg-final { scan-tree-dump-times {return x21 == 0 \? p21 : 0B;} 1 "original" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/hybrid-null.c b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-null.c
new file mode 100644
index 00000000000..42df410b3de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-null.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/*
+** foo:
+** 	mov	x0, xzr
+** 	ret
+*/
+char * __capability foo(void)
+{
+  return (void *)0;
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-03-13 18:12 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-13 18:12 [gcc(refs/vendors/ARM/heads/morello)] c: Fix hybrid null pointer to capability conversions Alex Coplan

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