[gcc/devel/ranger] c-family: One more 40752 tweak for unsigned char.

Aldy Hernandez aldyh@gcc.gnu.org
Wed Jun 17 18:14:32 GMT 2020


https://gcc.gnu.org/g:6d00f052ef209bacdd93f503b0c5fb428cc6c434

commit 6d00f052ef209bacdd93f503b0c5fb428cc6c434
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Jan 23 10:37:18 2020 -0500

    c-family: One more 40752 tweak for unsigned char.
    
    My last patch didn't fix all the failures on unsignd char targets.  We were
    missing one warning because by suppressing -Wsign-conversion for the second
    operand of + we missed an overflow that we want to warn about, and we
    properly don't warn about unsigned / or %.
    
            PR testsuite/93391 - PR 40752 test fails with unsigned plain char.
            * c-warn.c (conversion_warning): Change -Wsign-conversion handling.
            * lib/target-supports.exp (check_effective_target_unsigned_char):
            New.

Diff:
---
 gcc/c-family/ChangeLog                            |  4 ++++
 gcc/c-family/c-warn.c                             | 10 +++++++---
 gcc/testsuite/ChangeLog                           |  5 +++++
 gcc/testsuite/c-c++-common/Wconversion-pr40752a.c |  5 +++--
 gcc/testsuite/lib/target-supports.exp             |  8 ++++++++
 5 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 0b9c604956a..023e49ae508 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,7 @@
+2020-01-23  Jason Merrill  <jason@redhat.com>
+
+	* c-warn.c (conversion_warning): Change -Wsign-conversion handling.
+
 2020-01-23  Martin Sebor  <msebor@redhat.com>
 
 	PR c/84919
diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c
index 6c73317b4a6..9315cac683e 100644
--- a/gcc/c-family/c-warn.c
+++ b/gcc/c-family/c-warn.c
@@ -1315,10 +1315,14 @@ conversion_warning (location_t loc, tree type, tree expr, tree result)
 	    for (int i = 0; i < arith_ops; ++i)
 	      {
 		tree op = TREE_OPERAND (expr, i);
-		tree opr = convert (type, op);
 		/* Avoid -Wsign-conversion for (unsigned)(x + (-1)).  */
-		bool minus = TREE_CODE (expr) == PLUS_EXPR && i == 1;
-		if (unsafe_conversion_p (type, op, opr, !minus))
+		if (TREE_CODE (expr) == PLUS_EXPR && i == 1
+		    && INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
+		    && TREE_CODE (op) == INTEGER_CST
+		    && tree_int_cst_sgn (op) < 0)
+		  op = fold_build1 (NEGATE_EXPR, TREE_TYPE (op), op);
+		tree opr = convert (type, op);
+		if (unsafe_conversion_p (type, op, opr, true))
 		  goto op_unsafe;
 	      }
 	    /* The operands seem safe, we might still want to warn if
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fef595104fe..5c390ba1981 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-01-23  Jason Merrill  <jason@redhat.com>
+
+	* lib/target-supports.exp (check_effective_target_unsigned_char):
+	New.
+
 2020-01-23  Jakub Jelinek  <jakub@redhat.com>
 
 	PR target/93376
diff --git a/gcc/testsuite/c-c++-common/Wconversion-pr40752a.c b/gcc/testsuite/c-c++-common/Wconversion-pr40752a.c
index cd70e34c390..8e3ffae06f6 100644
--- a/gcc/testsuite/c-c++-common/Wconversion-pr40752a.c
+++ b/gcc/testsuite/c-c++-common/Wconversion-pr40752a.c
@@ -14,9 +14,10 @@ void foo(char c, char c2)
   c *= 2;			/* { dg-warning "conversion" } */
   c *= c2;			/* { dg-warning "conversion" } */
   c /= 2;
-  c /= c2;			/* { dg-warning "conversion" } */
+  /* If char is unsigned we avoid promoting to int.  */
+  c /= c2;  /* { dg-warning "conversion" "" { target { ! unsigned_char } } } */
   c %= 2;
-  c %= c2;			/* { dg-warning "conversion" } */
+  c %= c2;  /* { dg-warning "conversion" "" { target { ! unsigned_char } } } */
   c = -c2;			/* { dg-warning "conversion" } */
   c = ~c2;			/* { dg-warning "conversion" } */
   c = c2++;
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index f65a8100da9..3ca3dd3a9e4 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -3115,6 +3115,14 @@ proc check_effective_target_dfprt { } {
     }]
 }
 
+# Return 1 iff target has unsigned plain 'char' by default.
+
+proc check_effective_target_unsigned_char {} {
+    return [check_no_compiler_messages unsigned_char assembly {
+	char ar[(char)-1];
+    }]
+}
+
 proc check_effective_target_powerpc_popcntb_ok { } {
     return [check_cached_effective_target powerpc_popcntb_ok {


More information about the Gcc-cvs mailing list