This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/30252] [4.2 regression] miscompilation of sigc++-2.0 based code with -fstrict-aliasing
- From: "dberlin at dberlin dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 5 Jun 2007 16:20:21 -0000
- Subject: [Bug c++/30252] [4.2 regression] miscompilation of sigc++-2.0 based code with -fstrict-aliasing
- References: <bug-30252-7958@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #34 from dberlin at gcc dot gnu dot org 2007-06-05 16:20 -------
Subject: Re: [4.2 regression] miscompilation of sigc++-2.0 based code with
-fstrict-aliasing
On 5 Jun 2007 09:27:34 -0000, rguenth at gcc dot gnu dot org
<gcc-bugzilla@gcc.gnu.org> wrote:
>
>
> ------- Comment #30 from rguenth at gcc dot gnu dot org 2007-06-05 09:27 -------
> See this testcase (reduced from spec2k6 dealII by Micha):
>
> struct I {
> int ix;
> struct II {
> int j,i;
> void *ptr;
> } ii;
> };// inner;
> struct O : public I {
> // int x;
> int y;
> };
>
> static int geti (struct O *o)
> {
> return o->ii.i;
> }
> extern void init(struct O*);
> extern void deinit(struct O*);
> extern int getcond(void);
> struct O::I *getinner (struct O*);
> int reset (int cond)
> {
>
> struct O cell;
> struct O *o;
> struct I::II *in;
> int *pi;
> o = &cell;
> init (o);
> in = &o->ii;
> while (getcond()) {
> if (o->y)
> cell.ii.i = -2;
> if (!getcond()) {
> in->i = -1;
> in->j = o->ii.i;
> break;
> }
> }
> pi = &in->j;
> pi++;
> deinit(&cell);
> return *pi;
> }
>
> and note how we compute the wrong points-to solution for in:
>
> o_3 = { cell cell.y cell.ptr cell.i cell.j }
> in_4 = { cell.y cell.ptr cell.j }
>
> we are missing cell.i in the points-to set. This is because with looking
> simply for vars with oldoffset + offset is appearantly not enough here.
>
> cell + 64 -> cell.j
> cell.y + 64 -> off structure
> cell.ptr + 64 -> cell.y
> cell.i + 64 -> cell.ptr (actually in the middle of it)
> cell.j + 64 -> cell.ptr
>
> so, there is nothing in the structure that, if added 64, will point to
> cell.i. But of course we are taking the address of the substructure and
> so we are indeed pointing to cell.i.
We are pointing to cell, and using that to access cell.i
Not quite the same thing.
But I guess in our world we have to make them the same thing.
> So a different solution would be to add _each_ var starting with the
> first one + offset.
You don't want to play in solution_set_add, which is common to a bunch of code.
The only cases where the above problem comes into play is in offseted
copy constraints, line 1520 (IE the last part of
do_complex_constraint).
In actuality, this is a bug in constraint building.
When we generate the constraints for in = &o->ii, we should be adding
an offsetted copy constraint for each offset of type *o.
This will fix the problem.
> I did with the patch (it needs some fixing still, as pruning at the
> end is bogus in it as vars may be still reached from others).
>
You can never get back to the parent structure from a pointer to the
substructure.
I asked this explicitly and was told it was undefined behavior.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30252