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