This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PR middle-end/30017 (ICE in C++ size hook)
Jan Hubicka wrote:
>> Jan Hubicka wrote:
>>
>>> Yes, I think what we have problem with is mixing the two highlevel and
>>> lowlevel point of views. For C++ up to gimplification it is perfectly
>>> valid to stick on the C++ conventions (such as requiring copy
>>> constructor to be used at copies), after gimplification we however
>>> should make IL independent on such a details so the structure remains
>>> just structure.
>> I'm not sure I agree. In general, the backend *must not* copy these
>> objects, as that would violate the C++ semantics. We could have a flag
>
> I am not quite sure I folow your logic here either. Perhaps some
> example would help.
Let's leave this aside. The key thing is that you don't know how many
bytes are there. Here's the example I've given in the past:
struct A {
int i;
};
struct B : virtual public A {};
Now, sizeof (B) is 8 (on an ILP32 system). But, now, consider:
struct C: public B {
};
struct D : public C, public B {
};
Here, there are two "B" subobjects of D, but only one "A" subobject.
So, if you have the second "B" subobject, there are only 4 bytes there
-- not 8. You must not try to read/write 8 bytes, even though sizeof
(B) is 8.
So, asking for the expr_size of an object of type "B" just doesn't make
sense. The answer is 4 sometimes and 8 sometimes. There's no
conservative answer: if we say 8, sometimes we'll copy bytes that aren't
there; if we say 4, sometimes we'll not copy enough. There's a
context-dependent right answer in the front end, specified by the
language semantics -- but without the context we don't know the right
answer.
> It seems to me that C++ is actually more relaxed here giving the
> mechanizm to copy data around via copy constructors (compiler is not
> allowed to use them completely freely either, right?)
No, the compiler may not call them except where explicitly permitted by
the standard. The back end must never introduce a call to a copy
constructor.
>> Can we pass down the known size, so that calling the expr_size hook is
>> unnecessary? As per the above, there's no right answer, in general, for
>> "what's the size of this C++ object of type X", so using the expr_size
>> hook is sketchy.
>
> We perhaps might play around with with_size_expr, but I don't think it
> is good idea here. Whole point of introducing the assignment is to
> allow optimizations later in queue to happen (such as copy propagation)
> and making them compatible with WITH_SIZE_EXPR is somewhat tricky too.
Why do we need a tree node? When expanding __builtin_memcpy into a
block copy, just use the size argument to __builtin_memcpy as the number
of bytes to copy. Ignore the types of the arguments. You can still do
the transformation; you just have to trust the argument to __builtin_memcpy.
> The problem is that the code quote uses TYPE_UNIT_SIZE believing that
> the value contains the type size. (ie the transformation happen only
> when the memcpy operand is identical to TYPE_UNIT_SIZE if defined.)
> Perhaps it should be set NULL then by C++ frontend as documenation
> suggest?
The type is definitely not incomplete. It is just that given a "B*",
you don't know how many bytes are pointed to by that pointer.
--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713