1/* Check that various C constructs are handled correctly by profile-directed
2   block ordering.
3
4   This test is the same as gcov-4.c.  The "count" comments are left in to
5   make comparisons easier; they are ignored for this test. */
6
7extern void abort (void);
8
9int do_something (int i)
10{
11  return i;
12}
13
14/* Check static inline functions. */
15
16int unref_val;
17
18static inline int
19unreferenced (int i, int j)
20{
21  return i - j;
22}
23
24static inline int
25uncalled (int i, int j)
26{
27  return i * j;
28}
29
30static inline int
31called (int i, int j)
32{
33    return i + j;			/* count(1) */
34}
35
36void
37call_unref ()
38{
39  if (unref_val)			/* count(1) */
40    unref_val = uncalled (1, 2);
41  unref_val = called (unref_val, 4);	/* count(1) */
42}
43
44
45/* Check for loops. */
46
47int for_val1;
48int for_val2;
49int for_temp;
50
51int
52test_for1 (int n)
53{
54  int i;
55  for_temp = 1;				/* count(3) */
56  for (i = 0; i < n; i++)
57    for_temp++;				/* count(9) */
58  return for_temp;			/* count(3) */
59}
60
61int
62test_for2 (int m, int n, int o)
63{
64  int i, j, k;
65  for_temp = 1;				/* count(6) */
66  for (i = 0; i < n; i++)
67    for (j = 0; j < m; j++)
68      for (k = 0; k < o; k++)
69	for_temp++;			/* count(81) */
70  return for_temp;			/* count(6) */
71}
72
73void
74call_for ()
75{
76  for_val1 += test_for1 (0);
77  for_val1 += test_for1 (2);
78  for_val1 += test_for1 (7);
79
80  for_val2 += test_for2 (0, 0, 0);
81  for_val2 += test_for2 (1, 0, 0);
82  for_val2 += test_for2 (1, 3, 0);
83  for_val2 += test_for2 (1, 3, 1);
84  for_val2 += test_for2 (3, 1, 5);
85  for_val2 += test_for2 (3, 7, 3);
86}
87
88/* Check the use of goto. */
89
90int goto_val;
91
92int
93test_goto1 (int f)
94{
95  if (f)				/* count(2) */
96    goto lab1;				/* count(1) */
97  return 1;				/* count(1) */
98lab1:
99  return 2;				/* count(1) */
100}
101
102int
103test_goto2 (int f)
104{
105  int i;
106  for (i = 0; i < 10; i++)		/* count(15) */
107    if (i == f) goto lab2;		/* count(14) */
108  return 4;				/* count(1) */
109lab2:
110  return 8;				/* count(1) */
111}
112
113void
114call_goto ()
115{
116  goto_val += test_goto1 (0);
117  goto_val += test_goto1 (1);
118  goto_val += test_goto2 (3);
119  goto_val += test_goto2 (30);
120}
121
122/* Check nested if-then-else statements. */
123
124int ifelse_val1;
125int ifelse_val2;
126int ifelse_val3;
127
128int
129test_ifelse1 (int i, int j)
130{
131  int result = 0;
132  if (i)				/* count(5) */
133    if (j)				/* count(3) */
134      result = do_something (4);	/* count(3) */
135    else
136      result = do_something (1024);
137  else
138    if (j)				/* count(2) */
139      result = do_something (1);	/* count(1) */
140    else
141      result = do_something (2);	/* count(1) */
142  if (i > j)				/* count(5) */
143    result = do_something (result*2);	/* count(1) */
144  if (i > 10)				/* count(5) */
145    if (j > 10)				/* count(1) */
146      result = do_something (result*4);	/* count(1) */
147  return result;			/* count(5) */
148}
149
150int
151test_ifelse2 (int i)
152{
153  int result = 0;
154  if (!i)				/* count(6) */
155    result = do_something (1);		/* count(1) */
156  if (i == 1)				/* count(6) */
157    result = do_something (1024);
158  if (i == 2)				/* count(6) */
159    result = do_something (2);		/* count(3) */
160  if (i == 3)				/* count(6) */
161    return do_something (8);		/* count(2) */
162  if (i == 4)				/* count(4) */
163    return do_something (2048);
164  return result;			/* count(4) */
165}
166
167int
168test_ifelse3 (int i, int j)
169{
170  int result = 1;
171  if (i > 10 && j > i && j < 20)	/* count(11) */
172    result = do_something (16);		/* count(1) */
173  if (i > 20)				/* count(11) */
174    if (j > i)				/* count(5) */
175      if (j < 30)			/* count(2) */
176	result = do_something (32);	/* count(1) */
177  if (i == 3 || j == 47 || i == j)	/* count(11) */
178    result = do_something (64);		/* count(3) */
179  return result;			/* count(11) */
180}
181
182void
183call_ifelse ()
184{
185  ifelse_val1 += test_ifelse1 (0, 2);
186  ifelse_val1 += test_ifelse1 (0, 0);
187  ifelse_val1 += test_ifelse1 (1, 2);
188  ifelse_val1 += test_ifelse1 (10, 2);
189  ifelse_val1 += test_ifelse1 (11, 11);
190
191  ifelse_val2 += test_ifelse2 (0);
192  ifelse_val2 += test_ifelse2 (2);
193  ifelse_val2 += test_ifelse2 (2);
194  ifelse_val2 += test_ifelse2 (2);
195  ifelse_val2 += test_ifelse2 (3);
196  ifelse_val2 += test_ifelse2 (3);
197
198  ifelse_val3 += test_ifelse3 (11, 19);
199  ifelse_val3 += test_ifelse3 (25, 27);
200  ifelse_val3 += test_ifelse3 (11, 22);
201  ifelse_val3 += test_ifelse3 (11, 10);
202  ifelse_val3 += test_ifelse3 (21, 32);
203  ifelse_val3 += test_ifelse3 (21, 20);
204  ifelse_val3 += test_ifelse3 (1, 2);
205  ifelse_val3 += test_ifelse3 (32, 31);
206  ifelse_val3 += test_ifelse3 (3, 0);
207  ifelse_val3 += test_ifelse3 (0, 47);
208  ifelse_val3 += test_ifelse3 (65, 65);
209}
210
211/* Check switch statements. */
212
213int switch_val, switch_m;
214
215int
216test_switch (int i, int j)
217{
218  int result = 0;			/* count(5) */
219
220  switch (i)				/* count(5) */
221    {
222      case 1:
223        result = do_something (2);	/* count(1) */
224        break;
225      case 2:
226        result = do_something (1024);
227        break;
228      case 3:
229      case 4:
230        if (j == 2)			/* count(3) */
231          return do_something (4);	/* count(1) */
232        result = do_something (8);	/* count(2) */
233        break;
234      default:
235	result = do_something (32);	/* count(1) */
236	switch_m++;			/* count(1) */
237        break;
238    }
239  return result;			/* count(4) */
240}
241
242void
243call_switch ()
244{
245  switch_val += test_switch (1, 0);
246  switch_val += test_switch (3, 0);
247  switch_val += test_switch (3, 2);
248  switch_val += test_switch (4, 0);
249  switch_val += test_switch (16, 0);
250  switch_val += switch_m;
251}
252
253int
254main()
255{
256  call_for ();
257  call_goto ();
258  call_ifelse ();
259  call_switch ();
260  call_unref ();
261  if ((for_val1 != 12)
262      || (for_val2 != 87)
263      || (goto_val != 15)
264      || (ifelse_val1 != 31)
265      || (ifelse_val2 != 23)
266      || (ifelse_val3 != 246)
267      || (switch_val != 55)
268      || (unref_val != 4))
269    abort ();
270  return 0;
271}
272