public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] Handle INTCAP_TYPEs in conversion warnings
@ 2022-06-16 13:45 Richard Sandiford
0 siblings, 0 replies; only message in thread
From: Richard Sandiford @ 2022-06-16 13:45 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:b27ecfa2999280d3e87bdac3cefa3811a8646a7d
commit b27ecfa2999280d3e87bdac3cefa3811a8646a7d
Author: Richard Sandiford <richard.sandiford@arm.com>
Date: Thu Jun 16 14:42:39 2022 +0100
Handle INTCAP_TYPEs in conversion warnings
-Wconversion emits warnings for things like:
uint64_t f1() { return -1; } // changes value
int64_t f2(uint64_t x) { return x; } // might change sign
uint64_t f3(float x) { return x; } // might change value
int32_t f4(int64_t x) { return x; } // might change value
However, it wasn't emitting the corresponding warnings with
int64_t replaced by intcap_t and uint64_t replaced by uintcap_t.
Also (unrelated to capabilities), -Wconversion wouldn't diagnose
cases in which a scalar integer was converted to a complex
integer (although it did handle the reverse, which if nothing
else can change the value by dropping the imaginary component).
Diff:
---
gcc/c-family/c-common.c | 15 +++++
gcc/c-family/c-warn.c | 10 +++-
.../aarch64/morello/conversion-warnings-1.c | 66 ++++++++++++++++++++++
gcc/tree.c | 9 ++-
4 files changed, 96 insertions(+), 4 deletions(-)
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index fed39e74f11..20030960b33 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -1331,8 +1331,17 @@ enum conversion_safety
unsafe_conversion_p (tree type, tree expr, tree result, bool check_sign)
{
enum conversion_safety give_warning = SAFE_CONVERSION; /* is 0 or false */
+
+ /* Converting an intcap_t or uintcap_t is unsafe iff the same conversion
+ would be unsafe for the integer capability value. */
+ if (TREE_CODE (TREE_TYPE (expr)) == INTCAP_TYPE)
+ expr = fold_drop_capability (expr);
tree expr_type = TREE_TYPE (expr);
+ /* Likewise converting to an intcap_t or uintcap_t. */
+ if (TREE_CODE (type) == INTCAP_TYPE)
+ type = TREE_TYPE (type);
+
expr = fold_for_warn (expr);
if (TREE_CODE (expr) == REAL_CST || TREE_CODE (expr) == INTEGER_CST)
@@ -1439,6 +1448,12 @@ unsafe_conversion_p (tree type, tree expr, tree result, bool check_sign)
/* Checks for remaining case: EXPR is not constant. */
else
{
+ /* Treat a conversion from a scalar to a complex in the same way
+ as a conversion from the scalar to the real component. */
+ if (TREE_CODE (type) == COMPLEX_TYPE
+ && TREE_CODE (expr_type) != COMPLEX_TYPE)
+ type = TREE_TYPE (type);
+
/* Warn for real types converted to integer types. */
if (TREE_CODE (expr_type) == REAL_TYPE
&& TREE_CODE (type) == INTEGER_TYPE)
diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c
index 1963847ff33..b98bb59087b 100644
--- a/gcc/c-family/c-warn.c
+++ b/gcc/c-family/c-warn.c
@@ -1193,7 +1193,7 @@ conversion_warning (location_t loc, tree type, tree expr, tree result)
/* Conversion from boolean to a signed:1 bit-field (which only
can hold the values 0 and -1) doesn't lose information - but
it does change the value. */
- if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type))
+ if (TYPE_NONCAP_PRECISION (type) == 1 && !TYPE_UNSIGNED (type))
warning_at (loc, OPT_Wconversion,
"conversion to %qT from boolean expression", type);
return true;
@@ -1293,6 +1293,11 @@ conversion_warning (location_t loc, tree type, tree expr, tree result)
|| conversion_warning (loc, type, op2, result));
}
+ case CALL_EXPR:
+ if (CALL_EXPR_IFN (expr) == IFN_REPLACE_ADDRESS_VALUE)
+ return conversion_warning (loc, type, CALL_EXPR_ARG (expr, 1), result);
+ goto default_;
+
default_:
default:
conversion_kind = unsafe_conversion_p (type, expr, result, true);
@@ -1370,7 +1375,8 @@ warnings_for_convert_and_check (location_t loc, tree type, tree expr,
if (TREE_CODE (expr) == INTEGER_CST
&& (TREE_CODE (type) == INTEGER_TYPE
- || TREE_CODE (type) == ENUMERAL_TYPE)
+ || TREE_CODE (type) == ENUMERAL_TYPE
+ || TREE_CODE (type) == INTCAP_TYPE)
&& !int_fits_type_p (expr, type))
{
/* Do not diagnose overflow in a constant expression merely
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/conversion-warnings-1.c b/gcc/testsuite/gcc.target/aarch64/morello/conversion-warnings-1.c
new file mode 100644
index 00000000000..78d94a5659e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/conversion-warnings-1.c
@@ -0,0 +1,66 @@
+/* { dg-additional-options "-W -Wall -Wconversion" } */
+
+#include <stdint.h>
+
+__intcap_t overflow_intcap() { return 1ULL << 63; } /* { dg-warning "overflow in conversion" } */
+__uintcap_t overflow_uintcap() { return -1; } /* { dg-warning "unsigned conversion" } */
+
+__intcap_t compare_to_intcap(int x) { return x == 0; }
+__intcap_t short_to_intcap(short x) { return x; }
+__intcap_t ushort_to_intcap(unsigned short x) { return x; }
+__intcap_t int_to_intcap(int x) { return x; }
+__intcap_t uint_to_intcap(unsigned int x) { return x; }
+__intcap_t int64_to_intcap(int64_t x) { return x; }
+__intcap_t uint64_to_intcap(uint64_t x) { return x; } /* { dg-warning "may change the sign of the result" } */
+__intcap_t uintcap_to_intcap(__uintcap_t x) { return x; } /* { dg-warning "may change the sign of the result" } */
+__intcap_t float_to_intcap(float x) { return x; } /* { dg-warning "may change value" } */
+__intcap_t complex_uint_to_intcap(_Complex unsigned int x) { return x; } /* { dg-warning "discards imaginary component" } */
+
+__uintcap_t compare_to_uintcap(int x) { return x == 0; }
+__uintcap_t short_to_uintcap(short x) { return x; } /* { dg-warning "may change the sign of the result" } */
+__uintcap_t ushort_to_uintcap(unsigned short x) { return x; }
+__uintcap_t int_to_uintcap(int x) { return x; } /* { dg-warning "may change the sign of the result" } */
+__uintcap_t uint_to_uintcap(unsigned int x) { return x; }
+__uintcap_t int64_to_uintcap(int64_t x) { return x; } /* { dg-warning "may change the sign of the result" } */
+__uintcap_t uint64_to_uintcap(uint64_t x) { return x; }
+__uintcap_t intcap_to_uintcap(__intcap_t x) { return x; } /* { dg-warning "may change the sign of the result" } */
+__uintcap_t float_to_uintcap(float x) { return x; } /* { dg-warning "may change value" } */
+__uintcap_t complex_uint_to_uintcap(_Complex unsigned int x) { return x; } /* { dg-warning "discards imaginary component" } */
+
+short intcap_to_short(__intcap_t x) { return x; } /* { dg-warning "may change value" } */
+unsigned short intcap_to_ushort(__intcap_t x) { return x; } /* { dg-warning "may change value" } */
+int intcap_to_int(__intcap_t x) { return x; } /* { dg-warning "may change value" } */
+unsigned int intcap_to_uint(__intcap_t x) { return x; } /* { dg-warning "may change value" } */
+int64_t intcap_to_int64(__intcap_t x) { return x; }
+uint64_t intcap_to_uint64(__intcap_t x) { return x; } /* { dg-warning "may change the sign of the result" } */
+float intcap_to_float(__intcap_t x) { return x; } /* { dg-warning "may change value" } */
+_Complex unsigned int intcap_to_complex_uint(__intcap_t x) { return x; } /* { dg-warning "may change value" } */
+_Complex long intcap_to_complex_long(__intcap_t x) { return x; }
+_Complex unsigned long intcap_to_complex_ulong(__intcap_t x) { return x; } /* { dg-warning "may change the sign of the result" } */
+
+short uintcap_to_short(__uintcap_t x) { return x; } /* { dg-warning "may change value" } */
+unsigned short uintcap_to_ushort(__uintcap_t x) { return x; } /* { dg-warning "may change value" } */
+int uintcap_to_int(__uintcap_t x) { return x; } /* { dg-warning "may change value" } */
+unsigned int uintcap_to_uint(__uintcap_t x) { return x; } /* { dg-warning "may change value" } */
+int64_t uintcap_to_int64(__uintcap_t x) { return x; } /* { dg-warning "may change the sign of the result" } */
+uint64_t uintcap_to_uint64(__uintcap_t x) { return x; }
+float uintcap_to_float(__uintcap_t x) { return x; } /* { dg-warning "may change value" } */
+_Complex unsigned int uintcap_to_complex_uint(__uintcap_t x) { return x; } /* { dg-warning "may change value" } */
+_Complex long uintcap_to_complex_long(__uintcap_t x) { return x; } /* { dg-warning "may change the sign of the result" } */
+_Complex unsigned long uintcap_to_complex_ulong(__uintcap_t x) { return x; }
+
+__intcap_t precise_intcap() { return 1.0; }
+__intcap_t imprecise_intcap() { return 1.2; } /* { dg-warning "changes value" } */
+
+__intcap_t masked_uintcap_to_intcap(__uintcap_t x) { return x & 0xff; }
+__uintcap_t masked_intcap_to_uintcap(__intcap_t x) { return x & 0xff; }
+
+__intcap_t ptr_to_intcap(void *__capability x) { return x; } /* { dg-warning {integer from pointer without a cast} } */
+__uintcap_t ptr_to_uintcap(void *__capability x) { return x; } /* { dg-warning {integer from pointer without a cast} } */
+int64_t ptr_to_int64(void *__capability x) { return x; } /* { dg-warning {integer from pointer without a cast} } */
+uint64_t ptr_to_uint64(void *__capability x) { return x; } /* { dg-warning {integer from pointer without a cast} } */
+
+__intcap_t explicit_ptr_to_intcap(void *__capability x) { return (__intcap_t)x; }
+__uintcap_t explicit_ptr_to_uintcap(void *__capability x) { return (__uintcap_t)x; }
+int64_t explicit_ptr_to_int64(void *__capability x) { return (int64_t)x; }
+uint64_t explicit_ptr_to_uint64(void *__capability x) { return (uint64_t)x; }
diff --git a/gcc/tree.c b/gcc/tree.c
index 055a446b5e6..67349b66914 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -9033,10 +9033,15 @@ excess_precision_type (tree type)
tree
get_unwidened (tree op, tree for_type)
{
- /* Set UNS initially if converting OP to FOR_TYPE is a zero-extension. */
tree type = TREE_TYPE (op);
+
+ /* Capability values have a fixed size, so we can't drop their precision. */
+ if (TREE_CODE (type) == INTCAP_TYPE)
+ return op;
+
unsigned final_prec
- = TYPE_PRECISION (for_type != 0 ? for_type : type);
+ = TYPE_NONCAP_PRECISION (for_type != 0 ? for_type : type);
+ /* Set UNS initially if converting OP to FOR_TYPE is a zero-extension. */
int uns
= (for_type != 0 && for_type != type
&& final_prec > TYPE_PRECISION (type)
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-06-16 13:45 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-16 13:45 [gcc(refs/vendors/ARM/heads/morello)] Handle INTCAP_TYPEs in conversion warnings Richard Sandiford
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).