On Fri, 17 Feb 2017, Marek Polacek wrote:

> For "(int) -x", which is a NOP_EXPR, negate_expr_p returns true, which means
> that fold_negate_expr cannot return NULL_TREE.  But that's what happens here,
> leading to a crash in fold_build2.  negate_expr_p has (as well as negate_expr)
> STRIP_SIGN_NOPS, so the "(int) -x" becomes "-x", but fold_negate_expr doesn't
> have any STRIP_SIGN_NOPS.  Richi suggested to add a wrapper for 
> fold_negate_expr
> that strips/restores such NOP_EXPRs, much like negate_expr, which is what this
> patch does.
> 
> Bootstrapped/regtested on x86_64-linux, ok for trunk?  And 6 after a while?

Ok.

Thanks,
Richard.

> 2017-02-16  Marek Polacek  <pola...@redhat.com>
> 
>       PR middle-end/79536
>       * fold-const.c (fold_negate_expr_1): Renamed from fold_negate_expr.
>       (fold_negate_expr): New wrapper.
> 
>       * gcc.dg/torture/pr79536.c: New test.
> 
> diff --git gcc/fold-const.c gcc/fold-const.c
> index a8bb8af..ad4770b 100644
> --- gcc/fold-const.c
> +++ gcc/fold-const.c
> @@ -139,6 +139,7 @@ static tree fold_relational_const (enum tree_code, tree, 
> tree, tree);
>  static tree fold_convert_const (enum tree_code, tree, tree);
>  static tree fold_view_convert_expr (tree, tree);
>  static bool vec_cst_ctor_to_array (tree, tree *);
> +static tree fold_negate_expr (location_t, tree);
>  
>  
>  /* Return EXPR_LOCATION of T if it is not UNKNOWN_LOCATION.
> @@ -522,7 +523,7 @@ negate_expr_p (tree t)
>     returned.  */
>  
>  static tree
> -fold_negate_expr (location_t loc, tree t)
> +fold_negate_expr_1 (location_t loc, tree t)
>  {
>    tree type = TREE_TYPE (t);
>    tree tem;
> @@ -533,7 +534,7 @@ fold_negate_expr (location_t loc, tree t)
>      case BIT_NOT_EXPR:
>        if (INTEGRAL_TYPE_P (type))
>          return fold_build2_loc (loc, PLUS_EXPR, type, TREE_OPERAND (t, 0),
> -                            build_one_cst (type));
> +                             build_one_cst (type));
>        break;
>  
>      case INTEGER_CST:
> @@ -581,14 +582,14 @@ fold_negate_expr (location_t loc, tree t)
>      case COMPLEX_EXPR:
>        if (negate_expr_p (t))
>       return fold_build2_loc (loc, COMPLEX_EXPR, type,
> -                         fold_negate_expr (loc, TREE_OPERAND (t, 0)),
> -                         fold_negate_expr (loc, TREE_OPERAND (t, 1)));
> +                             fold_negate_expr (loc, TREE_OPERAND (t, 0)),
> +                             fold_negate_expr (loc, TREE_OPERAND (t, 1)));
>        break;
>  
>      case CONJ_EXPR:
>        if (negate_expr_p (t))
>       return fold_build1_loc (loc, CONJ_EXPR, type,
> -                         fold_negate_expr (loc, TREE_OPERAND (t, 0)));
> +                             fold_negate_expr (loc, TREE_OPERAND (t, 0)));
>        break;
>  
>      case NEGATE_EXPR:
> @@ -605,7 +606,7 @@ fold_negate_expr (location_t loc, tree t)
>           {
>             tem = negate_expr (TREE_OPERAND (t, 1));
>             return fold_build2_loc (loc, MINUS_EXPR, type,
> -                               tem, TREE_OPERAND (t, 0));
> +                                   tem, TREE_OPERAND (t, 0));
>           }
>  
>         /* -(A + B) -> (-A) - B.  */
> @@ -613,7 +614,7 @@ fold_negate_expr (location_t loc, tree t)
>           {
>             tem = negate_expr (TREE_OPERAND (t, 0));
>             return fold_build2_loc (loc, MINUS_EXPR, type,
> -                               tem, TREE_OPERAND (t, 1));
> +                                   tem, TREE_OPERAND (t, 1));
>           }
>       }
>        break;
> @@ -623,7 +624,7 @@ fold_negate_expr (location_t loc, tree t)
>        if (!HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
>         && !HONOR_SIGNED_ZEROS (element_mode (type)))
>       return fold_build2_loc (loc, MINUS_EXPR, type,
> -                         TREE_OPERAND (t, 1), TREE_OPERAND (t, 0));
> +                             TREE_OPERAND (t, 1), TREE_OPERAND (t, 0));
>        break;
>  
>      case MULT_EXPR:
> @@ -638,11 +639,11 @@ fold_negate_expr (location_t loc, tree t)
>         tem = TREE_OPERAND (t, 1);
>         if (negate_expr_p (tem))
>           return fold_build2_loc (loc, TREE_CODE (t), type,
> -                             TREE_OPERAND (t, 0), negate_expr (tem));
> +                                 TREE_OPERAND (t, 0), negate_expr (tem));
>         tem = TREE_OPERAND (t, 0);
>         if (negate_expr_p (tem))
>           return fold_build2_loc (loc, TREE_CODE (t), type,
> -                             negate_expr (tem), TREE_OPERAND (t, 1));
> +                                 negate_expr (tem), TREE_OPERAND (t, 1));
>       }
>        break;
>  
> @@ -715,6 +716,19 @@ fold_negate_expr (location_t loc, tree t)
>    return NULL_TREE;
>  }
>  
> +/* A wrapper for fold_negate_expr_1.  */
> +
> +static tree
> +fold_negate_expr (location_t loc, tree t)
> +{
> +  tree type = TREE_TYPE (t);
> +  STRIP_SIGN_NOPS (t);
> +  tree tem = fold_negate_expr_1 (loc, t);
> +  if (tem == NULL_TREE)
> +    return NULL_TREE;
> +  return fold_convert_loc (loc, type, tem);
> +}
> +
>  /* Like fold_negate_expr, but return a NEGATE_EXPR tree, if T can not be
>     negated in a simpler way.  Also allow for T to be NULL_TREE, in which case
>     return NULL_TREE. */
> diff --git gcc/testsuite/gcc.dg/torture/pr79536.c 
> gcc/testsuite/gcc.dg/torture/pr79536.c
> index e69de29..6f05ca7 100644
> --- gcc/testsuite/gcc.dg/torture/pr79536.c
> +++ gcc/testsuite/gcc.dg/torture/pr79536.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +
> +typedef int A;
> +int
> +fn1 (A x, A y)
> +{
> +  if ((x + (x - y) * 1i) != -(-x + (y - x) * 1i))
> +    return 1;
> +  return 0;
> +}
> 
>       Marek
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)

Reply via email to