1/* Check that execution counts and branch probabilities for various C
2   constructs are reported correctly by gcov. */
3
4/* { dg-options "-fprofile-arcs -ftest-coverage" } */
5/* { dg-do run { target native } } */
6
7extern "C" 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++)		/* branch(25) */
57					/* branch(end) */
58    for_temp++;				/* count(9) */
59  return for_temp;			/* count(3) */
60}
61
62int
63test_for2 (int m, int n, int o)
64{
65  int i, j, k;
66  for_temp = 1;				/* count(6) */
67  for (i = 0; i < n; i++)		/* branch(30) */
68					/* branch(end) */
69    for (j = 0; j < m; j++)		/* branch(32) */
70					/* branch(end) */
71      for (k = 0; k < o; k++)		/* branch(27) */
72					/* branch(end) */
73	for_temp++;			/* count(81) */
74  return for_temp;			/* count(6) */
75}
76
77int
78call_for ()
79{
80  for_val1 += test_for1 (0);
81  for_val1 += test_for1 (2);
82  for_val1 += test_for1 (7);
83
84  for_val2 += test_for2 (0, 0, 0);
85  for_val2 += test_for2 (1, 0, 0);
86  for_val2 += test_for2 (1, 3, 0);
87  for_val2 += test_for2 (1, 3, 1);
88  for_val2 += test_for2 (3, 1, 5);
89  for_val2 += test_for2 (3, 7, 3);
90}
91
92/* Check the use of goto. */
93
94int goto_val;
95
96int
97test_goto1 (int f)
98{
99					/* branch(50) */
100  if (f)				/* count(2) */
101					/* branch(end) */
102    goto lab1;				/* count(1) */
103  return 1;				/* count(1) */
104lab1:
105  return 2;				/* count(1) */
106}
107
108int
109test_goto2 (int f)
110{
111  int i;
112					/* branch(7) */
113  for (i = 0; i < 10; i++)		/* count(15) */
114					/* branch(end) */
115    if (i == f) goto lab2;		/* count(14) */
116  return 4;				/* count(1) */
117lab2:
118  return 8;				/* count(1) */
119}
120
121void
122call_goto ()
123{
124  goto_val += test_goto1 (0);
125  goto_val += test_goto1 (1);
126  goto_val += test_goto2 (3);
127  goto_val += test_goto2 (30);
128}
129
130/* Check nested if-then-else statements. */
131
132int ifelse_val1;
133int ifelse_val2;
134int ifelse_val3;
135
136int
137test_ifelse1 (int i, int j)
138{
139  int result = 0;
140					/* branch(40) */
141  if (i)				/* count(5) */
142					/* branch(0) */
143    if (j)				/* count(3) */
144					/* branch(end) */
145      result = do_something (4);	/* count(3) */
146    else
147      result = do_something (1024);
148  else
149					/* branch(50) */
150    if (j)				/* count(2) */
151					/* branch(end) */
152      result = do_something (1);	/* count(1) */
153    else
154      result = do_something (2);	/* count(1) */
155					/* branch(80) */
156  if (i > j)				/* count(5) */
157					/* branch(end) */
158    result = do_something (result*2);	/* count(1) */
159					/* branch(80) */
160  if (i > 10)				/* count(5) */
161					/* branch(100) */
162    if (j > 10)				/* count(1) */
163					/* branch(end) */
164      result = do_something (result*4);	/* count(1) */
165  return result;			/* count(5) */
166}
167
168int
169test_ifelse2 (int i)
170{
171  int result = 0;
172					/* branch(83) */
173  if (!i)				/* count(6) */
174					/* branch(end) */
175    result = do_something (1);		/* count(1) */
176					/* branch(100) */
177  if (i == 1)				/* count(6) */
178					/* branch(end) */
179    result = do_something (1024);
180					/* branch(50) */
181  if (i == 2)				/* count(6) */
182					/* branch(end) */
183    result = do_something (2);		/* count(3) */
184					/* branch(67) */
185  if (i == 3)				/* count(6) */
186					/* branch(end) */
187    return do_something (8);		/* count(2) */
188					/* branch(100) */
189  if (i == 4)				/* count(4) */
190					/* branch(end) */
191    return do_something (2048);
192  return result;			/* count(4) */
193}
194
195int
196test_ifelse3 (int i, int j)
197{
198  int result = 1;
199					/* branch(27 50 75) */
200  if (i > 10 && j > i && j < 20)	/* count(11) */
201					/* branch(end) */
202    result = do_something (16);		/* count(1) */
203					/* branch(55) */
204  if (i > 20)				/* count(11) */
205					/* branch(60) */
206    if (j > i)				/* count(5) */
207					/* branch(50) */
208      if (j < 30)			/* count(2) */
209					/* branch(end) */
210	result = do_something (32);	/* count(1) */
211					/* branch(9 10 89) */
212  if (i == 3 || j == 47 || i == j)	/* count(11) */
213					/* branch(end) */
214    result = do_something (64);		/* count(3) */
215  return result;			/* count(11) */
216}
217
218void
219call_ifelse ()
220{
221  ifelse_val1 += test_ifelse1 (0, 2);
222  ifelse_val1 += test_ifelse1 (0, 0);
223  ifelse_val1 += test_ifelse1 (1, 2);
224  ifelse_val1 += test_ifelse1 (10, 2);
225  ifelse_val1 += test_ifelse1 (11, 11);
226
227  ifelse_val2 += test_ifelse2 (0);
228  ifelse_val2 += test_ifelse2 (2);
229  ifelse_val2 += test_ifelse2 (2);
230  ifelse_val2 += test_ifelse2 (2);
231  ifelse_val2 += test_ifelse2 (3);
232  ifelse_val2 += test_ifelse2 (3);
233
234  ifelse_val3 += test_ifelse3 (11, 19);
235  ifelse_val3 += test_ifelse3 (25, 27);
236  ifelse_val3 += test_ifelse3 (11, 22);
237  ifelse_val3 += test_ifelse3 (11, 10);
238  ifelse_val3 += test_ifelse3 (21, 32);
239  ifelse_val3 += test_ifelse3 (21, 20);
240  ifelse_val3 += test_ifelse3 (1, 2);
241  ifelse_val3 += test_ifelse3 (32, 31);
242  ifelse_val3 += test_ifelse3 (3, 0);
243  ifelse_val3 += test_ifelse3 (0, 47);
244  ifelse_val3 += test_ifelse3 (65, 65);
245}
246
247/* Check switch statements. */
248
249int switch_val, switch_m;
250
251int
252test_switch (int i, int j)
253{
254  int result = 0;			/* count(5) */
255
256					/* branch(20 0 60 20) */
257  switch (i)				/* count(5) */
258					/* branch(end) */
259    {
260      case 1:
261        result = do_something (2);	/* count(1) */
262        break;
263      case 2:
264        result = do_something (1024);
265        break;
266      case 3:
267      case 4:
268					/* branch(67) */
269        if (j == 2)			/* count(3) */
270					/* branch(end) */
271          return do_something (4);	/* count(1) */
272        result = do_something (8);	/* count(2) */
273        break;
274      default:
275	result = do_something (32);	/* count(1) */
276	switch_m++;			/* count(1) */
277        break;
278    }
279  return result;			/* count(4) */
280}
281
282void
283call_switch ()
284{
285  switch_val += test_switch (1, 0);
286  switch_val += test_switch (3, 0);
287  switch_val += test_switch (3, 2);
288  switch_val += test_switch (4, 0);
289  switch_val += test_switch (16, 0);
290  switch_val += switch_m;
291}
292
293int
294main()
295{
296  call_for ();
297  call_goto ();
298  call_ifelse ();
299  call_switch ();
300  call_unref ();
301  if ((for_val1 != 12)
302      || (for_val2 != 87)
303      || (goto_val != 15)
304      || (ifelse_val1 != 31)
305      || (ifelse_val2 != 23)
306      || (ifelse_val3 != 246)
307      || (switch_val != 55)
308      || (unref_val != 4))
309    abort ();
310  return 0;
311}
312
313/* { dg-final { run-gcov branches { -b gcov-1.C } } } */
314