This is the mail archive of the gcc@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]

Re: RFA: Examine PR2758


Mark Mitchell <mark@codesourcery.com> writes:

> PR2758 is a C++ bug report for alphaev56-unknown-linux.  I don't
> have access to such a box, so I can't figure out if this is a
> regression and/or how to debug it.  The code works fine on x86.
> 
> If you have an alpha system, would you test this code?  If it
> doesn't fail any more, please close the report.  Otherwise, please
> check if it's a regression from 2.95.2, and downgrade it if not.
> Otherwise, we'll have to try to debug it.

I have an alphaev56-unknown-linux. The code segfaults with 3.0
20010426 (Debian prerelease). Today's CVS gives a bootstrap comparison
failure, so I couldn't try. I'll also try the 3.0 branch.

It doesn't crash with version 2.95.4 20010506 (Debian prerelease) or
with 2.95.2. The crash occurs at -O2 or higher. 

I have stripped the code down a bit, because I suspected a bug in the
code, but I couldn't find one. I've attached the stripped version.
Interestingly, for the stripped version, adding -finline-functions
doesn't help anymore.

	Falk

typedef unsigned uint;

struct QShared
{
    QShared() { count = 1; }
    void ref() { count++; }
    bool deref() { return !--count; }
    uint count;
};

template <class T>
class QValueListNode
{
public:
    QValueListNode( const T& t ) : data( t ) { }
    QValueListNode() { }

    QValueListNode<T>* next;
    QValueListNode<T>* prev;
    T data;
};

template<class T>
class QValueListIterator
{
 public:
    typedef QValueListNode<T>* NodePtr;

    NodePtr node;

    QValueListIterator() : node( 0 ) {}
    QValueListIterator( NodePtr p ) : node( p ) {}
    QValueListIterator( const QValueListIterator<T>& it ) : node( it.node ) {}

    bool operator==( const QValueListIterator<T>& it ) const { return node == it.node; }
    bool operator!=( const QValueListIterator<T>& it ) const { return node != it.node; }
    const T& operator*() const { return node->data; }
    T& operator*() { return node->data; }

    QValueListIterator<T>& operator++() {
        node = node->next;
        return *this;
    }

    QValueListIterator<T> operator++(int) {
        QValueListIterator<T> tmp = *this;
        node = node->next;
        return tmp;
    }
};

template <class T>
class QValueListPrivate : public QShared
{
public:
    typedef QValueListIterator<T> Iterator;
    typedef QValueListNode<T> Node;
    typedef QValueListNode<T>* NodePtr;

    QValueListPrivate() { node = new Node; node->next = node->prev = node; nodes = 0; }
    QValueListPrivate( const QValueListPrivate<T>& _p ) : QShared() {
        node = new Node; node->next = node->prev = node; nodes = 0;
        Iterator b( _p.node->next );
        Iterator e( _p.node );
        Iterator i( node );
        while( b != e )
            insert( i, *b++ );
    }

    void derefAndDelete()
    {
	//if ( deref() ) {
//            delete this;
//	}
    }

    ~QValueListPrivate() {
//        NodePtr p = node->next;
//        while( p != node ) {
//            NodePtr x = p->next;
//            delete p;
//            p = x;
//        }
//        delete node;
    }

    Iterator insert( Iterator it, const T& x ) {
        NodePtr p = new Node( x );
        p->next = it.node;
        p->prev = it.node->prev;
        it.node->prev->next = p;
        it.node->prev = p;
        nodes++;
        return p;
    }

    NodePtr node;
    uint nodes;
};

template <class T>
class QValueList
{
public:
    typedef QValueListIterator<T> Iterator;
    typedef T ValueType;

    QValueList() { sh = new QValueListPrivate<T>; }
    QValueList( const QValueList<T>& l ) { sh = l.sh; sh->ref(); }
    ~QValueList() { sh->derefAndDelete(); }

    Iterator begin() { detach(); return Iterator( sh->node->next ); }
    Iterator end() { detach(); return Iterator( sh->node ); }

    Iterator insert( Iterator it, const T& x ) { detach(); return sh->insert( it, x ); }

    Iterator append( const T& x ) { detach(); return sh->insert( end(), x ); }

protected:
    void detach() {
	if ( sh->count > 1 ) {
	    sh->deref();
	    sh = new QValueListPrivate<T>( *sh );
	}
    }

    QValueListPrivate<T>* sh;
};


void setSizes( QValueList<int> list )
{
    // seems e. g. list.sh->count is destroyed at this point already
    QValueList<int>::Iterator it = list.begin();
}

int main(void) {
    QValueList<int> sizes;
    sizes.append(50);
    sizes.append(50);
    setSizes(sizes);

    return 0;
}

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