------- Comment #37 from matz at gcc dot gnu dot org  2007-06-05 18:24 -------
> We are pointing to cell, and using that to access cell.i

No.  We are pointing to cell.ii, and use that pointer to access cell.ii.i
(via in->i).  Hence of course the points-to set of 'in' needs to include
cell.in.i (or cell.i, as the point-to debug dump likes to call it).  At least
how the points-to solver is used.  Theoretically it would of course be more
sensible to only note that 'in' can point to 'cell.ii', and make the user
of that information recognize that this actually is a structure, and hence
over that pointer you can access all members of it.  But that's not
how the info is used, so we have to include cell.ii.i in the points to set
(which in our case rather is a can-access set).

Now, regarding where to fix it properly: if you say that solution_set_add()
is not the right place (and I don't buy that yet, because something is wrong
with it no matter what, e.g. looking for subfields starting from the things
in the pt set, which themself might be subfields feels wrong), then we must
not use pointer arithmetic (or at least '+' constraints) to represent pointing
to substructures.  And I'm not sure that's easily doable.  Because the insn
we see is not "in = &cell.in", but "in = &o->in", and only the pt solver
itself sees that 'o' points to cell.  So what constraints do you suggest
should be added instead of offseted constraints for this insn?

> You don't want to play in solution_set_add, which is common to a bunch of 
> code.

Well, it's common to exactly the code which handles offsetted constraints.
And I don't see why the problem we face here (with offseted copy constraints)
doesn't also occur with any other of the offseted constraints, e.g.
"*x = y+32", handled in do_ds_constraint.

> > 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.

Well, it's perhaps illegal in C (I'm not sure about that actually), but
certainly occurs in C++, and even if it didn't occur there we are talking
about the middle-end, for which such invalidity shouldn't matter (except we
choose to define it as invalid).  To see why this is valid, consider this
C++ program:

struct A {int a;};
struct B {int b;};
struct C : public A, B { int c;};
C* b2c (B* b) { return (C*)b; }
C* get_c (void)
{
  static C c;
  B *pb;
  C *pc;
  pb = &c;
  pc = (C*)pb;
  return pc;
}

This is completely valid (suppose b2c is only ever called with pointers
to the B-in-C base of any C), and results in this insn:

  b.2_3 = (struct C *) b_2(D);
  D.2496_4 = b.2_3 - 4;

A better example might be the other function 'get_c', which also has the
subtraction:

  pb_3 = (struct CD.2478 *) &cD.2495.D.2482;
  pc_4 = pb_3 - 4;
  return pc_4;

This currently only works because points-to gives up on subtraction and 
adds INTEGER to the access set of pc_4 (additionally to c.b and c.c; c.a
or c itself are missing).


-- 

matz at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |matz at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30252

Reply via email to