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

--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> ---
The problem is in shorten_compare() in c-common.c which deals with these cases.
 The comment above the block that handles this has this to say just above the
conditional that guards the code.  The conditional fails in the fint case
because both operands of the inequality have the same precision:

  /* If comparing an integer against a constant more bits wide,
     maybe we can deduce a value of 1 or 0 independent of the data.
     Or else truncate the constant now
     rather than extend the variable at run time.

     This is only interesting if the constant is the wider arg.
     Also, it is not safe if the constant is unsigned and the
     variable arg is signed, since in this case the variable
     would be sign-extended and then regarded as unsigned.
     Our technique fails in this case because the lowest/highest
     possible unsigned results don't follow naturally from the
     lowest/highest possible values of the variable operand.
     For just EQ_EXPR and NE_EXPR there is another technique that
     could be used: see if the constant can be faithfully represented
     in the other operand's type, by truncating it and reextending it
     and see if that preserves the constant's value.  */

  if (!real1 && !real2
      && TREE_CODE (TREE_TYPE (primop0)) != FIXED_POINT_TYPE
      && TREE_CODE (primop1) == INTEGER_CST
      && TYPE_PRECISION (TREE_TYPE (primop0)) < TYPE_PRECISION (*restype_ptr))
    {

Eventually, after the function returns the inequality expression without a
warning, c_parser_condition() calls c_fully_fold() on it which folds it into a
constant, without a warning.

Reply via email to