public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] cp: Handle INTCAP_TYPE in constant expression contexts
@ 2022-06-13 10:13 Alex Coplan
  0 siblings, 0 replies; only message in thread
From: Alex Coplan @ 2022-06-13 10:13 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:7d494d93b8fd36101ca2ab6472ed8e4c88c8d633

commit 7d494d93b8fd36101ca2ab6472ed8e4c88c8d633
Author: Alex Coplan <alex.coplan@arm.com>
Date:   Wed Apr 6 16:53:16 2022 +0100

    cp: Handle INTCAP_TYPE in constant expression contexts
    
    This patch ports the morello intcap-const.c test to C++ and adds some
    missing handling for INTCAP_TYPE in constant expression contexts.
    
    Adding the handling of REPLACE_ADDRESS_VALUE to the constexpr
    interpreter revealed some other issues in the testsuite such as when
    tree.c:force_fit_type is callewd with overflowed = true and type is an
    INTCAP_TYPE. Here we were simply missing a case of TYPE_PRECISION being
    updated. I belive this case should use TYPE_CAP_PRECISION.
    
    gcc/c-family/ChangeLog:
    
            * c-common.c (check_case_value): Handle INTCAP_TYPE by dropping the
            capability.
    
    gcc/cp/ChangeLog:
    
            * class.c (check_bitfield_decl): Allow bitfield widths of
            INTCAP_TYPE: drop the capability on these.
            * constexpr.c (cxx_finish_replace_address_value): New.
            (cxx_eval_internal_function): Handle REPLACE_ADDRESS_VALUE.
            (potential_constant_expression_1): Likewise.
            * decl2.c (grokbitfield): Handle widths of INTCAP_TYPE.
            * tree.c (cast_valid_in_integral_constant_expression_p): Allow
            cast to INTCAP_TYPE.
    
    gcc/ChangeLog:
    
            * tree.c (force_fit_type): Handle capability types with
            overflowed = true.
    
    gcc/testsuite/ChangeLog:
    
            * g++.target/aarch64/morello/intcap-const.C: New test.

Diff:
---
 gcc/c-family/c-common.c                            |  2 +-
 gcc/cp/class.c                                     |  2 ++
 gcc/cp/constexpr.c                                 | 34 ++++++++++++++++++++++
 gcc/cp/decl2.c                                     |  3 +-
 gcc/cp/tree.c                                      |  1 +
 .../g++.target/aarch64/morello/intcap-const.C      | 33 +++++++++++++++++++++
 gcc/tree.c                                         |  2 +-
 7 files changed, 74 insertions(+), 3 deletions(-)

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 5390d5779aa..212d48e6eaa 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -2073,7 +2073,7 @@ check_case_value (location_t loc, tree value)
 
   if (TREE_CODE (value) == INTEGER_CST)
     /* Promote char or short to int.  */
-    value = perform_integral_promotions (value);
+    value = perform_integral_promotions (drop_intcap (value));
   else if (value != error_mark_node)
     {
       error_at (loc, "case label does not reduce to an integer constant");
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 693c0f73ec4..99c4c0c8745 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -3400,6 +3400,8 @@ check_bitfield_decl (tree field)
       w = cxx_constant_value (w);
       input_location = loc;
 
+      w = drop_intcap (w);
+
       if (TREE_CODE (w) != INTEGER_CST)
 	{
 	  error ("bit-field %q+D width not an integer constant", field);
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 5fa5d433c5d..291be3a998a 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1661,6 +1661,31 @@ cx_error_context (void)
   return r;
 }
 
+/* REPLACE_ADDRESS_VALUE can be used to perform an integer to pointer
+   conversion.  Some such conversions are not valid in a constexpr context, so
+   we need to make sure to detect them.  */
+static tree
+cxx_finish_replace_address_value (const constexpr_ctx *ctx,
+				  tree t,
+				  tree op0, tree op1, bool *non_constant_p)
+{
+  location_t loc = cp_expr_loc_or_input_loc (t);
+
+  if (TYPE_PTR_P (TREE_TYPE (op0)) && !integer_zerop (op1))
+    {
+      gcc_assert (integer_zerop (op0));
+      if (!ctx->quiet)
+	error_at (loc,
+		  "%<reinterpret_cast<%T>(%E)%> is not "
+		  "a constant expression",
+		  TREE_TYPE (op0), op1);
+      *non_constant_p = true;
+      return t;
+    }
+
+  return fold_build_replace_address_value_loc (loc, op0, op1);
+}
+
 /* Evaluate a call T to a GCC internal function when possible and return
    the evaluated result or, under the control of CTX, give an error, set
    NON_CONSTANT_P, and return the unevaluated call T otherwise.  */
@@ -1708,6 +1733,9 @@ cxx_eval_internal_function (const constexpr_ctx *ctx, tree t,
 	  }
       }
 
+    case IFN_REPLACE_ADDRESS_VALUE:
+      break;
+
     default:
       if (!ctx->quiet)
 	error_at (cp_expr_loc_or_input_loc (t),
@@ -1726,6 +1754,11 @@ cxx_eval_internal_function (const constexpr_ctx *ctx, tree t,
   if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
     {
       location_t loc = cp_expr_loc_or_input_loc (t);
+
+      if (CALL_EXPR_IFN (t) == IFN_REPLACE_ADDRESS_VALUE)
+	return cxx_finish_replace_address_value (ctx, t, arg0, arg1,
+						 non_constant_p);
+
       tree type = TREE_TYPE (TREE_TYPE (t));
       tree result = fold_binary_loc (loc, opcode, type,
 				     fold_convert_loc (loc, type, arg0),
@@ -7546,6 +7579,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
 		case IFN_MUL_OVERFLOW:
 		case IFN_LAUNDER:
 		case IFN_VEC_CONVERT:
+		case IFN_REPLACE_ADDRESS_VALUE:
 		  bail = false;
 		  break;
 
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index c1dba94408a..7d406026a20 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1118,7 +1118,8 @@ grokbitfield (const cp_declarator *declarator,
     {
       /* The width must be an integer type.  */
       if (!type_dependent_expression_p (width)
-	  && !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (width)))
+	  && !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (width))
+	  && !INTCAP_TYPE_P (TREE_TYPE (width)))
 	error ("width of bit-field %qD has non-integral type %qT", value,
 	       TREE_TYPE (width));
       else
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 3e6a51a86f1..f60c435d716 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -5648,6 +5648,7 @@ bool
 cast_valid_in_integral_constant_expression_p (tree type)
 {
   return (INTEGRAL_OR_ENUMERATION_TYPE_P (type)
+	  || INTCAP_TYPE_P (type)
 	  || cxx_dialect >= cxx11
 	  || dependent_type_p (type)
 	  || type == error_mark_node);
diff --git a/gcc/testsuite/g++.target/aarch64/morello/intcap-const.C b/gcc/testsuite/g++.target/aarch64/morello/intcap-const.C
new file mode 100644
index 00000000000..efcb22de4ca
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/morello/intcap-const.C
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* Check we can use __intcap_t in contexts that require integral constant
+   expressions.  */
+
+enum {
+    a = (__intcap_t)1,
+    b = (__intcap_t)1 + 1,
+};
+
+struct s {
+    unsigned x : (__intcap_t)1;
+    unsigned y : ((__intcap_t)2 * 2);
+};
+
+int a1[(__intcap_t)3];
+int a2[(__intcap_t)1 + 1];
+
+void f(void)
+{
+  char not_a_vla[(__intcap_t)1 + 1];
+  enum { x = sizeof not_a_vla, };
+}
+
+int intcap_switch(__intcap x)
+{
+  switch (x) {
+    case (__intcap_t)1:
+      return 42;
+    case ((__intcap_t)3 + 4):
+      return 25;
+  }
+  return 0;
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index 75b177cbb99..055a446b5e6 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1424,7 +1424,7 @@ force_fit_type (tree type, const poly_wide_int_ref &cst,
 	  || overflowable < 0
 	  || (overflowable > 0 && sign == SIGNED))
 	{
-	  poly_wide_int tmp = poly_wide_int::from (cst, TYPE_PRECISION (type),
+	  poly_wide_int tmp = poly_wide_int::from (cst, TYPE_CAP_PRECISION (type),
 						   sign);
 	  tree t;
 	  if (tmp.is_constant ())


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

only message in thread, other threads:[~2022-06-13 10:13 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-13 10:13 [gcc(refs/vendors/ARM/heads/morello)] cp: Handle INTCAP_TYPE in constant expression contexts 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).