// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s void clang_analyzer_eval(int); void clang_analyzer_warnIfReached(); #define INT_MIN 0x80000000 #define INT_MAX 0x7fffffff // PR16833: Analyzer consumes memory until killed by kernel OOM killer // while analyzing large case ranges. void PR16833(unsigned op) { switch (op) { case 0x02 << 26 ... 0x03 << 26: // Analyzer should not hang here. return; } } void testAdjustment(int t) { switch (t + 1) { case 2: clang_analyzer_eval(t == 1); // expected-warning{{TRUE}} break; case 3 ... 10: clang_analyzer_eval(t > 1); // expected-warning{{TRUE}} clang_analyzer_eval(t + 2 <= 11); // expected-warning{{TRUE}} clang_analyzer_eval(t > 2); // expected-warning{{UNKNOWN}} clang_analyzer_eval(t + 1 == 3); // expected-warning{{UNKNOWN}} clang_analyzer_eval(t + 1 == 10); // expected-warning{{UNKNOWN}} break; default: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} } } void testUnknownVal(int value, int mask) { // Once ConstraintManager will process '&' and this test will require some changes. switch (value & mask) { case 1: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} break; case 3 ... 10: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} break; default: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} } } void testSwitchCond(int arg) { if (arg > 10) { switch (arg) { case INT_MIN ... 10: clang_analyzer_warnIfReached(); // no-warning break; case 11 ... 20: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} break; default: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} } switch (arg) { case INT_MIN ... 9: clang_analyzer_warnIfReached(); // no-warning break; case 10 ... 20: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} clang_analyzer_eval(arg > 10); // expected-warning{{TRUE}} break; default: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} } } // arg > 10 } void testDefaultUnreachable(int arg) { if (arg > 10) { switch (arg) { case INT_MIN ... 9: clang_analyzer_warnIfReached(); // no-warning break; case 10 ... INT_MAX: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} clang_analyzer_eval(arg > 10); // expected-warning{{TRUE}} break; default: clang_analyzer_warnIfReached(); // no-warning } } } void testBranchReachability(int arg) { if (arg > 10 && arg < 20) { switch (arg) { case INT_MIN ... 4: clang_analyzer_warnIfReached(); // no-warning break; case 5 ... 9: clang_analyzer_warnIfReached(); // no-warning break; case 10 ... 15: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} clang_analyzer_eval(arg > 10 && arg <= 15); // expected-warning{{TRUE}} break; default: clang_analyzer_warnIfReached(); // no-warning break; case 17 ... 25: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} clang_analyzer_eval(arg >= 17 && arg < 20); // expected-warning{{TRUE}} break; case 26 ... INT_MAX: clang_analyzer_warnIfReached(); // no-warning break; case 16: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} clang_analyzer_eval(arg == 16); // expected-warning{{TRUE}} break; } } } void testDefaultBranchRange(int arg) { switch (arg) { case INT_MIN ... 9: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} break; case 20 ... INT_MAX: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} clang_analyzer_eval(arg >= 20); // expected-warning{{TRUE}} break; default: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} clang_analyzer_eval(arg == 16); // expected-warning{{FALSE}} clang_analyzer_eval(arg > 9); // expected-warning{{TRUE}} clang_analyzer_eval(arg <= 20); // expected-warning{{TRUE}} case 16: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} } } void testAllUnreachableButDefault(int arg) { if (arg < 0) { switch (arg) { case 0 ... 9: clang_analyzer_warnIfReached(); // no-warning break; case 20 ... INT_MAX: clang_analyzer_warnIfReached(); // no-warning break; default: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} break; case 16: clang_analyzer_warnIfReached(); // no-warning } clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} } } void testAllUnreachable(int arg) { if (arg < 0) { switch (arg) { case 0 ... 9: clang_analyzer_warnIfReached(); // no-warning break; case 20 ... INT_MAX: clang_analyzer_warnIfReached(); // no-warning break; case 16: clang_analyzer_warnIfReached(); // no-warning } clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} } } void testDifferentTypes(int arg) { switch (arg) { case -1U ... 400000000LL: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} break; default: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} break; } } void testDifferentTypes2(unsigned long arg) { switch (arg) { case 1UL ... 400000000UL: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} break; default: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} break; } } void testDifferentTypes3(int arg) { switch (arg) { case 1UL ... 400000000UL: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} break; default: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} break; } } void testConstant() { switch (3) { case 1 ... 5: clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} break; default: clang_analyzer_warnIfReached(); // no-warning break; } }