111
|
1 /* { dg-do link } */
|
|
2 /* { dg-options "-O2" } */
|
|
3
|
|
4 struct S
|
|
5 {
|
|
6 int w, x, y, z;
|
|
7 };
|
|
8
|
|
9 struct T
|
|
10 {
|
|
11 int r;
|
|
12 struct S s;
|
|
13 };
|
|
14
|
|
15 void link_error (void);
|
|
16 int bar (struct S, int);
|
|
17
|
|
18 void
|
|
19 foo (int a, struct T b)
|
|
20 {
|
|
21 struct S *c = 0;
|
|
22
|
|
23 if (a)
|
|
24 c = &b.s;
|
|
25
|
|
26 b.s.w = 3;
|
|
27
|
|
28 /* Since 'c' may be pointing to NULL here, we used to flag it as
|
|
29 pointing anywhere, which was forcing the aliaser to mark as
|
|
30 call-clobbered every other variable pointed-to by 'c' ('b' in
|
|
31 this case). This, in turn, caused the insertion of V_MAY_DEFs
|
|
32 for 'b' at this call-site, which prevented constant propagation
|
|
33 from 'b.s.w = 3' to 'if (b.s.w != 3)'. */
|
|
34 bar (*c, a);
|
|
35
|
|
36 if (b.s.w != 3)
|
|
37 link_error ();
|
|
38 }
|
|
39
|
|
40 int main ()
|
|
41 {
|
|
42 struct T b;
|
|
43 foo (3, b);
|
|
44 return 0;
|
|
45 }
|
|
46
|
|
47 int X;
|
|
48
|
|
49 int bar (struct S x, int i)
|
|
50 {
|
|
51 X = 3;
|
|
52 }
|