1  /* { dg-options "-fgnu89-inline" } */
       2  
       3  extern void abort (void);
       4  extern void exit (int);
       5  
       6  __attribute__ ((externally_visible)) int global;
       7  int func(void);
       8  
       9  /* These must fail.  */
      10  int bad0(void) { return __builtin_constant_p(global); }
      11  int bad1(void) { return __builtin_constant_p(global++); }
      12  inline int bad2(int x) { return __builtin_constant_p(x++); }
      13  inline int bad3(int x) { return __builtin_constant_p(x); }
      14  inline int bad4(const char *x) { return __builtin_constant_p(x); }
      15  int bad5(void) { return bad2(1); }
      16  inline int bad6(int x) { return __builtin_constant_p(x+1); }
      17  int bad7(void) { return __builtin_constant_p(func()); }
      18  int bad8(void) { char buf[10]; return __builtin_constant_p(buf); }
      19  int bad9(const char *x) { return __builtin_constant_p(x[123456]); }
      20  int bad10(void) { return __builtin_constant_p(&global); }
      21  
      22  /* These must pass, or we've broken gcc2 functionality.  */
      23  int good0(void) { return __builtin_constant_p(1); }
      24  int good1(void) { return __builtin_constant_p("hi"); }
      25  int good2(void) { return __builtin_constant_p((1234 + 45) & ~7); }
      26  
      27  /* These are extensions to gcc2.  Failure indicates an optimization
      28     regression.  */
      29  int opt0(void) { return bad3(1); }
      30  int opt1(void) { return bad6(1); }
      31  int opt2(void) { return __builtin_constant_p("hi"[0]); }
      32  
      33  /* 
      34   * Opt3 is known to fail.  It is one of the important cases that glibc
      35   * was interested in though, so keep this around as a reminder.
      36   *
      37   * The solution is to add bits to recover bytes from constant pool
      38   * elements given nothing but a constant pool label and an offset.
      39   * When we can do that, and we can simplify strlen after the fact,
      40   * then we can enable recognition of constant pool labels as constants.
      41   */
      42  
      43  /* int opt3(void) { return bad4("hi"); } */
      44  
      45  
      46  /* Call through tables so -finline-functions can't screw with us.  */
      47  int (* volatile bad_t0[])(void) = {
      48  	bad0, bad1, bad5, bad7, bad8, bad10
      49  };
      50  
      51  int (* volatile bad_t1[])(int x) = {
      52  	bad2, bad3, bad6
      53  };
      54  
      55  int (* volatile bad_t2[])(const char *x) = {
      56  	bad4, bad9
      57  };
      58  
      59  int (* volatile good_t0[])(void) = {
      60  	good0, good1, good2
      61  };
      62  
      63  int (* volatile opt_t0[])(void) = {
      64  	opt0, opt1, opt2 /* , opt3 */
      65  };
      66  
      67  #define N(arr) (sizeof(arr)/sizeof(*arr))
      68  
      69  int main()
      70  {
      71    int i;
      72  
      73    for (i = 0; i < N(bad_t0); ++i)
      74      if ((*bad_t0[i])())
      75        abort();
      76  
      77    for (i = 0; i < N(bad_t1); ++i)
      78      if ((*bad_t1[i])(1))
      79        abort();
      80  
      81    for (i = 0; i < N(bad_t2); ++i)
      82      if ((*bad_t2[i])("hi"))
      83        abort();
      84  
      85    for (i = 0; i < N(good_t0); ++i)
      86      if (! (*good_t0[i])())
      87        abort();
      88  
      89  #ifdef __OPTIMIZE__
      90    for (i = 0; i < N(opt_t0); ++i)
      91      if (! (*opt_t0[i])())
      92        abort();
      93  #endif
      94  
      95    exit(0);
      96  }