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

Reply via email to