This is the mail archive of the gcc-bugs@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]
Other format: [Raw text]

[Bug c++/11376] [3.3/3.4 regression] mozilla-1.4 miscompiled


PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11376



------- Additional Comments From kevin dot hendricks at sympatico dot ca  2003-06-30 14:04 -------
Subject: Re:  [3.3/3.4 regression] mozilla-1.4 miscompiled

Hi,

Here is an even simpler test case with the specialized templates removed.
cat tcase2a.cxx

#include <cstdlib>
#include <cstdio>

typedef unsigned int nsrefcnt;
typedef unsigned int nsresult;

class nsISupports {
public:
  virtual nsrefcnt AddRef(void) = 0;
  virtual nsrefcnt Release(void) = 0;
};


class mc0 : public nsISupports {
public:
  int hello;
  int setHello(int j) { hello = j; }
  int SetMutable(int k) { setHello(k); }
  nsrefcnt AddRef(void) { hello++; }
  nsrefcnt Release(void) { hello--; }
};



template <class T>
class nsDerivedSafe : public T
  {
    private:
      nsrefcnt AddRef(void);
      nsrefcnt Release(void);
    protected:
      nsDerivedSafe();
  };


template <class T>
nsrefcnt
nsDerivedSafe<T>::AddRef()
  {
    return 0;
  }


template <class T>
nsrefcnt
nsDerivedSafe<T>::Release()
  {
    return 0;
  }



class nsCOMPtr_base
  {
    public:

      nsCOMPtr_base( nsISupports* rawPtr = 0 )
          : mRawPtr(rawPtr)
        {
        }


      ~nsCOMPtr_base();

      void assign_with_AddRef( nsISupports* );
      void** begin_assignment();

    protected:
      nsISupports* mRawPtr;

      void
      assign_assuming_AddRef( nsISupports* newPtr )
        {
          nsISupports* oldPtr = mRawPtr;
          mRawPtr = newPtr;
          if ( oldPtr )
            (oldPtr)->Release();
        }
  };


nsCOMPtr_base::~nsCOMPtr_base()
{
    if ( mRawPtr )
        (mRawPtr)->Release();
}


void
nsCOMPtr_base::assign_with_AddRef( nsISupports* rawPtr )
{
    if ( rawPtr )
        (rawPtr)->AddRef();
    assign_assuming_AddRef(rawPtr);
}


void**
nsCOMPtr_base::begin_assignment()
{
    assign_assuming_AddRef(0);
    return reinterpret_cast< void** >(&mRawPtr);
}



template <class T>
class nsCOMPtr : private nsCOMPtr_base
  {
    public:
      typedef T element_type;
      nsCOMPtr()
            : nsCOMPtr_base(0)
        {
        }

      nsCOMPtr( const nsCOMPtr<T>& aSmartPtr )
            : nsCOMPtr_base(aSmartPtr.mRawPtr)

        {
          if ( mRawPtr )
            (mRawPtr)->AddRef();
        }

      nsCOMPtr( T* aRawPtr )
            : nsCOMPtr_base(aRawPtr)

        {
          if ( mRawPtr )
            (mRawPtr)->AddRef();
        }


      nsCOMPtr<T>&
      operator=( const nsCOMPtr<T>& rhs )

        {
          assign_with_AddRef(rhs.mRawPtr);
          return *this;
        }

      nsCOMPtr<T>&
      operator=( T* rhs )

        {
          assign_with_AddRef(rhs);
          return *this;
        }


      nsDerivedSafe<T>*
      get() const
        {
          return reinterpret_cast< nsDerivedSafe<T>* >(mRawPtr);
        }

      operator nsDerivedSafe<T>*() const
        {
          return get();
        }

      nsDerivedSafe<T>*
      operator->() const
        {
          return get();
        }

      nsCOMPtr<T>*
      get_address()
        {
          return this;
        }

      const nsCOMPtr<T>*
      get_address() const
        {
          return this;
        }


    public:
      nsDerivedSafe<T>&
      operator*() const
        {
          return *get();
        }


      T**
      StartAssignment()
        {
          return reinterpret_cast< T** >(begin_assignment());
        }
  };



template <class T>
inline
nsCOMPtr<T>*
address_of( nsCOMPtr<T>& aPtr )
  {
    return aPtr.get_address();
  }



template <class T>
inline
const nsCOMPtr<T>*
address_of( const nsCOMPtr<T>& aPtr )
  {
    return aPtr.get_address();
  }



template <class T>
class nsGetterAddRefs
  {
    public:
      explicit
      nsGetterAddRefs( nsCOMPtr<T>& aSmartPtr )
          : mTargetSmartPtr(aSmartPtr)
        {
        }

      operator void**()
        {
          return reinterpret_cast< void** 
>(mTargetSmartPtr.StartAssignment());
        }

      operator nsISupports**()
        {
          return reinterpret_cast< nsISupports** 
>(mTargetSmartPtr.StartAssignment());
        }

      operator T**()
        {
          return mTargetSmartPtr.StartAssignment();
        }

      T*&
      operator*()
        {
          return *(mTargetSmartPtr.StartAssignment());
        }

    private:
      nsCOMPtr<T>& mTargetSmartPtr;
  };


template <class T>
inline
nsGetterAddRefs<T>
getter_AddRefs( nsCOMPtr<T>& aSmartPtr )
  {
    return nsGetterAddRefs<T>(aSmartPtr);
  }


int
main(int argc, char** argv)
{

    nsISupports* aFrames[1];
    nsCOMPtr<mc0> myframe;
    myframe = new mc0();
    aFrames[0]=static_cast<nsISupports*> (myframe);

    nsCOMPtr<mc0> currentFrame;
    mc0** retval = getter_AddRefs(currentFrame);

    nsISupports* _elem = aFrames[0];
    *retval = static_cast< mc0* >(_elem);

    currentFrame->SetMutable(0);

    fprintf(stderr,"done\n"); fflush(stderr);
    return 0;
}


Hope this helps.

Kevin


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