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: "mark at codesourcery dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 8 Jul 2003 05:36:38 -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 mark at codesourcery dot com 2003-07-08 05:36 -------
Subject: Re: [3.3/3.4 regression] mozilla-1.4 miscompiled
On Mon, 2003-07-07 at 19:33, kevin dot hendricks at sympatico dot ca
wrote:
> 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 02:33 -------
> Subject: Re: [3.3/3.4 regression] mozilla-1.4 miscompiled
>
> Hi,
>
> Just to add insult to injury here ...
Thanks for cutting this down; now I can see easily that this test case
is invalid C++.
> [kbhend@base1 huh]$ cat tcase6.cxx
> struct A {
> virtual int Setit(int k) = 0;
> };
>
> struct B : A {
> int Setit(int k) { int i; i = k; }
> };
>
> A* a;
> void ** begin_assign() { return reinterpret_cast< void **> (&a); }
>
> int
> main(int argc, char** argv)
> {
> B** ppB = reinterpret_cast<B**> (begin_assign());
> *ppB = new B();
> a->Setit(0);
> return 0;
> }
The problem is that "*ppB" modifies a "B*". Unfortunately, the location
pointed to by "ppB" is actually an "A*". That's invalid. (It's true
that in C++ you can assign a "B*" to an "A*", but that's not the same as
using a "B**" to point at at an "A*" and then writing into the "B**".)
Simplifying your code even further gives:
A* a;
B** ppB = (B**) &a;
*ppB = new B;
which makes it clearer that the code is invalid.
This code is very much analogous to:
long l;
int *ip = (int *) &l;
*ip = 3;
on a machine where "int" and "long" are the same width. It seems like
it should work, but it's not valid.