https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107465

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #3)
> --- a/gcc/c-family/c-warn.cc
> +++ b/gcc/c-family/c-warn.cc
> @@ -2302,8 +2302,8 @@ warn_for_sign_compare (location_t location,
>        sop = fold_for_warn (sop);
>        uop = fold_for_warn (uop);
> 
> -      STRIP_TYPE_NOPS (sop);
> -      STRIP_TYPE_NOPS (uop);
> +      STRIP_SIGN_NOPS (sop);
> +      STRIP_SIGN_NOPS (uop);
>        base_type = (TREE_CODE (result_type) == COMPLEX_TYPE
>                    ? TREE_TYPE (result_type) : result_type);
> 
> 

No, this has nothing to do with it.
The problem is purely in incorrect use of get_narrower/c_common_get_narrower.
  op0 = c_common_get_narrower (op0, &unsignedp0);
  op1 = c_common_get_narrower (op1, &unsignedp1);

  if ((TREE_CODE (op0) == BIT_NOT_EXPR)
      ^ (TREE_CODE (op1) == BIT_NOT_EXPR))
    {
      if (TREE_CODE (op0) == BIT_NOT_EXPR)
        op0 = c_common_get_narrower (TREE_OPERAND (op0, 0), &unsignedp0);
      if (TREE_CODE (op1) == BIT_NOT_EXPR)
        op1 = c_common_get_narrower (TREE_OPERAND (op1, 0), &unsignedp1);
What get_narrower/c_common_get_narrower store into the integer pointed by the
second argument doesn't mean anything at all if the function doesn't return
something narrower, it is purely about whether if there needs to be some
extension from what {,c_common_}get_narrower returns to what has been passed to
it as the first argument needs to be a sign or zero extension.
E.g. shorten_binary_op does it get right and uses:
  arg0 = c_common_get_narrower (op0, &unsigned0);
  arg1 = c_common_get_narrower (op1, &unsigned1);

  /* UNS is 1 if the operation to be done is an unsigned one.  */
  uns = TYPE_UNSIGNED (result_type);

  /* Handle the case that OP0 (or OP1) does not *contain* a conversion
     but it *requires* conversion to FINAL_TYPE.  */

  if ((TYPE_PRECISION (TREE_TYPE (op0))
       == TYPE_PRECISION (TREE_TYPE (arg0)))
      && TREE_TYPE (op0) != result_type)
    unsigned0 = TYPE_UNSIGNED (TREE_TYPE (op0));
  if ((TYPE_PRECISION (TREE_TYPE (op1))
       == TYPE_PRECISION (TREE_TYPE (arg1)))
      && TREE_TYPE (op1) != result_type)
    unsigned1 = TYPE_UNSIGNED (TREE_TYPE (op1));
I guess for the first pair of c_common_get_narrower we can do something
similar.
The problem is that there is another pair of them.
For those one can surely do that as well, but there is a further problem.
If the precision changes in both the c_common_get_narrower (op{0,1},
&unsignedp{0,1}) and c_common_get_narrower (TREE_OPERAND (op{0,1}, 0),
&unsignedp{0,1}) calls, we need to take into account also what actually
it means.

Note, this has been introduced already in
r0-9641-g64c01f8071113aff84414204e9d63cff3701bfb7
And, the bits < HOST_BITS_PER_LONG && part made sense in 1995 when it was using
long, but it doesn't make any sense to me now (we check tree_fits_shwi_p and
that verifies it fits into HOST_WIDE_INT).

Reply via email to