Bug 36387 - [4.3 Regression] points-to variables not transitively clobbered
Summary: [4.3 Regression] points-to variables not transitively clobbered
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.3.1
: P2 normal
Target Milestone: 4.4.0
Assignee: Not yet assigned to anyone
Keywords: alias, wrong-code
Depends on:
Reported: 2008-05-30 09:48 UTC by Richard Biener
Modified: 2009-06-17 12:37 UTC (History)
4 users (show)

See Also:
Known to work: 4.1.2 4.4.0
Known to fail: 4.2.4 4.3.1 4.3.4
Last reconfirmed: 2008-05-30 09:49:07


Note You need to log in before you can comment on or make changes to this bug.
Description Richard Biener 2008-05-30 09:48:54 UTC
Call clobbering doesn't transitively close the pointed-to sets.

This blocks removal of call-clobbering of variables that have their addresses
stored in local structures.

This also generates wrong code for (-O2 {,-fno-tree-sra} - dependent on
the amount of fixes installed)

extern void abort (void);
struct Foo {
    int *p;
struct Bar {
    struct Foo *x;
    int *q;
struct Foo __attribute__((noinline))
bar(int *p)
  struct Foo f;
  f.p = p;
  return f;
void __attribute__((noinline))
foo(struct Foo f)
  *f.p = 0;
int main()
  int a, b;
  a = 0;
  b = 1;
  struct Bar f;
  struct Foo g = bar (&b);
  f.x = &g;
  f.q = &a;
  if (b != 0)
    abort ();
  return 0;
Comment 1 Richard Biener 2008-05-30 09:49:06 UTC
Comment 2 Richard Biener 2008-05-30 11:38:36 UTC
It shows really that points-to analysis and call-clobber analysis cannot be
done separately.  We try to "connect" them at a single point, in handle_rhs
call where we add constraints from anything to dereferenced pointer arguments.

But this is obviously not enough as we are not transitively closing the points-to

extern void abort (void);
int j;
void __attribute__((noinline))
bar (int ***q)
  j = 1;
  **q = &j;
int main()
  int i;
  int *p = &i;
  int **q = &p;
  int ***r = &q;
  i = 0;
  bar (r);
  if (*p != 1)
    abort ();
  return 0;

while this doesn't abort in its current form, it shows that points-to
analysis thinks that p points to i, which is not true, as it points to j
after the call to bar:

<bb 2>:
  # p_7 = VDEF <p_6(D)>
  p = &i;
  # q_9 = VDEF <q_8(D)>
  q = &p;
  # i_11 = VDEF <i_10(D)>
  i = 0; 
  # i_13 = VDEF <i_11>
  # p_14 = VDEF <p_7>
  # q_15 = VDEF <q_9>
  # SMT.28_16 = VDEF <SMT.28_12(D)>
  bar (&q);
  # VUSE <p_14>
  p.0_2 = p;
  # VUSE <i_13>
  D.1569_3 = *p.0_2;
  if (D.1569_3 != 1)
    goto <bb 3>;
    goto <bb 4>;

Pointed-to sets for pointers in main

p.0_2, name memory tag: NMT.29, is dereferenced, points-to vars: { i }

if we would do a pointer-equivalence test here and use PTA for its
disambiguation things would go wrong.  The lame hack in handle_rhs_call
only saves us for double-indirection (and only because &q is invariant
and substituted in the call argument).

Now - I'd really like to hear what the "theory" says to this (handling of
escape points).  I guess they simply only handle IPA-PTA for whole-programs,
thus the "academic" case.
Comment 3 Richard Biener 2008-05-31 10:23:27 UTC
Wrong points-to result is split out to PR36400.
Comment 4 Richard Biener 2008-06-12 13:34:02 UTC
This is a regression with -O2 -fno-tree-sra and the testcase from the initial
Comment 5 Richard Biener 2008-07-01 15:35:11 UTC
This is fixed on the trunk.
Comment 6 Ramana Radhakrishnan 2009-01-15 10:38:14 UTC
Change CC addresses.
Comment 7 Richard Biener 2009-01-16 23:09:46 UTC
I have no plans of fixing this on the branches.
Comment 8 Joseph S. Myers 2009-03-31 20:52:20 UTC
Closing 4.2 branch.
Comment 9 Richard Biener 2009-06-17 12:37:42 UTC
WONTFIX for 4.3.  Alias fixes are considered too risky at this stage.