152
|
1 /* { dg-do run } */
|
|
2
|
|
3 struct list { struct list *n; };
|
|
4
|
|
5 struct obj {
|
|
6 int n;
|
|
7 struct list l;
|
|
8 } _o;
|
|
9
|
|
10 struct list _l = { .n = &_o.l };
|
|
11
|
|
12 int main(int argc, char *argv[])
|
|
13 {
|
|
14 struct obj *o = &_o;
|
|
15 _o.l.n = &_l;
|
|
16 while (&o->l != &_l)
|
|
17 /* Note the following is invoking undefined behavior but in
|
|
18 this kind of "obvious" cases we don't want to break things
|
|
19 unnecessarily and thus we avoid analyzing o as pointing
|
|
20 to nothing via the undefined pointer subtraction. Instead
|
|
21 we canonicalize the pointer subtraction followed by the
|
|
22 pointer conversion to pointer offsetting. */
|
|
23 o = ((struct obj *)((const char *)(o->l.n)
|
|
24 - (const char *)&((struct obj *)0)->l));
|
|
25 return 0;
|
|
26 }
|