public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] cp: Handle various capability conversions
@ 2022-03-14 10:34 Matthew Malcomson
  0 siblings, 0 replies; only message in thread
From: Matthew Malcomson @ 2022-03-14 10:34 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:69cb7c2d4b5afe9be7e023ae1a139eadfbbfe816

commit 69cb7c2d4b5afe9be7e023ae1a139eadfbbfe816
Author: Alex Coplan <alex.coplan@arm.com>
Date:   Mon Jan 31 14:12:29 2022 +0000

    cp: Handle various capability conversions
    
    This patch implements:
     - Casting from integers to capability pointers.
     - Implicit conversions from integer to intcap.
     - Handle pointer to intcap conversions.
    
    Here we make a decision on where INTCAP_TYPE fits into the hierarcy set
    out in cp-tree.h of CP_INTEGRAL_TYPE_P < ARITHMETIC_TYPE_P <
    SCALAR_TYPE_P. With the initial C work, we made the decision that
    INTCAP_TYPEs will not be INTEGRAL_TYPE_P. Since the types satisfying
    CP_INTEGRAL_TYPE_P are a strict subset of INTEGRAL_TYPE_P, it follows
    that INTCAP_TYPEs should not be CP_INTEGRAL_TYPE_P.
    
    ARITHMETIC_TYPE_P then extends CP_INTEGRAL_TYPE_P with real and complex
    types. We choose not to add INTCAP_TYPE here, since it's not possible to
    perform arithmetic on INTCAP_TYPEs directly. Instead, we add them to
    SCALAR_TYPE_P, along with the other preexisting pointer types and such.
    
    As follow-on work, it will be necessary to audit places using
    [CP_]INTEGRAL_TYPE_P and ARITHMETIC_TYPE_P to ensure that either that is
    unreachable with INTCAP_TYPE or has the correct behaviour for
    INTCAP_TYPE.
    
    Notes on implementation: I considered using c_common_cap_from_noncap,
    but the routine needs to use convert internally for an integer
    conversion, and it made more sense to use the cp_convert function for
    C++, and we also want to pass around the "complain" flags for C++, so at
    this point defining a C++-specific routine seemed to make more sense.
    
    gcc/cp/ChangeLog:
    
            * call.c (standard_conversion): Handle implicit conversions from
            integer to intcap.
            * cp-tree.h (SCALAR_TYPE_P): Return true for INTCAP_TYPEs.
            * cvt.c (cp_cap_from_noncap): New. Use it ...
            (cp_convert_to_pointer): ... here, and ...
            (ocp_convert): ... here (for converting to INTCAP_TYPE).
            * typeck.c (build_reinterpret_cast_1): Allow reinterpret_casting
            between suitably-sized integers and INTCAP_TYPE.

Diff:
---
 gcc/cp/call.c    |  2 +-
 gcc/cp/cp-tree.h |  3 ++-
 gcc/cp/cvt.c     | 25 +++++++++++++++++++++++++
 gcc/cp/typeck.c  |  4 ++--
 4 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 4726e57a30d..c0c52120e14 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1482,7 +1482,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
   /* We don't check for ENUMERAL_TYPE here because there are no standard
      conversions to enum type.  */
   /* As an extension, allow conversion to complex type.  */
-  else if (ARITHMETIC_TYPE_P (to))
+  else if (ARITHMETIC_TYPE_P (to) || INTCAP_TYPE_P (to))
     {
       if (! (INTEGRAL_CODE_P (fcode)
 	     || (fcode == REAL_TYPE && !(flags & LOOKUP_NO_NON_INTEGRAL)))
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 2b7c9b9913a..c2491673e94 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4195,7 +4195,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
    || ARITHMETIC_TYPE_P (TYPE)			\
    || TYPE_PTR_P (TYPE)				\
    || TYPE_PTRMEMFUNC_P (TYPE)                  \
-   || NULLPTR_TYPE_P (TYPE))
+   || NULLPTR_TYPE_P (TYPE)			\
+   || INTCAP_TYPE_P (TYPE))
 
 /* Determines whether this type is a C++0x scoped enumeration
    type. Scoped enumerations types are introduced via "enum class" or
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 4869cb096a7..a36a3cce8af 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -42,6 +42,21 @@ static tree build_type_conversion (tree, tree);
 static tree build_up_reference (tree, tree, int, tree, tsubst_flags_t);
 static void diagnose_ref_binding (location_t, tree, tree, tree);
 
+static tree
+cp_cap_from_noncap (tree type, tree expr, tsubst_flags_t complain)
+{
+  gcc_assert (capability_type_p (type)
+	      && !capability_type_p (TREE_TYPE (expr)));
+
+  if (TREE_TYPE (expr) != noncapability_type (type))
+    expr = cp_convert (noncapability_type (type), expr, complain);
+
+  location_t loc = EXPR_LOCATION (expr);
+  return fold_build_replace_address_value_loc (loc,
+					       build_int_cst (type, 0),
+					       expr);
+}
+
 /* Change of width--truncation and extension of integers or reals--
    is represented with NOP_EXPR.  Proper functioning of many things
    assumes that no other conversions can be NOP_EXPRs.
@@ -230,6 +245,9 @@ cp_convert_to_pointer (tree type, tree expr, bool dofold,
 
   if (INTEGRAL_CODE_P (form))
     {
+      if (capability_type_p (type))
+	return cp_cap_from_noncap (type, expr, complain);
+
       if (TYPE_PRECISION (intype) == POINTER_SIZE)
 	return build1 (CONVERT_EXPR, type, expr);
       expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr,
@@ -878,6 +896,13 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
       /* Ignore any integer overflow caused by the conversion.  */
       return ignore_overflows (converted, e);
     }
+  if (INTCAP_TYPE_P (type))
+    {
+      if (!capability_type_p (TREE_TYPE (e)))
+	return cp_cap_from_noncap (type, e, complain);
+      else
+	return convert_to_intcap_maybe_fold (type, e, dofold);
+    }
   if (INDIRECT_TYPE_P (type) || TYPE_PTRMEM_P (type))
     return cp_convert_to_pointer (type, e, dofold, complain);
   if (code == VECTOR_TYPE)
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 5de36ddf0ce..cb049ce708c 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -7885,10 +7885,10 @@ build_reinterpret_cast_1 (location_t loc, tree type, tree expr,
      hold it. ... A value of type std::nullptr_t can be converted to
      an integral type; the conversion has the same meaning and
      validity as a conversion of (void*)0 to the integral type.  */
-  if (CP_INTEGRAL_TYPE_P (type)
+  if ((CP_INTEGRAL_TYPE_P (type) || INTCAP_TYPE_P (type))
       && (TYPE_PTR_P (intype) || NULLPTR_TYPE_P (intype)))
     {
-      if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
+      if (TYPE_NONCAP_PRECISION (type) < TYPE_NONCAP_PRECISION (intype))
         {
           if (complain & tf_error)
             permerror (loc, "cast from %qH to %qI loses precision",


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

only message in thread, other threads:[~2022-03-14 10:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-14 10:34 [gcc(refs/vendors/ARM/heads/morello)] cp: Handle various capability conversions 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).