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