/* { dg-do run } */ struct list { struct list *n; }; struct obj { int n; struct list l; } _o; struct list _l = { .n = &_o.l }; int main(int argc, char *argv[]) { struct obj *o = &_o; _o.l.n = &_l; while (&o->l != &_l) /* Note the following is invoking undefined behavior but in this kind of "obvious" cases we don't want to break things unnecessarily and thus we avoid analyzing o as pointing to nothing via the undefined pointer subtraction. Instead we canonicalize the pointer subtraction followed by the pointer conversion to pointer offsetting. */ o = ((struct obj *)((const char *)(o->l.n) - (const char *)&((struct obj *)0)->l)); return 0; }