diff --git a/crcfactory.h b/crcfactory.h index c006039..4825e1c 100644 --- a/crcfactory.h +++ b/crcfactory.h @@ -22,6 +22,7 @@ #ifndef __CRCFACTORY_H__ #define __CRCFACTORY_H__ +#include #include #include #include @@ -101,10 +102,13 @@ CRCFACTORY_INLINE CRCFACTORY_CRC_TYPE _crcfactory_mask(int width, bool reflected if (!reflected && width <= 8) { return value & 0xff; } - // The following if statement is due to a bug under x86_64: - // "1ULL << 64" evaluates to 0 (expected), but - // "1ULL << x" when x==64 evaluates to 1 (wrong). - if ((1ULL << width) == 1) return value; + + // Avoid undefined behavior if a shift to generate the mask would exceed + // the size of the type. Just return the value unmasked, since the mask + // would cover all bits anyway. Strictly speaking we probably want a + // limits-based check here in case CRC_TYPE is signed, but signed types + // would likely break other things anyway. + if ((size_t)width >= (CHAR_BIT * sizeof(CRCFACTORY_CRC_TYPE))) return value; return value & ((1ULL << width) - 1); } diff --git a/test/crclist2test.py b/test/crclist2test.py index 80ebb57..f5de642 100755 --- a/test/crclist2test.py +++ b/test/crclist2test.py @@ -6,6 +6,7 @@ CFILE_TEMPLATE = r""" /* NOTE: This file was auto-generated by crclist2test.py */ #include +#include #define CRCFACTORY_CRC_TYPE <> #define CRCFACTORY_CRCTABLE_TYPE <> @@ -20,7 +21,7 @@ func##_t_init(crctable); \ uint64_t r = func((uint8_t *)TESTDATA, TESTDATA_LEN); \ uint64_t r_t = func##_t(crctable, (uint8_t *)TESTDATA, TESTDATA_LEN); \ - printf("%-20s: %-16lx %-6s : %-16lx %-6s\n", desc, r, (r == check) ? "(OK)" : "(FAIL)", r_t, (r_t == check) ? "(OK)" : "(FAIL)"); \ + printf("%-20s: %-16" PRIx64 " %-6s : %-16" PRIx64 " %-6s\n", desc, r, (r == check) ? "(OK)" : "(FAIL)", r_t, (r_t == check) ? "(OK)" : "(FAIL)"); \ test_count += 2; \ test_failures += (r == check) ? 0 : 1; \ test_failures += (r_t == check) ? 0 : 1; \