| // RUN: %clang_analyze_cc1 -verify %s -analyzer-checker=core | |
| // This file tests ExprEngine::processSwitch. | |
| int switch_simple(int x) { | |
| // Validate that switch behaves as expected in a very simple situation. | |
| switch (x) { | |
| case 1: | |
| return 13 / x; | |
| case 0: | |
| return 14 / x; // expected-warning {{Division by zero}} | |
| case 2: | |
| return 15 / x; | |
| default: | |
| return 67 / (x - x); // expected-warning {{Division by zero}} | |
| } | |
| } | |
| int switch_default(int x) { | |
| // Validate that the default case is evaluated after excluding the other | |
| // cases -- even if it appears first. | |
| if (x > 2 || x < 0) | |
| return 0; | |
| switch (x) { | |
| default: | |
| return 16 / x; // expected-warning {{Division by zero}} | |
| case 1: | |
| return 13 / x; | |
| case 2: | |
| return 15 / x; | |
| } | |
| } | |
| int switch_unreachable_default(int x) { | |
| // Validate that the default case is not evaluated if it is infeasible. | |
| int zero = 0; | |
| if (x > 2 || x < 0) | |
| return 0; | |
| switch (x) { | |
| default: | |
| return 16 / zero; // no-warning | |
| case 0: | |
| return 456; | |
| case 1: | |
| return 13 / x; | |
| case 2: | |
| return 15 / x; | |
| } | |
| } | |
| enum Color {Red, Green, Blue}; | |
| int switch_all_enum_cases_covered(enum Color x) { | |
| // Validate that the default case is not evaluated if the switch is over an | |
| // enum value and all enumerators appear as 'case's. | |
| int zero = 0; | |
| switch (x) { | |
| default: | |
| return 16 / zero; // no-warning | |
| case Red: | |
| case Green: | |
| return 2; | |
| case Blue: | |
| return 3; | |
| } | |
| } | |
| int switch_all_feasible_enum_cases_covered(enum Color x) { | |
| // Highlight a shortcoming of enum/switch handling: here the 'case's cover | |
| // all the enumerators that could appear in the symbolic value 'x', but the | |
| // default is still executed. | |
| // FIXME: The default branch shouldn't be executed here. | |
| int zero = 0; | |
| if (x == Red) | |
| return 1; | |
| switch (x) { | |
| default: | |
| return 16 / zero; // expected-warning {{Division by zero}} | |
| case Green: | |
| return 2; | |
| case Blue: | |
| return 3; | |
| } | |
| } | |
| int switch_no_compound_stmt(int x) { | |
| // Validate that the engine can follow the switch statement even if there is | |
| // no compound statement around the cases. (Yes, this is valid, although | |
| // not very practical.) | |
| switch (x) case 1: case 0: return 16 / x; // expected-warning {{Division by zero}} | |
| return 0; | |
| } | |
| void switch_empty(int x) { | |
| // Validate that the engine does not crash on these empty switches. | |
| // (These are pretty useless, but the analyzer should still handle them.) | |
| switch (x) {} | |
| switch (x) | |
| ; | |
| } | |
| int switch_with_case_range(int x) { | |
| // Validate that the GNU case range extension is properly handled. | |
| switch (x) { | |
| case 5: | |
| return 55 / x; | |
| case 2 ... 4: | |
| return 3; | |
| case 0 ... 1: | |
| return 44 / x; // no-warning: there is no state split between 0 and 1 | |
| default: | |
| if (x) | |
| return 8; | |
| return 45 / x; // no-warning: x cannot be 0 on the default branch | |
| } | |
| } |