1 /* Check that execution counts for various C constructs are reported
2    correctly by gcov. */
3 
4 /* { dg-options "-fprofile-arcs -ftest-coverage" } */
5 /* { dg-do run { target native } } */
6 
7 extern void abort (void);
8 
do_something(int i)9 int do_something (int i)
10 {
11   return i;
12 }
13 
14 /* Check static inline functions. */
15 
16 int unref_val;
17 
18 static inline int
unreferenced(int i,int j)19 unreferenced (int i, int j)
20 {
21   return i - j;
22 }
23 
24 static inline int
uncalled(int i,int j)25 uncalled (int i, int j)
26 {
27   return i * j;
28 }
29 
30 static inline int
called(int i,int j)31 called (int i, int j)
32 {
33     return i + j;			/* count(1) */
34 }
35 
36 void
call_unref()37 call_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 
47 int for_val1;
48 int for_val2;
49 int for_temp;
50 
51 int
test_for1(int n)52 test_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 
61 int
test_for2(int m,int n,int o)62 test_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 
73 void
call_for()74 call_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 
90 int goto_val;
91 
92 int
test_goto1(int f)93 test_goto1 (int f)
94 {
95   if (f)				/* count(2) */
96     goto lab1;				/* count(1) */
97   return 1;				/* count(1) */
98 lab1:
99   return 2;				/* count(1) */
100 }
101 
102 int
test_goto2(int f)103 test_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) */
109 lab2:
110   return 8;				/* count(1) */
111 }
112 
113 void
call_goto()114 call_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 
124 int ifelse_val1;
125 int ifelse_val2;
126 int ifelse_val3;
127 
128 int
test_ifelse1(int i,int j)129 test_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 
150 int
test_ifelse2(int i)151 test_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 
167 int
test_ifelse3(int i,int j)168 test_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 
182 void
call_ifelse()183 call_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 
213 int switch_val, switch_m;
214 
215 int
test_switch(int i,int j)216 test_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 
242 void
call_switch()243 call_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 
253 int
main()254 main()
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 
273 /* { dg-final { run-gcov gcov-4.c } } */
274