aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-01-23 10:37:18 -0500
committerJason Merrill <jason@redhat.com>2020-01-23 11:13:48 -0500
commit6d00f052ef209bacdd93f503b0c5fb428cc6c434 (patch)
tree8cb9fb9702cb52b019574cf007b9d8da7ad48c20 /gcc
parent54b3d52c3cca836c7c4c08cc9c02eda6c096372a (diff)
downloadgcc-6d00f052ef209bacdd93f503b0c5fb428cc6c434.zip
gcc-6d00f052ef209bacdd93f503b0c5fb428cc6c434.tar.gz
gcc-6d00f052ef209bacdd93f503b0c5fb428cc6c434.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/ChangeLog4
-rw-r--r--gcc/c-family/c-warn.c10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/c-c++-common/Wconversion-pr40752a.c5
-rw-r--r--gcc/testsuite/lib/target-supports.exp8
5 files changed, 27 insertions, 5 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 0b9c604..023e49a 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 6c73317..9315cac 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 fef5951..5c390ba 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 cd70e34..8e3ffae 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 f65a810..3ca3dd3 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 {