uniform half4 colorGreen, colorRed;

bool return_in_one_case(int x) {
    int val = 0;
    switch (x) {
        case 1:
            ++val;
            return false;
            ++val;  // unreachable
        default: ++val;
    }

    // reachable
    return val == 1;
}

bool return_in_default(int x) {
    int val = 0;
    switch (x) {
        default: return true;
    }

    // unreachable
    ++val;
    return val == 1;
}

bool return_in_every_case(int x) {
    int val = 0;
    switch (x) {
        case 1: return false;
        default: return true;
    }

    // unreachable
    ++val;
    return val == 1;
}

bool return_in_every_case_no_default(int x) {
    int val = 0;
    switch (x) {
        case 1: return false;
        case 2: return true;
    }

    // reachable
    ++val;
    return val == 1;
}

bool case_has_break_before_return(int x) {
    int val = 0;
    switch (x) {
        case 1:
            break;
            return false;  // unreachable
        case 2: return true;
        default: return true;
    }

    // reachable
    ++val;
    return val == 1;
}

bool case_has_break_after_return(int x) {
    int val = 0;
    switch (x) {
        case 1:
            return false;
            break;  // unreachable
        case 2: return true;
        default: return true;
    }

    // unreachable
    ++val;
    return val == 1;
}

bool no_return_in_default(int x) {
    int val = 0;
    switch (x) {
        case 1: return false;
        case 2: return true;
        default: break;
    }

    // reachable
    ++val;
    return val == 1;
}

bool empty_default(int x) {
    int val = 0;
    switch (x) {
        case 1: return false;
        case 2: return true;
        default:
    }

    // reachable
    ++val;
    return val == 1;
}

bool return_with_fallthrough(int x) {
    int val = 0;
    switch (x) {
        case 1:
        case 2: return true;
        default: return false;
    }

    // unreachable
    ++val;
    return val == 1;
}

bool fallthrough_ends_in_break(int x) {
    int val = 0;
    switch (x) {
        case 1:
        case 2: break;
        default: return false;
    }

    // reachable
    ++val;
    return val == 1;
}

bool fallthrough_to_default_with_break(int x) {
    int val = 0;
    switch (x) {
        case 1:
        case 2:
        default: break;
    }

    // reachable
    ++val;
    return val == 1;
}

bool fallthrough_to_default_with_return(int x) {
    int val = 0;
    switch (x) {
        case 1:
        case 2:
        default: return true;
    }

    // unreachable
    ++val;
    return val == 1;
}

bool fallthrough_with_loop_break(int x) {
    int val = 0;
    switch (x) {
        case 1: for (int i = 0; i < 5; ++i) {
            ++val;
            break;  // break only applies to loop, should fallthrough
        }
        case 2:
        default: return true;
    }

    // unreachable
    ++val;
    return val == 1;
}

bool fallthrough_with_loop_continue(int x) {
    int val = 0;
    switch (x) {
        case 1: for (int i = 0; i < 5; ++i) {
            ++val;
            continue;  // continue only applies to loop, should fallthrough
        }
        case 2:
        default: return true;
    }

    // unreachable
    ++val;
    return val == 1;
}

half4 main(float2 coords) {
    int x = int(colorGreen.g);
    return (return_in_one_case(x) &&
            return_in_default(x) &&
            return_in_every_case(x) &&
            return_in_every_case_no_default(x) &&
            case_has_break_before_return(x) &&
            case_has_break_after_return(x) &&
            no_return_in_default(x) &&
            empty_default(x) &&
            return_with_fallthrough(x) &&
            fallthrough_ends_in_break(x) &&
            fallthrough_to_default_with_break(x) &&
            fallthrough_to_default_with_return(x) &&
            fallthrough_with_loop_break(x) &&
            fallthrough_with_loop_continue(x)) ? colorGreen : colorRed;
}
