This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/11376] [3.3/3.4 regression] mozilla-1.4 miscompiled
- From: "kevin dot hendricks at sympatico dot ca" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 30 Jun 2003 14:35:26 -0000
- Subject: [Bug c++/11376] [3.3/3.4 regression] mozilla-1.4 miscompiled
- References: <20030630081619.11376.sirl@gcc.gnu.org>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
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:35 -------
Subject: Re: [3.3/3.4 regression] mozilla-1.4 miscompiled
Hi,
Okay I took a shot at removing all of the functions/methods that I felt were
not involved and have a simpler test case.
cat tcase2b.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( T* aRawPtr )
: nsCOMPtr_base(aRawPtr)
{
if ( mRawPtr )
(mRawPtr)->AddRef();
}
nsCOMPtr<T>&
operator=( const nsCOMPtr<T>& rhs )
{
assign_with_AddRef(rhs.mRawPtr);
return *this;
}
nsDerivedSafe<T>*
get() const
{
return reinterpret_cast< nsDerivedSafe<T>* >(mRawPtr);
}
operator nsDerivedSafe<T>*() const
{
return get();
}
nsDerivedSafe<T>*
operator->() const
{
return get();
}
public:
T**
StartAssignment()
{
return reinterpret_cast< T** >(begin_assignment());
}
};
template <class T>
class nsGetterAddRefs
{
public:
explicit
nsGetterAddRefs( nsCOMPtr<T>& aSmartPtr )
: mTargetSmartPtr(aSmartPtr)
{
}
operator T**()
{
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;
}
[kbhend@base1 huh]$ gcc -dumpversion
3.3
[kbhend@base1 huh]$ g++ -O2 -fno-exceptions -o tcase2b tcase2b.cxx
[kbhend@base1 huh]$ ./tcase2b
Segmentation fault
[kbhend@base1 huh]$ g++ -O2 -o tcase2b tcase2b.cxx
[kbhend@base1 huh]$ ./tcase2b
Segmentation fault
[kbhend@base1 huh]$ g++ -O2 -fno-exceptions -fno-strict-aliasing -o tcase2b
tcase2b.cxx
[kbhend@base1 huh]$ ./tcase2b
done
Hope this helps,
Kevin