111
|
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;
|
|
11 int *c;
|
|
12 };
|
|
13 static int d, e;
|
|
14
|
|
15 static struct S s;
|
|
16
|
|
17 static int *
|
|
18 __attribute__((noinline, const))
|
|
19 foo (void)
|
|
20 {
|
|
21 return &s.b;
|
|
22 }
|
|
23
|
|
24 int *
|
|
25 __attribute__((noinline))
|
|
26 bar (int **f)
|
|
27 {
|
|
28 s.c = &d;
|
|
29 *f = &e;
|
|
30 /* As nothing ever takes the address of any int * 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))
|
|
37 baz (int *x)
|
|
38 {
|
|
39 s.b = 1;
|
|
40 *x = 4;
|
|
41 /* Function foo takes address of an int field in struct S,
|
|
42 so *x can alias with the s.b field (and it does in this testcase). */
|
|
43 return s.b;
|
|
44 }
|
|
45
|
|
46 int
|
|
47 __attribute__((noinline))
|
|
48 t (void)
|
|
49 {
|
|
50 int *f = (int *) 0;
|
|
51 return 10 * (bar (&f) != &d) + baz (foo ());
|
|
52 }
|
|
53
|
|
54 int
|
|
55 main (void)
|
|
56 {
|
|
57 if (t () != 4)
|
|
58 abort ();
|
|
59 return 0;
|
|
60 }
|