xref: /llvm-project/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c (revision 1c25a3bfa57209e7a29eaae58ce5e0432aafe8c3)
1 // Test visualization of general branch constructs in C.
2 
3 
4 
5 
6 
7 void simple_loops() {           // CHECK: @LINE|{{.*}}simple_loops()
8   int i;
9   for (i = 0; i < 100; ++i) {   // BRCOV: Branch ([[@LINE]]:15): [True: [[#min(C,100)]], False: 1]
10   }
11   while (i > 0)                 // BRCOV: Branch ([[@LINE]]:10): [True: [[#min(C,100)]], False: 1]
12     i--;
13   do {} while (i++ < 75);       // BRCOV: Branch ([[@LINE]]:16): [True: [[#min(C,75)]], False: 1]
14 
15 }
16 
17 void conditionals() {           // CHECK: @LINE|{{.*}}conditionals()
18   for (int i = 0; i < 100; ++i) {//BRCOV: Branch ([[@LINE]]:19): [True: [[#min(C,100)]], False: 1]
19     if (i % 2) {                // BRCOV: Branch ([[@LINE]]:9): [True: [[#min(C,50)]], False: [[#min(C,50)]]]
20       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,50)]], False: 0]
21     } else if (i % 3) {         // BRCOV: Branch ([[@LINE]]:16): [True: [[#min(C,33)]], False: [[#min(C,17)]]]
22       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,33)]], False: 0]
23     } else {
24       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,16)]], False: 1]
25     }
26                                 // BRCOV: Branch ([[@LINE+1]]:9): [True: [[#min(C,100)]], Folded]
27     if (1 && i) {}              // BRCOV: Branch ([[@LINE]]:14): [True: [[#min(C,99)]], False: 1]
28     if (0 || i) {}              // BRCOV: Branch ([[@LINE]]:9): [Folded, False: [[#min(C,100)]]]
29   }                             // BRCOV: Branch ([[@LINE-1]]:14): [True: [[#min(C,99)]], False: 1]
30 
31 }
32 
33 void early_exits() {            // CHECK: @LINE|{{.*}}early_exits()
34   int i = 0;
35 
36   if (i) {}                     // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: 1]
37 
38   while (i < 100) {             // BRCOV: Branch ([[@LINE]]:10): [True: [[#min(C,51)]], False: 0]
39     i++;
40     if (i > 50)                 // BRCOV: Branch ([[@LINE]]:9): [True: 1, False: [[#min(C,50)]]]
41       break;
42     if (i % 2)                  // BRCOV: Branch ([[@LINE]]:9): [True: [[#min(C,25)]], False: [[#min(C,25)]]]
43       continue;
44   }
45 
46   if (i) {}                     // BRCOV: Branch ([[@LINE]]:7): [True: 1, False: 0]
47 
48   do {
49     if (i > 75)                 // BRCOV: Branch ([[@LINE]]:9): [True: 1, False: [[#min(C,25)]]]
50       return;
51     else
52       i++;
53   } while (i < 100);            // BRCOV: Branch ([[@LINE]]:12): [True: [[#min(C,25)]], False: 0]
54 
55   if (i) {}                     // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: 0]
56 
57 }
58 
59 void jumps() {                  // CHECK: @LINE|{{.*}}jumps()
60   int i;
61 
62   for (i = 0; i < 2; ++i) {     // BRCOV: Branch ([[@LINE]]:15): [True: 1, False: 0]
63     goto outofloop;
64     // Never reached -> no weights
65     if (i) {}                   // BRCOV: Branch ([[@LINE]]:9): [True: 0, False: 0]
66   }
67 
68 outofloop:
69   if (i) {}                     // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: 1]
70 
71   goto loop1;
72 
73   while (i) {                   // BRCOV: Branch ([[@LINE]]:10): [True: 0, False: 1]
74   loop1:
75     if (i) {}                   // BRCOV: Branch ([[@LINE]]:9): [True: 0, False: 1]
76   }
77 
78   goto loop2;
79 first:
80 second:
81 third:
82   i++;
83   if (i < 3)                    // BRCOV: Branch ([[@LINE]]:7): [True: [[#min(C,2)]], False: 1]
84     goto loop2;
85 
86   while (i < 3) {               // BRCOV: Branch ([[@LINE]]:10): [True: 0, False: 1]
87   loop2:
88     switch (i) {
89     case 0:                     // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded]
90       goto first;
91     case 1:                     // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded]
92       goto second;
93     case 2:                     // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded]
94       goto third;
95     }
96   }
97 
98   for (i = 0; i < 10; ++i) {    // BRCOV: Branch ([[@LINE]]:15): [True: [[#min(C,10)]], False: 1]
99     goto withinloop;
100                                 // never reached -> no weights
101     if (i) {}                   // BRCOV: Branch ([[@LINE]]:9): [True: 0, False: 0]
102   withinloop:
103     if (i) {}                   // BRCOV: Branch ([[@LINE]]:9): [True: [[#min(C,9)]], False: 1]
104   }
105 
106 }
107 
108 void switches() {               // CHECK: @LINE|{{.*}}switches()
109   static int weights[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5};
110 
111   // No cases -> no weights
112   switch (weights[0]) {
113   default:                      // BRCOV: Branch ([[@LINE]]:3): [True: 1, Folded]
114     break;
115   }
116                                 // BRCOV: Branch ([[@LINE+1]]:63): [True: [[#min(C,15)]], False: 0]
117   for (int i = 0, len = sizeof(weights) / sizeof(weights[0]); i < len; ++i) {
118     switch (i[weights]) {
119     case 1:                     // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded]
120       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: 0, False: 1]
121       // fallthrough
122     case 2:                     // BRCOV: Branch ([[@LINE]]:5): [True: [[#min(C,2)]], Folded]
123       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,2)]], False: 1]
124       break;
125     case 3:                     // BRCOV: Branch ([[@LINE]]:5): [True: [[#min(C,3)]], Folded]
126       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,3)]], False: 0]
127       continue;
128     case 4:                     // BRCOV: Branch ([[@LINE]]:5): [True: [[#min(C,4)]], Folded]
129       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,4)]], False: 0]
130       switch (i) {
131       case 6 ... 9:             // BRCOV: Branch ([[@LINE]]:7): [True: [[#min(C,4)]], Folded]
132         if (i) {}               // BRCOV: Branch ([[@LINE]]:13): [True: [[#min(C,4)]], False: 0]
133         continue;
134       }
135 
136     default:                    // BRCOV: Branch ([[@LINE]]:5): [True: [[#min(C,5)]], Folded]
137       if (i == len - 1)         // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: [[#min(C,4)]]]
138         return;
139     }
140   }
141 
142   // Never reached -> no weights
143   if (weights[0]) {}            // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: 0]
144 
145 }
146 
147 void big_switch() {             // CHECK: @LINE|{{.*}}big_switch()
148   for (int i = 0; i < 32; ++i) {// BRCOV: Branch ([[@LINE]]:19): [True: [[#min(C,32)]], False: 1]
149     switch (1 << i) {
150     case (1 << 0):              // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded]
151       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: 0, False: 1]
152       // fallthrough
153     case (1 << 1):              // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded]
154       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: 1]
155       break;
156     case (1 << 2) ... (1 << 12):// BRCOV: Branch ([[@LINE]]:5): [True: [[#min(C,11)]], Folded]
157       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,11)]], False: 0]
158       break;
159       // The branch for the large case range above appears after the case body.
160 
161     case (1 << 13):             // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded]
162       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: 0]
163       break;
164     case (1 << 14) ... (1 << 28)://BRCOV: Branch ([[@LINE]]:5): [True: [[#min(C,15)]], Folded]
165       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,15)]], False: 0]
166       break;
167     // The branch for the large case range above appears after the case body.
168 
169     case (1 << 29) ... ((1 << 29) + 1):
170       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: 0]
171       break;
172     default:                    // BRCOV: Branch ([[@LINE]]:5): [True: [[#min(C,2)]], Folded]
173       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,2)]], False: 0]
174       break;
175     }
176   }
177 
178 }
179 
180 void boolean_operators() {      // CHECK: @LINE|{{.*}}boolean_operators()
181   int v;
182   for (int i = 0; i < 100; ++i) {
183     v = i % 3 || i;             // BRCOV: Branch ([[@LINE]]:9): [True: [[#min(C,66)]], False: [[#min(C,34)]]]
184                                 // BRCOV: Branch ([[@LINE-1]]:18): [True: [[#min(C,33)]], False: 1]
185     v = i % 3 && i;             // BRCOV: Branch ([[@LINE]]:9): [True: [[#min(C,66)]], False: [[#min(C,34)]]]
186                                 // BRCOV: Branch ([[@LINE-1]]:18): [True: [[#min(C,66)]], False: 0]
187     v = i % 3 || i % 2 || i;    // BRCOV: Branch ([[@LINE]]:9): [True: [[#min(C,66)]], False: [[#min(C,34)]]]
188                                 // BRCOV: Branch ([[@LINE-1]]:18): [True: [[#min(C,17)]], False: [[#min(C,17)]]]
189     v = i % 2 && i % 3 && i;    // BRCOV: Branch ([[@LINE-2]]:27): [True: [[#min(C,16)]], False: 1]
190   }                             // BRCOV: Branch ([[@LINE-1]]:9): [True: [[#min(C,50)]], False: [[#min(C,50)]]]
191                                 // BRCOV: Branch ([[@LINE-2]]:18): [True: [[#min(C,33)]], False: [[#min(C,17)]]]
192 }                               // BRCOV: Branch ([[@LINE-3]]:27): [True: [[#min(C,33)]], False: 0]
193 
194 void boolop_loops() {           // CHECK: @LINE|{{.*}}boolop_loops()
195   int i = 100;
196 
197   while (i && i > 50)           // BRCOV: Branch ([[@LINE]]:10): [True: [[#min(C,51)]], False: 0]
198     i--;                        // BRCOV: Branch ([[@LINE-1]]:15): [True: [[#min(C,50)]], False: 1]
199 
200   while ((i % 2) || (i > 0))    // BRCOV: Branch ([[@LINE]]:10): [True: [[#min(C,25)]], False: [[#min(C,26)]]]
201     i--;                        // BRCOV: Branch ([[@LINE-1]]:21): [True: [[#min(C,25)]], False: 1]
202 
203   for (i = 100; i && i > 50; --i);  // BRCOV: Branch ([[@LINE]]:17): [True: [[#min(C,51)]], False: 0]
204                                     // BRCOV: Branch ([[@LINE-1]]:22): [True: [[#min(C,50)]], False: 1]
205   for (; (i % 2) || (i > 0); --i);  // BRCOV: Branch ([[@LINE]]:10): [True: [[#min(C,25)]], False: [[#min(C,26)]]]
206                                     // BRCOV: Branch ([[@LINE-1]]:21): [True: [[#min(C,25)]], False: 1]
207 }
208 
209 void conditional_operator() {   // CHECK: @LINE|{{.*}}conditional_operator()
210   int i = 100;
211 
212   int j = i < 50 ? i : 1;       // BRCOV: Branch ([[@LINE]]:11): [True: 0, False: 1]
213 
214   int k = i ?: 0;               // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: 0]
215 
216 }
217 
218 void do_fallthrough() {         // CHECK: @LINE|{{.*}}do_fallthrough()
219   for (int i = 0; i < 10; ++i) {// BRCOV: Branch ([[@LINE]]:19): [True: [[#min(C,10)]], False: 1]
220     int j = 0;
221     do {
222       // The number of exits out of this do-loop via the break statement
223       // exceeds the counter value for the loop (which does not include the
224       // fallthrough count). Make sure that does not violate any assertions.
225       if (i < 8) break;
226       j++;
227     } while (j < 2);            // BRCOV: Branch ([[@LINE]]:14): [True: [[#min(C,2)]], False: [[#min(C,2)]]]
228   }
229 }
230 
231 static void static_func() {     // CHECK: @LINE|{{.*}}static_func()
232   for (int i = 0; i < 10; ++i) {// BRCOV: Branch ([[@LINE]]:19): [True: [[#min(C,10)]], False: 1]
233   }
234 }
235 
236 
237 
238 
239 
240 
241 
242 
243 
244 
245 int main(int argc, const char *argv[]) {
246   simple_loops();
247   conditionals();
248   early_exits();
249   jumps();
250   switches();
251   big_switch();
252   boolean_operators();
253   boolop_loops();
254   conditional_operator();
255   do_fallthrough();
256   static_func();
257   (void)0;
258   (void)0;
259   return 0;
260 }
261