github.com/Konstantin8105/c4go@v0.0.0-20240505174241-768bb1c65a51/tests/switch.c (about) 1 // This file tests the various forms of switch statement. 2 // 3 // We must be extra sensitive to the fact that switch fallthrough is handled 4 // differently in C and Go. Break statements are removed and fallthrough 5 // statements are added when nessesary. 6 // 7 // It is worth mentioning that a SwitchStmt has a CompoundStmt item that 8 // contains all of the cases. However, if the individual case are not enclosed 9 // in a scope each of the case statements and their childen are part of the same 10 // CompoundStmt. For example, the first switch statement below contains a 11 // CompoundStmt with 12 children. 12 13 #include "tests.h" 14 #include <stdio.h> 15 16 void match_a_single_case() 17 { 18 switch (1) { 19 case 0: 20 fail("code should not reach here"); 21 break; 22 case 1: 23 pass(__func__); 24 break; 25 case 2: 26 fail("code should not reach here"); 27 break; 28 default: 29 fail("code should not reach here"); 30 break; 31 } 32 } 33 34 void fallthrough_to_next_case() 35 { 36 switch (1) { 37 case 0: 38 fail("code should not reach here"); 39 break; 40 case 1: 41 pass(__func__); 42 case 2: 43 pass(__func__); 44 break; 45 default: 46 fail("code should not reach here"); 47 break; 48 } 49 } 50 51 void match_no_cases() 52 { 53 switch (1) { 54 case 5: 55 fail("code should not reach here"); 56 break; 57 case 2: 58 fail("code should not reach here"); 59 break; 60 } 61 } 62 63 void match_default() 64 { 65 switch (1) { 66 case 5: 67 fail("code should not reach here"); 68 break; 69 case 2: 70 fail("code should not reach here"); 71 break; 72 default: 73 pass(__func__); 74 break; 75 } 76 } 77 78 void fallthrough_several_cases_including_default() 79 { 80 switch (1) { 81 case 0: 82 fail("code should not reach here"); 83 case 1: 84 pass(__func__); 85 case 2: 86 pass(__func__); 87 default: 88 pass(__func__); 89 } 90 } 91 92 void scoped_match_a_single_case() 93 { 94 switch (1) { 95 case 0: { 96 fail("code should not reach here"); 97 break; 98 } 99 case 1: { 100 pass(__func__); 101 break; 102 } 103 case 2: { 104 fail("code should not reach here"); 105 break; 106 } 107 default: { 108 fail("code should not reach here"); 109 break; 110 } 111 } 112 } 113 114 void scoped_fallthrough_to_next_case() 115 { 116 switch (1) { 117 case 0: { 118 fail("code should not reach here"); 119 break; 120 } 121 case 1: { 122 pass(__func__); 123 } 124 case 2: { 125 pass(__func__); 126 break; 127 } 128 default: { 129 fail("code should not reach here"); 130 break; 131 } 132 } 133 } 134 135 void scoped_match_no_cases() 136 { 137 switch (1) { 138 case 5: { 139 fail("code should not reach here"); 140 break; 141 } 142 case 2: { 143 fail("code should not reach here"); 144 break; 145 } 146 } 147 } 148 149 void scoped_match_default() 150 { 151 switch (1) { 152 case 5: { 153 fail("code should not reach here"); 154 break; 155 } 156 case 2: { 157 fail("code should not reach here"); 158 break; 159 } 160 default: { 161 pass(__func__); 162 break; 163 } 164 } 165 } 166 167 void scoped_fallthrough_several_cases_including_default() 168 { 169 switch (1) { 170 case 0: { 171 fail("code should not reach here"); 172 } 173 case 1: { 174 pass(__func__); 175 } 176 case 2: { 177 pass(__func__); 178 } 179 default: { 180 pass(__func__); 181 } 182 } 183 } 184 185 typedef struct I67 I67; 186 struct I67 { 187 int x, y; 188 }; 189 190 void run(I67* i, int pos) 191 { 192 switch (pos) { 193 case 0: 194 (*i).x += 1; 195 (*i).y += 1; 196 break; 197 case 1: 198 (*i).x -= 1; 199 (*i).y -= 1; 200 break; 201 } 202 } 203 204 void run_with_block(I67* i, int pos) 205 { 206 switch (pos) { 207 case 0: { 208 (*i).x += 1; 209 (*i).y += 1; 210 break; 211 } 212 case 1: { 213 (*i).x -= 1; 214 (*i).y -= 1; 215 } break; 216 case 2: 217 (*i).x *= 1; 218 (*i).y *= 1; 219 break; 220 default: 221 (*i).x *= 10; 222 (*i).y *= 10; 223 } 224 } 225 226 void switch_issue67() 227 { 228 I67 i; 229 i.x = 0; 230 i.y = 0; 231 run(&i, 0); 232 is_eq(i.x, 1); 233 is_eq(i.y, 1); 234 run(&i, 1); 235 is_eq(i.x, 0); 236 is_eq(i.y, 0); 237 run_with_block(&i, 0); 238 is_eq(i.x, 1); 239 is_eq(i.y, 1); 240 run_with_block(&i, 1); 241 is_eq(i.x, 0); 242 is_eq(i.y, 0); 243 } 244 245 void empty_switch() 246 { 247 int pos = 0; 248 switch (pos) { 249 } 250 is_eq(pos, 0); 251 } 252 253 void default_only_switch() 254 { 255 int pos = 0; 256 switch (pos) { 257 case -1: // empty case 258 case -1 - 4: // empty case 259 case (-1 - 4 - 4): // empty case 260 case (-3): // empty case 261 case -2: // empty case 262 default: 263 pos++; 264 } 265 is_eq(pos, 1); 266 } 267 268 void switch_without_input() 269 { 270 int pos = 0; 271 switch (0) { 272 default: 273 pos++; 274 } 275 is_eq(pos, 1); 276 } 277 278 void test_switch() 279 { 280 int val = 1; 281 switch (0) { 282 case -1000: 283 default: 284 // ignored 285 val += 3; 286 case -1: 287 val += 1; 288 case 2: { 289 val *= 2; 290 } 291 case 3: { 292 val *= 4; 293 } 294 case 4: 295 case 5: 296 val += 5; 297 case 6: 298 case 7: 299 val *= 6; 300 break; 301 case 8:; 302 case 9:; 303 case 10:; 304 } 305 is_eq(val, 270); 306 } 307 308 void switch_bool() 309 { 310 double x = 3.0; 311 switch (x < 0.0) { 312 case 0: 313 pass("ok"); 314 break; 315 case 1: 316 fail("switch_bool 1"); 317 break; 318 default: 319 fail("switch_bool 3"); 320 } 321 int y = 7; 322 const int t = 0; 323 switch (y) { 324 case 0 == t: 325 fail("switch_bool 4"); 326 break; 327 case 1 == t: 328 fail("switch_bool 5"); 329 break; 330 default: 331 pass("ok"); 332 break; 333 } 334 } 335 336 void switch_char() 337 { 338 char form = '1'; 339 switch (form) { 340 default: 341 case '1': 342 form = 'S'; 343 break; 344 case 0:; 345 }; 346 is_eq(form, 'S'); 347 } 348 349 int value() 350 { 351 return 42; 352 } 353 354 void switch_stat() 355 { 356 int v = 15; 357 switch (v = value()) { 358 case 15: 359 fail("wrong"); 360 break; 361 case 42: 362 is_true(v == 42); 363 break; 364 } 365 } 366 367 int case_inside_block(int a) 368 { 369 switch (a) { 370 case 1: 371 break; 372 case 2: { 373 a = 42; 374 case 3: 375 a += 45; 376 break; 377 } 378 case 4: 379 break; 380 } 381 return a; 382 } 383 384 int main() 385 { 386 plan(37); 387 388 switch_char(); 389 switch_bool(); 390 match_a_single_case(); 391 fallthrough_to_next_case(); 392 match_no_cases(); 393 match_default(); 394 fallthrough_several_cases_including_default(); 395 test_switch(); 396 397 // For each of the tests above there will be identical cases that use scopes 398 // for the case statements. 399 scoped_match_a_single_case(); 400 scoped_fallthrough_to_next_case(); 401 scoped_match_no_cases(); 402 scoped_match_default(); 403 scoped_fallthrough_several_cases_including_default(); 404 405 switch_issue67(); 406 empty_switch(); 407 default_only_switch(); 408 switch_without_input(); 409 switch_stat(); 410 411 is_eq(case_inside_block(0), 0); 412 is_eq(case_inside_block(1), 1); 413 is_eq(case_inside_block(2), 45 + 42); 414 is_eq(case_inside_block(3), 3 + 45); 415 is_eq(case_inside_block(4), 4); 416 is_eq(case_inside_block(5), 5); 417 418 diag("without parens"); 419 { 420 int x = 0; 421 switch (x) 422 case 0: 423 pass("ok"); 424 (void)(x); 425 } 426 427 done_testing(); 428 }