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

--- Comment #7 from rguenther at suse dot de <rguenther at suse dot de> ---
On Thu, 16 Feb 2017, mpolacek at gcc dot gnu.org wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79536
> 
> --- Comment #6 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
> Yes, but see my Comment 3 regarding STRIP_SIGN_NOPS.
> 
> Also the typedef is necessary, otherwise there are no NOP_EXPRs (huh).

Yeah, but the issue is really

fold_negate_expr:

    case NOP_EXPR:
      /* Convert -((double)float) into (double)(-float).  */
      if (TREE_CODE (type) == REAL_TYPE)
        {
          tem = strip_float_extensions (t);
          if (tem != t && negate_expr_p (tem))
            return fold_convert_loc (loc, type, negate_expr (tem));
        }
      break;

vs. negate_expr_p:

  STRIP_SIGN_NOPS (t);

the type stripping has to be consistent.  Thus the fix is to
add the same STRIP_SIGN_NOPS to fold_negate_expr (negate_expr
does it as well!) or to remove it everywhere and handle the
cases allowed in case NOP_EXPR: by recursing.

Note it needs to fold back the result to the correct type
(like negate_expr does).  Most easily by making fold_negate_expr
a wrapper around fold_negate_expr_1 and stripping/restoring the nop in
the wrapper.

Not sure if we had it at some point.  My oldest source is GCC 4.3
and it behaves the same way.

Reply via email to