blob: 72c728eecacc13ea8d831b58847abe748686b2ec [file]
// 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
}
}