]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c-family: One more 40752 tweak for unsigned char.
authorJason Merrill <jason@redhat.com>
Thu, 23 Jan 2020 15:37:18 +0000 (10:37 -0500)
committerJason Merrill <jason@redhat.com>
Thu, 23 Jan 2020 16:13:48 +0000 (11:13 -0500)
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.

gcc/c-family/ChangeLog
gcc/c-family/c-warn.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Wconversion-pr40752a.c
gcc/testsuite/lib/target-supports.exp

index 0b9c604956a4ba340c6a653349dff1c66674475e..023e49ae5086954805d54d4407e16487437bc71f 100644 (file)
@@ -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
index 6c73317b4a6c66309a0b64d054136a161a869a7f..9315cac683e71e8b7da8cc00d8246e334c8cf309 100644 (file)
@@ -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
index fef595104fe52dfe73825e0c8cddbd685a9aa49e..5c390ba19816b56c78b8be78d49f5acbf9a0e5f9 100644 (file)
@@ -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
index cd70e34c390efad1d8acfd11f64f950cbf6bc5c8..8e3ffae06f62db55f5e4131ca5c9f2e0e2e63e5e 100644 (file)
@@ -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++;
index f65a8100da98742461155c0d6b13f57d249ec51b..3ca3dd3a9e4850adca5e7ca717c8bfa168404736 100644 (file)
@@ -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 {