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