diff options
author | Jason Merrill <jason@redhat.com> | 2020-01-22 14:21:06 -0500 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-01-22 17:05:43 -0500 |
commit | 55b7df8bfb12938e7716445d4e2dc0d2ddf44bac (patch) | |
tree | 92e64d32e8dc7e2491b7d52ef5e0c3b07ef197e1 /gcc/c-family | |
parent | d9637168812939d6c9df29ce747d8d4648b37cef (diff) | |
download | gcc-55b7df8bfb12938e7716445d4e2dc0d2ddf44bac.zip gcc-55b7df8bfb12938e7716445d4e2dc0d2ddf44bac.tar.gz gcc-55b7df8bfb12938e7716445d4e2dc0d2ddf44bac.tar.bz2 |
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.
Diffstat (limited to 'gcc/c-family')
-rw-r--r-- | gcc/c-family/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/c-family/c-warn.c | 47 |
2 files changed, 31 insertions, 23 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 3a9ce24..89a66bd 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -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> diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c index 4df4893..6c73317 100644 --- a/gcc/c-family/c-warn.c +++ b/gcc/c-family/c-warn.c @@ -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", |