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: "rguenther at suse dot de" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 5 Jun 2007 16:30:32 -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 #35 from rguenther at suse dot de 2007-06-05 16:30 -------
Subject: Re: [4.2 regression] miscompilation of sigc++-2.0
based code with -fstrict-aliasing
On Tue, 5 Jun 2007, dberlin at dberlin dot org wrote:
> 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.
How so? The solution_set_add method is still wrong.
> > 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.
Yep, this is what I convinced myself aswell.
Richard.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30252