Commit 55b7df8b by Jason Merrill

c-family: Fix problems with blender and PPC from PR 40752 patch.

blender in SPEC is built with -funsigned-char, which is also the default on
PPC, and exposed -Wsign-conversion issues that weren't seen by the x86_64
testsuite.  In blender we were complaining about operands to an expression
that we didn't't previously complain about as a whole.  So only check
operands after we check the whole expression.  Also, to fix the PR 40752
testcases on -funsigned-char targets, don't consider -Wsign-conversion for
the second operand of PLUS_EXPR, especially since fold changes
"x - 5" to "x + (-5)".  And don't use SCHAR_MAX with plain char.

	PR testsuite/93391 - PR 40752 test fails with unsigned plain char.
	PR c++/40752
	* c-warn.c (conversion_warning): Check operands only after checking
	the whole expression.  Don't check second operand of + for sign.
parent d9637168
2020-01-22 Jason Merrill <jason@redhat.com>
PR testsuite/93391 - PR 40752 test fails with unsigned plain char.
PR c++/40752
* c-warn.c (conversion_warning): Check operands only after checking
the whole expression. Don't check second operand of + for sign.
2020-01-21 Jason Merrill <jason@redhat.com> 2020-01-21 Jason Merrill <jason@redhat.com>
Manuel López-Ibáñez <manu@gcc.gnu.org> Manuel López-Ibáñez <manu@gcc.gnu.org>
......
...@@ -1163,7 +1163,7 @@ conversion_warning (location_t loc, tree type, tree expr, tree result) ...@@ -1163,7 +1163,7 @@ conversion_warning (location_t loc, tree type, tree expr, tree result)
{ {
tree expr_type = TREE_TYPE (expr); tree expr_type = TREE_TYPE (expr);
enum conversion_safety conversion_kind; enum conversion_safety conversion_kind;
bool is_arith = false; int arith_ops = 0;
if (!warn_conversion && !warn_sign_conversion && !warn_float_conversion) if (!warn_conversion && !warn_sign_conversion && !warn_float_conversion)
return false; return false;
...@@ -1266,14 +1266,8 @@ conversion_warning (location_t loc, tree type, tree expr, tree result) ...@@ -1266,14 +1266,8 @@ conversion_warning (location_t loc, tree type, tree expr, tree result)
case CEIL_DIV_EXPR: case CEIL_DIV_EXPR:
case EXACT_DIV_EXPR: case EXACT_DIV_EXPR:
case RDIV_EXPR: case RDIV_EXPR:
{ arith_ops = 2;
tree op0 = TREE_OPERAND (expr, 0); goto default_;
tree op1 = TREE_OPERAND (expr, 1);
if (conversion_warning (loc, type, op0, result)
|| conversion_warning (loc, type, op1, result))
return true;
goto arith_op;
}
case PREDECREMENT_EXPR: case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR: case PREINCREMENT_EXPR:
...@@ -1285,13 +1279,8 @@ conversion_warning (location_t loc, tree type, tree expr, tree result) ...@@ -1285,13 +1279,8 @@ conversion_warning (location_t loc, tree type, tree expr, tree result)
case NON_LVALUE_EXPR: case NON_LVALUE_EXPR:
case NEGATE_EXPR: case NEGATE_EXPR:
case BIT_NOT_EXPR: case BIT_NOT_EXPR:
{ arith_ops = 1;
/* Unary ops or binary ops for which we only care about the lhs. */ goto default_;
tree op0 = TREE_OPERAND (expr, 0);
if (conversion_warning (loc, type, op0, result))
return true;
goto arith_op;
}
case COND_EXPR: case COND_EXPR:
{ {
...@@ -1304,11 +1293,7 @@ conversion_warning (location_t loc, tree type, tree expr, tree result) ...@@ -1304,11 +1293,7 @@ conversion_warning (location_t loc, tree type, tree expr, tree result)
|| conversion_warning (loc, type, op2, result)); || conversion_warning (loc, type, op2, result));
} }
arith_op: default_:
/* We didn't warn about the operands, we might still want to warn if
-Warith-conversion. */
is_arith = true;
gcc_fallthrough ();
default: default:
conversion_kind = unsafe_conversion_p (type, expr, result, true); conversion_kind = unsafe_conversion_p (type, expr, result, true);
{ {
...@@ -1321,11 +1306,27 @@ conversion_warning (location_t loc, tree type, tree expr, tree result) ...@@ -1321,11 +1306,27 @@ conversion_warning (location_t loc, tree type, tree expr, tree result)
warnopt = OPT_Wconversion; warnopt = OPT_Wconversion;
else else
break; break;
if (is_arith
if (arith_ops
&& global_dc->option_enabled (warnopt, && global_dc->option_enabled (warnopt,
global_dc->lang_mask, global_dc->lang_mask,
global_dc->option_state)) global_dc->option_state))
warnopt = OPT_Warith_conversion; {
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))
goto op_unsafe;
}
/* The operands seem safe, we might still want to warn if
-Warith-conversion. */
warnopt = OPT_Warith_conversion;
op_unsafe:;
}
if (conversion_kind == UNSAFE_SIGN) if (conversion_kind == UNSAFE_SIGN)
warning_at (loc, warnopt, "conversion to %qT from %qT " warning_at (loc, warnopt, "conversion to %qT from %qT "
"may change the sign of the result", "may change the sign of the result",
......
...@@ -31,15 +31,15 @@ void bar(char c, int c2) ...@@ -31,15 +31,15 @@ void bar(char c, int c2)
c >>= (int)1; c >>= (int)1;
c <<= (int)1; c <<= (int)1;
c <<= c2; c <<= c2;
c += ((int)SCHAR_MAX + SCHAR_MAX); /* { dg-warning "conversion" } */ c += ((int)CHAR_MAX + CHAR_MAX); /* { dg-warning "conversion" } */
c += c2; /* { dg-warning "conversion" } */ c += c2; /* { dg-warning "conversion" } */
c -= ((int)SCHAR_MAX + SCHAR_MAX); /* { dg-warning "conversion" } */ c -= ((int)CHAR_MAX + CHAR_MAX); /* { dg-warning "conversion" } */
c -= c2; /* { dg-warning "conversion" } */ c -= c2; /* { dg-warning "conversion" } */
c *= ((int)SCHAR_MAX + SCHAR_MAX); /* { dg-warning "conversion" } */ c *= ((int)CHAR_MAX + CHAR_MAX); /* { dg-warning "conversion" } */
c *= c2; /* { dg-warning "conversion" } */ c *= c2; /* { dg-warning "conversion" } */
c /= ((int)SCHAR_MAX + SCHAR_MAX); /* { dg-warning "conversion" } */ c /= ((int)CHAR_MAX + CHAR_MAX); /* { dg-warning "conversion" } */
c /= c2; /* { dg-warning "conversion" } */ c /= c2; /* { dg-warning "conversion" } */
c %= ((int)SCHAR_MAX + SCHAR_MAX); /* { dg-warning "conversion" } */ c %= ((int)CHAR_MAX + CHAR_MAX); /* { dg-warning "conversion" } */
c %= c2; /* { dg-warning "conversion" } */ c %= c2; /* { dg-warning "conversion" } */
c = ~c2; /* { dg-warning "conversion" } */ c = ~c2; /* { dg-warning "conversion" } */
c = c2++; /* { dg-warning "conversion" } */ c = c2++; /* { dg-warning "conversion" } */
......
...@@ -31,15 +31,15 @@ void bar(char c, int c2) ...@@ -31,15 +31,15 @@ void bar(char c, int c2)
c >>= (int)1; c >>= (int)1;
c <<= (int)1; /* { dg-warning "conversion" } */ c <<= (int)1; /* { dg-warning "conversion" } */
c <<= c2; /* { dg-warning "conversion" } */ c <<= c2; /* { dg-warning "conversion" } */
c += ((int)SCHAR_MAX + SCHAR_MAX); /* { dg-warning "conversion" } */ c += ((int)CHAR_MAX + CHAR_MAX); /* { dg-warning "conversion" } */
c += c2; /* { dg-warning "conversion" } */ c += c2; /* { dg-warning "conversion" } */
c -= ((int)SCHAR_MAX + SCHAR_MAX); /* { dg-warning "conversion" } */ c -= ((int)CHAR_MAX + CHAR_MAX); /* { dg-warning "conversion" } */
c -= c2; /* { dg-warning "conversion" } */ c -= c2; /* { dg-warning "conversion" } */
c *= ((int)SCHAR_MAX + SCHAR_MAX); /* { dg-warning "conversion" } */ c *= ((int)CHAR_MAX + CHAR_MAX); /* { dg-warning "conversion" } */
c *= c2; /* { dg-warning "conversion" } */ c *= c2; /* { dg-warning "conversion" } */
c /= ((int)SCHAR_MAX + SCHAR_MAX); /* { dg-warning "conversion" } */ c /= ((int)CHAR_MAX + CHAR_MAX); /* { dg-warning "conversion" } */
c /= c2; /* { dg-warning "conversion" } */ c /= c2; /* { dg-warning "conversion" } */
c %= ((int)SCHAR_MAX + SCHAR_MAX); /* { dg-warning "conversion" } */ c %= ((int)CHAR_MAX + CHAR_MAX); /* { dg-warning "conversion" } */
c %= c2; /* { dg-warning "conversion" } */ c %= c2; /* { dg-warning "conversion" } */
c = ~c2; /* { dg-warning "conversion" } */ c = ~c2; /* { dg-warning "conversion" } */
c = c2++; /* { dg-warning "conversion" } */ c = c2++; /* { dg-warning "conversion" } */
......
// PR c++/40752
// { dg-additional-options -funsigned-char }
#pragma GCC diagnostic error "-Wsign-conversion"
void f(char *ar, int i)
{
ar[i] -= 'a' - 'A';
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment