This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix fold_unary (PR middle-end/38771)
- From: "Richard Guenther" <richard dot guenther at gmail dot com>
- To: "Jakub Jelinek" <jakub at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 9 Jan 2009 14:27:41 +0100
- Subject: Re: [PATCH] Fix fold_unary (PR middle-end/38771)
- References: <20090109132608.GU25055@tyan-ft48-01.lab.bos.redhat.com>
On Fri, Jan 9, 2009 at 2:26 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> On the attached testcase,
> fold_unary (NEGATE_EXPR, unsigned long long, (unsigned long long) (x0 ?: x1))
> for long long x0 and x1 creates tree with invalid types
> (NEGATE_EXPR with ullong type with operand of llong type).
> The problem is that fold_unary does:
> arg0 = op0;
> STRIP_NOPS (arg0);
> but doesn't for COND_EXPR or COMPOUND_EXPR arg0 convert back to the
> right type. The right type in this case is TREE_TYPE (op0), which might
> be different from type, e.g. for code FIX_TRUNC_EXPR, NOP_EXPR, etc.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?
Ok.
Thanks,
Richard.
> 2009-01-09 Jakub Jelinek <jakub@redhat.com>
>
> PR middle-end/38771
> * fold-const.c (fold_unary): For COMPOUND_EXPR and COND_EXPR,
> fold_convert arg0 operands to TREE_TYPE (op0) first.
>
> * gcc.c-torture/compile/pr38771.c: New test.
>
> --- gcc/fold-const.c.jj 2009-01-02 09:32:55.000000000 +0100
> +++ gcc/fold-const.c 2009-01-09 09:51:24.000000000 +0100
> @@ -8053,15 +8053,19 @@ fold_unary (enum tree_code code, tree ty
> {
> if (TREE_CODE (arg0) == COMPOUND_EXPR)
> return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
> - fold_build1 (code, type, TREE_OPERAND (arg0, 1)));
> + fold_build1 (code, type,
> + fold_convert (TREE_TYPE (op0),
> + TREE_OPERAND (arg0, 1))));
> else if (TREE_CODE (arg0) == COND_EXPR)
> {
> tree arg01 = TREE_OPERAND (arg0, 1);
> tree arg02 = TREE_OPERAND (arg0, 2);
> if (! VOID_TYPE_P (TREE_TYPE (arg01)))
> - arg01 = fold_build1 (code, type, arg01);
> + arg01 = fold_build1 (code, type,
> + fold_convert (TREE_TYPE (op0), arg01));
> if (! VOID_TYPE_P (TREE_TYPE (arg02)))
> - arg02 = fold_build1 (code, type, arg02);
> + arg02 = fold_build1 (code, type,
> + fold_convert (TREE_TYPE (op0), arg02));
> tem = fold_build3 (COND_EXPR, type, TREE_OPERAND (arg0, 0),
> arg01, arg02);
>
> --- gcc/testsuite/gcc.c-torture/compile/pr38771.c.jj 2009-01-09 10:00:23.000000000 +0100
> +++ gcc/testsuite/gcc.c-torture/compile/pr38771.c 2009-01-09 09:29:27.000000000 +0100
> @@ -0,0 +1,7 @@
> +/* PR middle-end/38771 */
> +
> +unsigned long long
> +foo (long long x)
> +{
> + return -(unsigned long long) (x ? : x);
> +}
>
> Jakub
>