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 >