Re: Fix PR 50565 (offsetof-type expressions in static initializers)

2011-10-12 Thread Richard Guenther
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



Re: Fix PR 50565 (offsetof-type expressions in static initializers)

2011-10-11 Thread Gabriel Dos Reis
On Tue, Oct 11, 2011 at 10:32 AM, Joseph S. Myers
jos...@codesourcery.com wrote:

 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.)

Interesting. C++11 classified this as linktime constants, e.g. they
are constant
expressions for static initialization purposes, but not compile-time constant
expressions, precisely because of this kind of issues.