Sent from my iPhone
On May 17, 2010, at 8:37 PM, "eyakubovich at gmail dot com" <gcc-bugzi...@gcc.gnu.org
> wrote:
This is a stripped down code from proposed Boost.Move library.
Asserts don't
fire with -O0 and -O1 but do with -O2 and -O3
#include <assert.h>
template <class T>
class rv : public T
{
rv();
~rv();
rv(rv const&);
void operator=(rv const&);
};
template <class T>
rv<T>& move(T& x)
{
return *static_cast<rv<T>* >(&x);
}
//A movable class
class movable
{
movable(movable &);
movable& operator=(movable&);
public:
operator rv<movable>&()
{ return *reinterpret_cast< rv<movable>* >(this); }
operator const rv<movable>&() const
{ return *reinterpret_cast<const rv<movable>* >(this); }
private:
int value_;
public:
movable() : value_(1){}
//Move constructor and assignment
movable(rv<movable>& m)
{ value_ = m.value_; m.value_ = 0; }
movable & operator=(rv<movable>& m)
{ value_ = m.value_; m.value_ = 0; return *this; }
bool moved() const //Observer
{ return value_ == 0; }
};
movable function(movable m)
{
return movable(move(m));
}
int main()
{
{
movable m;
movable m2(move(m));
The above code cause aliasing violations because you acess a movable
object via a rv<movable> (from now on just refered to as rv for short)
one. So you have a type rv who's base type is movable. note both rv
and movable are non pods which I think removes the case for upcasting
and then accessing the first member.
assert(m.moved());
assert(!m2.moved());
}
{
movable m;
movable m3(function(movable(move(m))));
assert(m.moved());
assert(!m3.moved());
}
{
movable m;
movable m4(function(move(m)));
assert(m.moved());
assert(!m4.moved());
}
return 0;
}
--
Summary: Wrong code generated with -O2 and above
Product: gcc
Version: 4.4.4
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: eyakubovich at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44186