#include "tests.h" #include "crucible/error.h" #include "crucible/limits.h" #include #include using namespace crucible; // Like catch_all but don't bother printing anything static int silent_catch_all(const function &f) { try { f(); return 0; } catch (const exception &) { return 1; } catch (...) { return -1; } } #define SHOULD_FAIL(expr) assert(1 == silent_catch_all([&]() { (expr); })) #define SHOULD_PASS(expr, result) assert(0 == silent_catch_all([&]() { assert((result) == (expr)); })) static void test_cast_signed_negative_to_unsigned() { off_t tv = -1; SHOULD_FAIL(ranged_cast(tv)); SHOULD_FAIL(ranged_cast(tv)); SHOULD_FAIL(ranged_cast(tv)); SHOULD_FAIL(ranged_cast(tv)); SHOULD_FAIL(ranged_cast(tv)); SHOULD_FAIL(ranged_cast(tv)); SHOULD_FAIL(ranged_cast(tv)); SHOULD_FAIL(ranged_cast(tv)); SHOULD_FAIL(ranged_cast(tv)); } static void test_cast_1_to_things() { auto tv = 1; SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); SHOULD_PASS(ranged_cast(tv), 1); } static void test_cast_128_to_things() { auto tv = 128; SHOULD_PASS(ranged_cast(tv), 128); SHOULD_PASS(ranged_cast(tv), 128); SHOULD_PASS(ranged_cast(tv), 128); SHOULD_PASS(ranged_cast(tv), 128); SHOULD_PASS(ranged_cast(tv), 128); SHOULD_PASS(ranged_cast(tv), 128); SHOULD_PASS(ranged_cast(tv), 128); SHOULD_PASS(ranged_cast(tv), 128); SHOULD_FAIL(ranged_cast(tv)); SHOULD_PASS(ranged_cast(tv), 128); SHOULD_PASS(ranged_cast(tv), 128); SHOULD_PASS(ranged_cast(tv), 128); SHOULD_PASS(ranged_cast(tv), 128); SHOULD_PASS(ranged_cast(tv), 128); SHOULD_PASS(ranged_cast(tv), 128); SHOULD_PASS(ranged_cast(tv), 128); SHOULD_PASS(ranged_cast(tv), 128); SHOULD_PASS(ranged_cast(tv), 128); SHOULD_FAIL(ranged_cast(tv)); } static void test_cast_256_to_things() { auto tv = 256; SHOULD_PASS(ranged_cast(tv), 256); SHOULD_PASS(ranged_cast(tv), 256); SHOULD_PASS(ranged_cast(tv), 256); SHOULD_PASS(ranged_cast(tv), 256); SHOULD_FAIL(ranged_cast(tv)); SHOULD_PASS(ranged_cast(tv), 256); SHOULD_PASS(ranged_cast(tv), 256); SHOULD_PASS(ranged_cast(tv), 256); SHOULD_FAIL(ranged_cast(tv)); SHOULD_PASS(ranged_cast(tv), 256); SHOULD_PASS(ranged_cast(tv), 256); SHOULD_PASS(ranged_cast(tv), 256); SHOULD_PASS(ranged_cast(tv), 256); SHOULD_FAIL(ranged_cast(tv)); SHOULD_PASS(ranged_cast(tv), 256); SHOULD_PASS(ranged_cast(tv), 256); SHOULD_PASS(ranged_cast(tv), 256); SHOULD_PASS(ranged_cast(tv), 256); SHOULD_FAIL(ranged_cast(tv)); } static void test_cast_0x80000000_to_things() { auto sv = 0x80000000LL; auto uv = 0x80000000ULL; SHOULD_PASS(ranged_cast(sv), sv); SHOULD_PASS(ranged_cast(uv), uv); SHOULD_PASS(ranged_cast(uv), uv); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(uv)); SHOULD_PASS(ranged_cast(sv), sv); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_PASS(ranged_cast(uv), uv); SHOULD_PASS(ranged_cast(uv), uv); SHOULD_PASS(ranged_cast(uv), uv); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(uv)); SHOULD_PASS(ranged_cast(sv), sv); if (sizeof(long) == 4) { SHOULD_FAIL(ranged_cast(sv)); } else if (sizeof(long) == 8) { SHOULD_PASS(ranged_cast(sv), sv); } else { assert(!"unhandled case, please add code for long here"); } SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); if (sizeof(int) == 4) { SHOULD_FAIL(ranged_cast(sv)); } else if (sizeof(int) == 8) { SHOULD_PASS(ranged_cast(sv), sv); } else { assert(!"unhandled case, please add code for int here"); } } static void test_cast_0xffffffff_to_things() { auto sv = 0xffffffffLL; auto uv = 0xffffffffULL; SHOULD_PASS(ranged_cast(sv), sv); SHOULD_PASS(ranged_cast(uv), uv); SHOULD_PASS(ranged_cast(uv), uv); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(uv)); SHOULD_PASS(ranged_cast(sv), sv); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_PASS(ranged_cast(uv), uv); SHOULD_PASS(ranged_cast(uv), uv); SHOULD_PASS(ranged_cast(uv), uv); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(uv)); SHOULD_PASS(ranged_cast(sv), sv); if (sizeof(long) == 4) { SHOULD_FAIL(ranged_cast(sv)); } else if (sizeof(long) == 8) { SHOULD_PASS(ranged_cast(sv), sv); } else { assert(!"unhandled case, please add code for long here"); } SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); if (sizeof(int) == 4) { SHOULD_FAIL(ranged_cast(sv)); } else if (sizeof(int) == 8) { SHOULD_PASS(ranged_cast(sv), sv); } else { assert(!"unhandled case, please add code for int here"); } } static void test_cast_0xfffffffff_to_things() { auto sv = 0xfffffffffLL; auto uv = 0xfffffffffULL; SHOULD_PASS(ranged_cast(sv), sv); SHOULD_PASS(ranged_cast(uv), uv); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(uv)); SHOULD_PASS(ranged_cast(sv), sv); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_PASS(ranged_cast(uv), uv); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(uv)); SHOULD_PASS(ranged_cast(sv), sv); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); if (sizeof(int) == 4) { SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(uv)); } else if (sizeof(int) == 8) { SHOULD_PASS(ranged_cast(sv), sv); SHOULD_PASS(ranged_cast(uv), uv); } else { assert(!"unhandled case, please add code here"); } if (sizeof(long) == 4) { SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(uv)); } else if (sizeof(long) == 8) { SHOULD_PASS(ranged_cast(sv), sv); SHOULD_PASS(ranged_cast(uv), uv); } else { assert(!"unhandled case, please add code here"); } } static void test_cast_0x8000000000000000_to_things() { auto sv = 0x8000000000000000LL; auto uv = 0x8000000000000000ULL; SHOULD_FAIL(ranged_cast(sv)); SHOULD_PASS(ranged_cast(uv), uv); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_PASS(ranged_cast(uv), uv); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); if (sizeof(int) == 4) { SHOULD_FAIL(ranged_cast(uv)); } else if (sizeof(int) == 8) { SHOULD_PASS(ranged_cast(uv), uv); } else { assert(!"unhandled case, please add code here"); } if (sizeof(long) == 4) { SHOULD_FAIL(ranged_cast(uv)); } else if (sizeof(long) == 8) { SHOULD_PASS(ranged_cast(uv), uv); } else { assert(!"unhandled case, please add code here"); } } static void test_cast_0xffffffffffffffff_to_things() { auto sv = 0xffffffffffffffffLL; auto uv = 0xffffffffffffffffULL; SHOULD_FAIL(ranged_cast(sv)); SHOULD_PASS(ranged_cast(uv), uv); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_PASS(ranged_cast(uv), uv); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(uv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); SHOULD_FAIL(ranged_cast(sv)); if (sizeof(int) == 4) { SHOULD_FAIL(ranged_cast(uv)); } else if (sizeof(int) == 8) { SHOULD_PASS(ranged_cast(uv), uv); } else { assert(!"unhandled case, please add code here"); } if (sizeof(long) == 4) { SHOULD_FAIL(ranged_cast(uv)); } else if (sizeof(long) == 8) { SHOULD_PASS(ranged_cast(uv), uv); } else { assert(!"unhandled case, please add code here"); } } // OK enough with the small values. We want to know if 32-bit machines break. int main(int, char**) { RUN_A_TEST(test_cast_signed_negative_to_unsigned()); RUN_A_TEST(test_cast_1_to_things()); RUN_A_TEST(test_cast_128_to_things()); RUN_A_TEST(test_cast_256_to_things()); RUN_A_TEST(test_cast_0x80000000_to_things()); RUN_A_TEST(test_cast_0xffffffff_to_things()); RUN_A_TEST(test_cast_0xfffffffff_to_things()); RUN_A_TEST(test_cast_0x8000000000000000_to_things()); RUN_A_TEST(test_cast_0xffffffffffffffff_to_things()); exit(EXIT_SUCCESS); }