1  /* Verify that simple indirect calls are inlined even without early
       2     inlining..  */
       3  /* { dg-do run } */
       4  /* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining"  } */
       5  
       6  extern void abort (void);
       7  
       8  struct S
       9  {
      10    int i;
      11    void (*f)(struct S *);
      12    int j,k,l;
      13  };
      14  
      15  struct Z
      16  {
      17    unsigned u;
      18    void (*f)(struct Z *, int);
      19    struct Z *next;
      20  };
      21  
      22  static struct S *gs;
      23  static int gr = 111;
      24  char gc[1024];
      25  
      26  static __attribute__ ((noinline, noclone)) struct S *
      27  get_s (void)
      28  {
      29    return (struct S *) &gc;
      30  }
      31  
      32  static void wrong_target (struct S *s)
      33  {
      34    abort ();
      35  }
      36  
      37  static void good_target (struct S *s)
      38  {
      39    gr = 0;
      40  }
      41  
      42  static void g1 (struct S *s)
      43  {
      44    s->f (s);
      45  }
      46  
      47  static void f2 (struct Z *z)
      48  {
      49    gs->f = good_target;
      50    g1 ((struct S *) z);
      51  }
      52  
      53  static inline __attribute__ ((flatten)) void f1 (struct S *s)
      54  {
      55    f2 ((struct Z *) s);
      56  }
      57  
      58  int main (int argc, char **argv)
      59  {
      60    struct S *s = get_s();
      61    s->i = 5678;
      62    s->f = wrong_target;
      63    s->j = 1234;
      64    gs = s;
      65    f1 (s);
      66  
      67    return gr;
      68  }
      69  
      70  
      71  /* { dg-final { scan-ipa-dump-not "wrong_target\[^\\n\]*inline copy in" "inline"  } } */