1 /* PR tree-optimization/33136 */ 2 /* { dg-do run } */ 3 /* { dg-options "-O2" } */ 4 5 extern void abort (void); 6 7 struct S 8 { 9 void *a; 10 int b[3]; 11 double *c; 12 }; 13 static double d, e; 14 15 static struct S s; 16 17 static int * 18 __attribute__((noinline, const)) foo(void)19foo (void) 20 { 21 return (int *) &s.b; 22 } 23 24 double * 25 __attribute__((noinline)) bar(double ** f)26bar (double **f) 27 { 28 s.c = &d; 29 *f = &e; 30 /* As nothing ever takes the address of any double * field in struct S, 31 the write to *f can't alias with the s.c field. */ 32 return s.c; 33 } 34 35 int 36 __attribute__((noinline)) baz(int * x)37baz (int *x) 38 { 39 s.b[0] = 1; 40 *x = 4; 41 /* Function foo takes address of an int array field in struct S, 42 so *x can alias with the s.b field (and it does in this testcase). */ 43 return s.b[0]; 44 } 45 46 int 47 __attribute__((noinline)) t(void)48t (void) 49 { 50 double *f = (double *) 0; 51 return 10 * (bar (&f) != &d) + baz (foo ()); 52 } 53 54 int main(void)55main (void) 56 { 57 if (t () != 4) 58 abort (); 59 return 0; 60 } 61