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.
This commit is contained in:
parent
d963716881
commit
55b7df8bfb
|
@ -1,3 +1,10 @@
|
|||
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>
|
||||
Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||
|
||||
|
|
|
@ -1163,7 +1163,7 @@ conversion_warning (location_t loc, tree type, tree expr, tree result)
|
|||
{
|
||||
tree expr_type = TREE_TYPE (expr);
|
||||
enum conversion_safety conversion_kind;
|
||||
bool is_arith = false;
|
||||
int arith_ops = 0;
|
||||
|
||||
if (!warn_conversion && !warn_sign_conversion && !warn_float_conversion)
|
||||
return false;
|
||||
|
@ -1266,14 +1266,8 @@ conversion_warning (location_t loc, tree type, tree expr, tree result)
|
|||
case CEIL_DIV_EXPR:
|
||||
case EXACT_DIV_EXPR:
|
||||
case RDIV_EXPR:
|
||||
{
|
||||
tree op0 = TREE_OPERAND (expr, 0);
|
||||
tree op1 = TREE_OPERAND (expr, 1);
|
||||
if (conversion_warning (loc, type, op0, result)
|
||||
|| conversion_warning (loc, type, op1, result))
|
||||
return true;
|
||||
goto arith_op;
|
||||
}
|
||||
arith_ops = 2;
|
||||
goto default_;
|
||||
|
||||
case PREDECREMENT_EXPR:
|
||||
case PREINCREMENT_EXPR:
|
||||
|
@ -1285,13 +1279,8 @@ conversion_warning (location_t loc, tree type, tree expr, tree result)
|
|||
case NON_LVALUE_EXPR:
|
||||
case NEGATE_EXPR:
|
||||
case BIT_NOT_EXPR:
|
||||
{
|
||||
/* Unary ops or binary ops for which we only care about the lhs. */
|
||||
tree op0 = TREE_OPERAND (expr, 0);
|
||||
if (conversion_warning (loc, type, op0, result))
|
||||
return true;
|
||||
goto arith_op;
|
||||
}
|
||||
arith_ops = 1;
|
||||
goto default_;
|
||||
|
||||
case COND_EXPR:
|
||||
{
|
||||
|
@ -1304,11 +1293,7 @@ conversion_warning (location_t loc, tree type, tree expr, tree result)
|
|||
|| conversion_warning (loc, type, op2, result));
|
||||
}
|
||||
|
||||
arith_op:
|
||||
/* 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);
|
||||
{
|
||||
|
@ -1321,11 +1306,27 @@ conversion_warning (location_t loc, tree type, tree expr, tree result)
|
|||
warnopt = OPT_Wconversion;
|
||||
else
|
||||
break;
|
||||
if (is_arith
|
||||
|
||||
if (arith_ops
|
||||
&& global_dc->option_enabled (warnopt,
|
||||
global_dc->lang_mask,
|
||||
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)
|
||||
warning_at (loc, warnopt, "conversion to %qT from %qT "
|
||||
"may change the sign of the result",
|
||||
|
|
|
@ -31,15 +31,15 @@ void bar(char c, int c2)
|
|||
c >>= (int)1;
|
||||
c <<= (int)1;
|
||||
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 -= ((int)SCHAR_MAX + SCHAR_MAX); /* { dg-warning "conversion" } */
|
||||
c -= ((int)CHAR_MAX + CHAR_MAX); /* { 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 /= ((int)SCHAR_MAX + SCHAR_MAX); /* { dg-warning "conversion" } */
|
||||
c /= ((int)CHAR_MAX + CHAR_MAX); /* { 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" } */
|
||||
|
|
|
@ -31,15 +31,15 @@ void bar(char c, int c2)
|
|||
c >>= (int)1;
|
||||
c <<= (int)1; /* { 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 -= ((int)SCHAR_MAX + SCHAR_MAX); /* { dg-warning "conversion" } */
|
||||
c -= ((int)CHAR_MAX + CHAR_MAX); /* { 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 /= ((int)SCHAR_MAX + SCHAR_MAX); /* { dg-warning "conversion" } */
|
||||
c /= ((int)CHAR_MAX + CHAR_MAX); /* { 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" } */
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
// PR c++/40752
|
||||
// { dg-additional-options -funsigned-char }
|
||||
|
||||
#pragma GCC diagnostic error "-Wsign-conversion"
|
||||
void f(char *ar, int i)
|
||||
{
|
||||
ar[i] -= 'a' - 'A';
|
||||
}
|
Loading…
Reference in New Issue