On Tue, Oct 11, 2011 at 5:32 PM, Joseph S. Myers
<jos...@codesourcery.com> wrote:
> This patch fixes PR 50565, a failure to accept certain offsetof-type
> expressions in static initializers introduced by my constant
> expressions changes.  (These expressions are permitted but not
> required by ISO C to be accepted; the intent of my constant
> expressions model is that they should be valid in GNU C.)
>
> The problem comes down to an expression with the difference of two
> pointers being cast to int on a 64-bit system, resulting in
> convert_to_integer moving the conversions inside the subtraction.
> (These optimizations at conversion time should really be done later as
> a part of folding, or even later than that, rather than
> unconditionally in convert_to_*, but that's another issue.)  So when
> the expression reaches c_fully_fold it is a difference of narrowed
> pointers being folded, which the compiler cannot optimize as it can a
> difference of unnarrowed pointers with the same base object.  Before
> the introduction of c_fully_fold the difference would have been folded
> when built and so the narrowing of operands would never have been
> applied to it.
>
> This patch disables the narrowing in the case of pointer subtraction,
> as it doesn't seem particularly likely to be useful there and is known
> to prevent this folding required for these initializers to be
> accepted.
>
> Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  OK to
> commit?

Ok.

Thanks,
Richard.

> 2011-10-11  Joseph Myers  <jos...@codesourcery.com>
>
>        PR c/50565
>        * convert.c (convert_to_integer): Do not narrow operands of
>        pointer subtraction.
>
> testsuite:
> 2011-10-11  Joseph Myers  <jos...@codesourcery.com>
>
>        PR c/50565
>        * gcc.c-torture/compile/pr50565-1.c,
>        gcc.c-torture/compile/pr50565-2.c: New tests.
>
> Index: gcc/testsuite/gcc.c-torture/compile/pr50565-1.c
> ===================================================================
> --- gcc/testsuite/gcc.c-torture/compile/pr50565-1.c     (revision 0)
> +++ gcc/testsuite/gcc.c-torture/compile/pr50565-1.c     (revision 0)
> @@ -0,0 +1,4 @@
> +struct s { char p[2]; };
> +static struct s v;
> +const int o0 = (int) ((void *) &v.p[0] - (void *) &v) + 0U;
> +const int o1 = (int) ((void *) &v.p[0] - (void *) &v) + 1U;
> Index: gcc/testsuite/gcc.c-torture/compile/pr50565-2.c
> ===================================================================
> --- gcc/testsuite/gcc.c-torture/compile/pr50565-2.c     (revision 0)
> +++ gcc/testsuite/gcc.c-torture/compile/pr50565-2.c     (revision 0)
> @@ -0,0 +1,4 @@
> +struct s { char p[2]; };
> +static struct s v;
> +const int o0 = (int) ((void *) &v.p[0] - (void *) &v) + 0;
> +const int o1 = (int) ((void *) &v.p[0] - (void *) &v) + 1;
> Index: gcc/convert.c
> ===================================================================
> --- gcc/convert.c       (revision 179754)
> +++ gcc/convert.c       (working copy)
> @@ -745,6 +745,15 @@ convert_to_integer (tree type, tree expr
>            tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
>            tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
>
> +           /* Do not try to narrow operands of pointer subtraction;
> +              that will interfere with other folding.  */
> +           if (ex_form == MINUS_EXPR
> +               && CONVERT_EXPR_P (arg0)
> +               && CONVERT_EXPR_P (arg1)
> +               && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 0)))
> +               && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg1, 0))))
> +             break;
> +
>            if (outprec >= BITS_PER_WORD
>                || TRULY_NOOP_TRUNCATION (outprec, inprec)
>                || inprec > TYPE_PRECISION (TREE_TYPE (arg0))
>
> --
> Joseph S. Myers
> jos...@codesourcery.com
>

Reply via email to