This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix libstdc++/C++ fallout from RTL alias export


On Fri, 22 Jan 2010, Paolo Carlini wrote:

> Richard --
> 
> let's see if I understand your explanation, basing on the previous one:
> >   D.12950_92 = (struct _Simple_type_wrapper *) 
> > &D.12951.D.8815._M_functor._M_pod_data[0];
> >   *D.12950_92 = D.12949;
> >   __old_functor = D.12951.D.8815._M_functor;
> >
> > where it stores a struct _Simple_type_wrapper into _M_pod_data and
> > then reads from it via a union _Any_data type.
> >
> > Generated from tr1::function::swap.  Looks innocent but in reality
> > isn't:
> >
> >       void swap(function& __x)
> >       {
> >         _Any_data __old_functor = _M_functor;
> >         _M_functor = __x._M_functor;
> >
> > because you are effectively doing
> >
> >   int a, b;
> >   *(float *)&a = 0.0;
> >   b = a;
> >   
> If I understand correctly, the problem in swap is that we think we are
> doing safe operations because we are copying all _Any_data things, but
> in fact, by the time we are here performing the swap, we have stored a
> different effective type, _Tp, in those char array buffer, that is, not
> some chars, and, until we store a different type and begin a "new
> story", we can only use those as is if they were of type _Tp, not array
> of char (aka, _Any_data). Thus, I'm thinking, performance issues aside,
> would it be also correct, instead of using memcpy, using the _M_access
> members? I think so. But if you think memcpy is better, I'm also ok with
> it (after having fixed that memcpy over-optimization that is ;)

Correct.

> Just wanted to confirm I'm finally understanding these - interesting
> indeed - stories...

As memcpy is misoptimized I'm leaning towards using uninitialized_copy
on the members (but I'm not able to get the fancy things right there),
or simply do

        for (unsigned i = 0; i < sizeof (_Any_data); ++i)
          std::swap(((char *)__x._M_functor._M_access())[i],
                    ((char *)_M_functor._M_access())[i]);

that also avoids the temporary object.  There doesn't seem to be
a uninitalized_swap.

The above seems to work, but I of course have to double-check on the
other testcases I have at hand.

Richard.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]