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: 8 Jul 2003 00:14:01 -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-07-08 00:13 -------
Subject: Re: [3.3/3.4 regression] mozilla-1.4 miscompiled
Hi,
I could not recreate the bug with anything like the code you showed.
So I went back to the last testcase I posted and removed all of
the templates to make it easier to see what is going on and to further
simplify things.
I found something very strange (to me).
[kbhend@base1 huh]$ g++ -O2 -o tcase3 tcase3.cxx
[kbhend@base1 huh]$ ./tcase3
Segmentation fault
[kbhend@base1 huh]$ g++ -O2 -DALL_INTERNAL -o tcase3 tcase3.cxx
[kbhend@base1 huh]$ ./tcase3
done
All ALL_INTERNAL does is control whether one method is defined
internal to the class defintion or external to it.
This makes no sense to me but I hope it might for someone
who knows C++ well.
Here is the tcase3.cxx
#include <cstdlib>
#include <cstdio>
class Iface {
public:
virtual int Add(void) = 0;
};
class M : public Iface {
public:
int i;
int Add(void) { i++; return i; }
int SetMutable(int k) { i = k; }
};
class Safe : public M {
private:
int Add(void) { return 0; };
protected:
Safe ();
};
class Bbase {
public:
Bbase( Iface * rawPtr = 0 ) { a = rawPtr; }
void assign( Iface * q ) { a = q; }
#ifdef ALL_INTERNAL
void ** begin_assign() { assign(0); return reinterpret_cast< void **> (&a); }
#else
void ** begin_assign();
#endif
protected:
Iface * a;
};
#ifndef ALL_INTERNAL
void ** Bbase::begin_assign()
{
assign(0);
return reinterpret_cast< void **> (&a);
}
#endif
class B : private Bbase {
public:
B(): Bbase(0) {}
B( M* ptr ) : Bbase(ptr) {}
M** StartAssign() { return reinterpret_cast< M**> (begin_assign()); }
Safe* get () const { return reinterpret_cast< Safe* > (a); }
operator Safe*() const { return get(); }
Safe* operator->() const { return get(); }
};
class C {
public:
C( B& bp) : mTarget(bp) {};
operator M** () { return mTarget.StartAssign(); }
private:
B& mTarget;
};
inline C
getter( B & bp) { return C(bp); }
int
main(int argc, char** argv)
{
Iface * p;
B b1;
b1 = new M();
p=static_cast< Iface* >(b1);
B b2;
M** retval = getter(b2);
*retval = static_cast< M* >(p);
b2->SetMutable(0);
fprintf(stderr,"done\n"); fflush(stderr);
return 0;
}
Hope this tells someone something.
Kevin