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