This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: Aliasing problem? gcc-3.3 miscompiles mozilla-1.4
- From: "Kevin B. Hendricks" <kevin dot hendricks at sympatico dot ca>
- To: Franz Sirl <Franz dot Sirl-kernel at lauterbach dot com>,gcc-bugs at gcc dot gnu dot org
- Cc: falk at debian dot org
- Date: Thu, 19 Jun 2003 10:01:40 -0400
- Subject: Re: Aliasing problem? gcc-3.3 miscompiles mozilla-1.4
- References: <200306182048.18272@enzo.bigblue.local> <200306191207.41471@enzo.bigblue.local>
Hi,
I have been playing with the test case and I think we could simply this.
Here is a new main code in question:
int
main(int argc, char** argv)
{
// array container set up to hold parent types of gfxIImageFrame
nsSupportsArray aFrames;
// create our instance of this class
// note gfxIImageFrame is a pure virtual class
nsCOMPtr<gfxIImageFrame> myframe;
nsresult rv;
myframe = do_CreateInstance("@mozilla.org/gfx/image/frame;2", &rv);
fprintf(stderr,"create return value %x\n",rv); fflush(stderr);
// now add our frame instance to the contianer
// (okay since holds our parent class)
aFrames.AppendElement(myframe);
// now create a local copy of this frame
nsCOMPtr<gfxIImageFrame> currentFrame;
// use the template class trick to get the address of our local copy
gfxIImageFrame** retval = getter_AddRefs(currentFrame);
// now read from the container and copy it to the address from above
nsISupports *_elem = aFrames.ElementAt(0);
*retval = static_cast< gfxIImageFrame* >(_elem);
// now invoke that instances SetMutable and get the instant segfault
currentFrame->SetMutable(0);
fprintf(stderr,"done\n"); fflush(stderr);
return 0;
}
So it seems that the indirection passed in to get a copy of the frame
we stored in the container is not being recognized as being required
before currentFrame can be used again when compiled with no strict aliasing
The container array holds parents of our class and therefore can hold us
without a cast and we should be able to cast down that same pointer to our
specific object/type.
So I think the problem is in how the indirection is done in the getter_AddRefs
here (see below)
I can't claim to undestand how these work. But we can certainly create a
simple container class for parents of another simple class and then use
templates for redirection in a sample program and see if that shows us the
bug.
Is it worth a try?
Kevin
template <class T>
struct already_AddRefed
{
already_AddRefed( T* aRawPtr )
: mRawPtr(aRawPtr)
{
}
T* get() const { return mRawPtr; }
T* mRawPtr;
};
template <class T>
inline
const already_AddRefed<T>
getter_AddRefs( T* aRawPtr )
{
return already_AddRefed<T>(aRawPtr);
}
template <class T>
inline
const already_AddRefed<T>
getter_AddRefs( const already_AddRefed<T> aAlreadyAddRefedPtr )
{
return aAlreadyAddRefedPtr;
}