Linux buildhost 2.6.30.1amd64-kvm #1 SMP Tue Jul 7 10:55:30 UTC 2009 x86_64
GNU/Linux
../gcc-4.4.1/configure --disable-multilib --enable-languages=c,c++
(Also found to fail with gcc4.3.4 (64bit), gcc4.3.2 (32bit))
Test.cpp:
#include <cassert>
#include <iostream>
using std::cout;
using std::endl;
class BaseIf
{
public:
BaseIf()
{ cout << "BaseIf@" << this << endl; }
virtual int getBaseVal() const =0;
};
class DerivedIf : public virtual BaseIf
{};
class Base : public virtual BaseIf
{
private:
int baseVal;
public:
Base(int _baseVal)
: baseVal(_baseVal)
{}
int getBaseVal() const
{ return baseVal; }
};
class Derived : public Base, public virtual DerivedIf
{
public:
Derived(int baseVal)
: Base(baseVal)
{}
};
class InnerBarIf
{
public:
virtual int getVal() =0;
};
class BarIf
{
public:
virtual InnerBarIf* createInner() =0;
};
class Bar : public virtual BarIf, public virtual BaseIf
{
private:
static Bar* instance;
public:
Bar()
{
cout << "Bar@" << this << endl;
instance = this;
}
class InnerBar : public virtual InnerBarIf
{
public:
int getVal()
{
Bar& bar(getOuter());
cout << "bar: " << &bar << endl;
assert (&bar == Bar::instance);
BaseIf& baseIf(bar);
cout << "baseIf:" << &baseIf << endl;
cout << "baseIf.getBaseVal():" << baseIf.getBaseVal() << endl;
cout << "bar.getBaseVal(): " << bar.getBaseVal() << endl;
return bar.getBaseVal();
}
virtual Bar& getOuter() =0;
};
};
Bar* Bar::instance;
class Bart : public Derived, public Bar
{
public:
class InnerBart : public InnerBar
{
private:
Bart& outer;
public:
InnerBart(Bart& _outer)
: outer(_outer)
{
cout << "outer:" << &_outer << endl;
}
Bart& getOuter() // covariant return, broken!
//Bar& getOuter() // this works
{ return outer; }
};
Bart(int baseVal)
: Derived(baseVal)
{}
InnerBart* createInner()
{ return new InnerBart(*this); }
};
int main(int argc, char** argv)
{
const int BASE_VAL(4711);
Bart bart(BASE_VAL);
cout << "bart: " << &bart << endl;
BaseIf& baseIf(bart);
cout << "baseIf: " << &baseIf << endl;
Bar& bar = bart;
cout << "bar: " << &bar << endl;
BaseIf& baseIf2(bar);
cout << "baseIf2:" << &baseIf2 << endl;
cout << "bart.getBaseVal(): " << bart.getBaseVal() << endl;
cout << "baseIf.getBaseVal(): " << baseIf.getBaseVal() << endl;
cout << "bar.getBaseVal(): " << bar.getBaseVal() << endl;
cout << "baseIf2.getBaseVal():" << baseIf2.getBaseVal() << endl;
Bart::InnerBart* inner = bart.createInner();
int res = inner->getVal();
assert(res == BASE_VAL);
}
--
Summary: Wrong adress returned in covariant return
Product: gcc
Version: 4.4.1
Status: UNCONFIRMED
Severity: major
Priority: P3
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: philipp dot berndt at gmx dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40997