public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] cp: Initial support for binary ops on INTCAP_TYPEs
@ 2022-03-14 10:35 Matthew Malcomson
0 siblings, 0 replies; only message in thread
From: Matthew Malcomson @ 2022-03-14 10:35 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:cd8be6344fa7e046bce4d091e232edcd2d6e6bd9
commit cd8be6344fa7e046bce4d091e232edcd2d6e6bd9
Author: Alex Coplan <alex.coplan@arm.com>
Date: Fri Feb 4 11:40:50 2022 +0000
cp: Initial support for binary ops on INTCAP_TYPEs
This patch is mostly just lifting code from the C frontend: we could
consider refactoring to move some of the code to c-common.c, perhaps.
gcc/cp/ChangeLog:
* typeck.c (cp_common_type): Handle INTCAP_TYPEs, similar to C
frontend.
(cp_build_binary_op): Likewise.
Diff:
---
gcc/cp/typeck.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 96 insertions(+), 1 deletion(-)
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index cb049ce708c..5b3be9b0faa 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -282,9 +282,11 @@ cp_common_type (tree t1, tree t2)
/* FIXME: Attributes. */
gcc_assert (ARITHMETIC_TYPE_P (t1)
+ || INTCAP_TYPE_P (t1)
|| VECTOR_TYPE_P (t1)
|| UNSCOPED_ENUM_P (t1));
gcc_assert (ARITHMETIC_TYPE_P (t2)
+ || INTCAP_TYPE_P (t2)
|| VECTOR_TYPE_P (t2)
|| UNSCOPED_ENUM_P (t2));
@@ -323,6 +325,29 @@ cp_common_type (tree t1, tree t2)
if (code2 == REAL_TYPE && code1 != REAL_TYPE)
return build_type_attribute_variant (t2, attributes);
+ /* INTCAP_TYPEs out-rank all other integer types. */
+ if ((code1 == INTCAP_TYPE && code2 != INTCAP_TYPE)
+ || (code2 == INTCAP_TYPE && code1 != INTCAP_TYPE))
+ {
+ tree t_intcap = (code1 == INTCAP_TYPE) ? t1 : t2;
+ tree t_int = (t_intcap == t1) ? t2 : t1;
+ gcc_assert (INTEGRAL_TYPE_P (t_int));
+
+ /* Note that the intcap always out-ranks the integer type, the only
+ interesting case is therefore when the intcap is signed, the integer is
+ unsigned, and the intcap cannot represent all values of the integer
+ type.
+
+ [expr.arith.conv] (1.5.5) - Otherwise, both operands shall be converted
+ to the unsigned integer type corresponding to the type of the operand
+ with the signed integer type. */
+ if (!TYPE_UNSIGNED (t_intcap) && TYPE_UNSIGNED (t_int)
+ && TYPE_NONCAP_PRECISION (t_intcap) <= TYPE_PRECISION (t_int))
+ return uintcap_type_node;
+ else
+ return t_intcap;
+ }
+
/* Both real or both integers; use the one with greater precision. */
if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
return build_type_attribute_variant (t1, attributes);
@@ -4538,6 +4563,11 @@ cp_build_binary_op (const op_location_t &location,
STRIP_TYPE_NOPS (op0);
STRIP_TYPE_NOPS (op1);
+ if (INTCAP_TYPE_P (TREE_TYPE (op0)))
+ op0 = drop_capability (op0);
+ if (INTCAP_TYPE_P (TREE_TYPE (op1)))
+ op1 = drop_capability (op1);
+
/* DTRT if one side is an overloaded function, but complain about it. */
if (type_unknown_p (op0))
{
@@ -5530,7 +5560,19 @@ cp_build_binary_op (const op_location_t &location,
/* Since the middle-end checks the type when doing a build2, we
need to build the tree in pieces. This built tree will never
get out of the front-end as we replace it when instantiating
- the template. */
+ the template.
+
+ For capabilities, we must make sure that result_type and the
+ operands at a minimum agree on their capability-ness to avoid
+ tripping the capability_args_valid check. */
+ if (!capability_type_p (result_type))
+ {
+ if (capability_type_p (TREE_TYPE (op0)))
+ op0 = drop_capability (op0);
+ if (capability_type_p (TREE_TYPE (op1)))
+ op1 = drop_capability (op1);
+ }
+
tree tmp = build2 (resultcode,
build_type ? build_type : result_type,
NULL_TREE, op1);
@@ -5778,6 +5820,59 @@ cp_build_binary_op (const op_location_t &location,
if (final_type != 0)
result = cp_convert (final_type, result, complain);
+ /* For INTCAP_TYPEs, we dropped the capabilities early on and now need
+ to work out where the provenance (if any) should come from. */
+ if (!capability_type_p (TREE_TYPE (result))
+ && TREE_CODE_CLASS (code) != tcc_comparison
+ && result_type != boolean_type_node)
+ {
+ tree orig_type0 = TREE_TYPE (orig_op0);
+ tree orig_type1 = TREE_TYPE (orig_op1);
+
+ bool ic0 = INTCAP_TYPE_P (orig_type0);
+ bool ic1 = INTCAP_TYPE_P (orig_type1);
+
+ /* These flags are set if we need an intcap result type because of
+ either the left or right operand respectively. */
+ bool need_ic0 = ic0 && code1 == INTEGER_TYPE;
+ bool need_ic1 = ic1 && !doing_shift && code0 == INTEGER_TYPE;
+
+ bool prov0 = need_ic0
+ && !lookup_attribute ("cheri_no_provenance",
+ TYPE_ATTRIBUTES (orig_type0));
+ bool prov1 = need_ic1
+ && !lookup_attribute ("cheri_no_provenance",
+ TYPE_ATTRIBUTES (orig_type1));
+
+ tree intcap = nullptr;
+ if (prov0)
+ intcap = orig_op0;
+ else if (prov1)
+ intcap = orig_op1;
+ else if (need_ic0)
+ intcap = build_int_cst (orig_type0, 0);
+ else if (need_ic1)
+ intcap = build_int_cst (orig_type1, 0);
+
+ if (intcap)
+ {
+ tree ic_type = cp_common_type (TREE_TYPE (intcap),
+ TREE_TYPE (result));
+ gcc_assert (TREE_TYPE (result) == noncapability_type (ic_type));
+ intcap = cp_convert (ic_type, intcap, complain);
+ result = fold_build_replace_address_value_loc (location,
+ intcap,
+ result);
+ }
+
+ if (prov0 && prov1)
+ warning_at (location, OPT_Wcheri_provenance,
+ "binary expression on capability types %qT and %qT; "
+ "it is not clear which should be the source of provenance; "
+ "currently provenance is inherited from the left-hand side",
+ orig_type0, orig_type1);
+ }
+
if (instrument_expr != NULL)
result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
instrument_expr, result);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-03-14 10:35 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:35 [gcc(refs/vendors/ARM/heads/morello)] cp: Initial support for binary ops on INTCAP_TYPEs 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).