PATCH RFC: Narrowing POINTER_PLUS_EXPR can be a static initializer

Ian Lance Taylor iant@google.com
Fri Sep 5 16:19:00 GMT 2008


"Richard Guenther" <richard.guenther@gmail.com> writes:

> On Fri, Sep 5, 2008 at 7:37 AM, Ian Lance Taylor <iant@google.com> wrote:
>> I was given a test case which showed a regression in 4.3 and
>> mainline.  Consider this:
>>
>> short offsets[1] = {
>>  ((char*) &(((struct s*)16)->y) - (char *)16),
>> };
>>
>> Note that the array has type short.  When compiling this in C++, 4.2
>> generates a static initializer.  4.3 and mainline do not; they instead
>> generate a runtime constructor.  This is useless, as the expression
>> clearly can be computed at compile time, and indeed the runtime
>> constructor simply writes a constant to memory.
>>
>> This code is of course implementation defined, and using a runtime
>> constructor is a technically valid translation, but there is no ned to
>> regress in this way.
>>
>> The regression occurs because 4.2 generates a MINUS_EXPR and
>> 4.3/mainline generate a POINTER_PLUS_EXPR.  There is special code in
>> initializer_constant_valid_p to handle a narrowing subtraction.  That
>> code is currently only used for MINUS_EXPR.  The appended patch uses
>> the same code for POINTER_PLUS_EXPR as well.
>>
>> I have not bothered to open a bug report for this, but it is a
>> regression, and therefore appropriate to fix in stage 3 and on the 4.3
>> branch.
>>
>> I have bootstrapped and tested this patch on i686-pc-linux-gnu.  I
>> committed it to trunk and 4.3 branch.  (The patch to 4.3 branch is
>> trivially different due to the introduction of CONVERT_EXPR_P in
>> mainline).
>
> It looks like fold can already simplify
>
> struct s {
>   int x;
>   int y;
> };
> int foo()
> {
>   return (short)(((char*) &(((struct s*)16)->y) - (char *)16));
> }
>
> so, is the initializer not properly folded?

The initializer is not folded when using C++.  I looked in
fold-const.c, and I didn't see anything which handled folding this
unusual case; in particular, I don't see anything handling an
ADDR_EXPR of a COMPONENT_REF.  I looked at how it used to work in gcc
4.2, and discovered that it was handled in initializer_constant_valid,
so that is what I fixed.

Ian



More information about the Gcc-patches mailing list