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 
main(int argc,char * argv[])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 }
27