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.  */
bad0(void)10 int bad0(void) { return __builtin_constant_p(global); }
bad1(void)11 int bad1(void) { return __builtin_constant_p(global++); }
bad2(int x)12 inline int bad2(int x) { return __builtin_constant_p(x++); }
bad3(int x)13 inline int bad3(int x) { return __builtin_constant_p(x); }
bad4(const char * x)14 inline int bad4(const char *x) { return __builtin_constant_p(x); }
bad5(void)15 int bad5(void) { return bad2(1); }
bad6(int x)16 inline int bad6(int x) { return __builtin_constant_p(x+1); }
bad7(void)17 int bad7(void) { return __builtin_constant_p(func()); }
bad8(void)18 int bad8(void) { char buf[10]; return __builtin_constant_p(buf); }
bad9(const char * x)19 int bad9(const char *x) { return __builtin_constant_p(x[123456]); }
bad10(void)20 int bad10(void) { return __builtin_constant_p(&global); }
21 
22 /* These must pass, or we've broken gcc2 functionality.  */
good0(void)23 int good0(void) { return __builtin_constant_p(1); }
good1(void)24 int good1(void) { return __builtin_constant_p("hi"); }
good2(void)25 int good2(void) { return __builtin_constant_p((1234 + 45) & ~7); }
26 
27 /* These are extensions to gcc2.  Failure indicates an optimization
28    regression.  */
opt0(void)29 int opt0(void) { return bad3(1); }
opt1(void)30 int opt1(void) { return bad6(1); }
opt2(void)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 
main()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 }
97