1  /* { dg-do run } */
       2  
       3  extern void exit (int) __attribute__ ((noreturn));
       4  extern void abort (void) __attribute__ ((noreturn));
       5  
       6  struct t
       7  {
       8    char dummy;
       9  };
      10  
      11  struct m
      12  {
      13    const struct t *t;
      14    void (*m)(void);
      15  };
      16  
      17  struct s
      18  {
      19    const struct m *m;
      20    void *o;
      21  };
      22  
      23  struct e
      24  {
      25    const struct t *t;
      26    void *o;
      27  };
      28  
      29  struct ret
      30  {
      31    struct s s;
      32    _Bool b;
      33  };
      34  
      35  const struct t t1 = { 1 };
      36  const struct t t2 = { 2 };
      37  const struct t t3 = { 3 };
      38  const struct t t4 = { 4 };
      39  const struct t t5 = { 5 };
      40  
      41  void
      42  pass (void)
      43  {
      44    exit (0);
      45  }
      46  
      47  void
      48  fail (void)
      49  {
      50    abort ();
      51  }
      52  
      53  const struct m m1 = { &t4, fail };
      54  const struct m m2 = { &t5, pass };
      55  
      56  static struct e f2 (struct s s2, void *p);
      57  static struct e f3 (struct s, void *) __attribute__ ((noinline));
      58  static void f4 (struct s, void *) __attribute__ ((noinline));
      59  
      60  struct ret c (struct s, const struct t *) __attribute__ ((noinline));
      61  
      62  struct ret
      63  c (struct s s1, const struct t *t)
      64  {
      65    struct ret r;
      66  
      67    if (s1.m->t == t)
      68      {
      69        r.s.m = &m2;
      70        r.s.o = s1.o;
      71        r.b = 1;
      72      }
      73    else
      74      {
      75        r.s.m = 0;
      76        r.s.o = 0;
      77        r.b = 0;
      78      }
      79    return r;
      80  }
      81  
      82  void *m (void) __attribute__ ((noinline));
      83  
      84  void *
      85  m (void)
      86  {
      87    return 0;
      88  }
      89  
      90  struct e
      91  f1 (struct s s1, void *p)
      92  {
      93    struct ret r;
      94    void *a;
      95    struct s a2;
      96  
      97    r = c (s1, &t5);
      98    if (r.b)
      99      return f2 (r.s, p);
     100    a = m ();
     101    a2.m = &m1;
     102    a2.o = a;
     103    return f2 (a2, p);
     104  }
     105  
     106  static struct e
     107  f2 (struct s s2, void *p)
     108  {
     109    struct e e1;
     110  
     111    e1 = f3 (s2, p);
     112    if (e1.t == &t2 && e1.o == 0)
     113      {
     114        e1.t = 0;
     115        e1.o = 0;
     116      }
     117    return e1;
     118  }
     119  
     120  static struct e
     121  f3 (struct s s1, void *p)
     122  {
     123    struct e r;
     124  
     125    f4 (s1, p);
     126    r.t = &t3;
     127    r.o = 0;
     128    return r;
     129  }
     130  
     131  struct s g1;
     132  void *g2;
     133  
     134  static void
     135  f4 (struct s s1, void *p)
     136  {
     137    g1 = s1;
     138    g2 = p;
     139    s1.m->m ();
     140  }
     141  
     142  int
     143  main ()
     144  {
     145    struct s s1;
     146  
     147    s1.m = &m2;
     148    s1.o = 0;
     149    f1 (s1, 0);
     150    abort ();
     151  }