#include #include #include #ifndef GC_IGNORE_WARN /* * Ignore misleading "Out of Memory!" warning (which is printed on every * `GC_MALLOC` call below) by defining this macro before include `gc.h` file. */ # define GC_IGNORE_WARN #endif #ifndef GC_MAXIMUM_HEAP_SIZE # define GC_MAXIMUM_HEAP_SIZE (100 * 1024 * 1024) # define GC_INITIAL_HEAP_SIZE (GC_MAXIMUM_HEAP_SIZE / 20) /* * Otherwise heap expansion aborts when deallocating large block. * That is OK. We test this corner case mostly to make sure that * it fails predictably. */ #endif #ifndef GC_ATTR_ALLOC_SIZE /* * Omit `alloc_size` attribute to avoid compiler warnings about exceeding * maximum object size when values close to `GC_SWORD_MAX` are passed * to `GC_MALLOC()`. */ # define GC_ATTR_ALLOC_SIZE(argnum) /*< empty */ #endif #include "gc.h" /* * Check that very large allocation requests fail. "Success" would usually * indicate that the size was somehow converted to a negative number. * Clients should not do this, but we should fail in the expected manner. */ #define CHECK_ALLOC_FAILED(r, sz_str) \ do { \ if (NULL != (r)) { \ fprintf(stderr, "Size " sz_str " allocation unexpectedly succeeded\n"); \ exit(1); \ } \ } while (0) #undef SIZE_MAX #define SIZE_MAX (~(size_t)0) #define U_SSIZE_MAX (SIZE_MAX >> 1) /*< unsigned */ int main(void) { GC_INIT(); CHECK_ALLOC_FAILED(GC_MALLOC(U_SSIZE_MAX - 4096), "SSIZE_MAX-4096"); /* Skip other checks to avoid "exceeds maximum object size" gcc warning. */ #if !(defined(_FORTIFY_SOURCE) && defined(__x86_64__) && defined(__ILP32__)) CHECK_ALLOC_FAILED(GC_MALLOC(U_SSIZE_MAX - 1024), "SSIZE_MAX-1024"); CHECK_ALLOC_FAILED(GC_MALLOC(U_SSIZE_MAX), "SSIZE_MAX"); #endif #if !defined(_FORTIFY_SOURCE) CHECK_ALLOC_FAILED(GC_MALLOC(U_SSIZE_MAX + 1), "SSIZE_MAX+1"); CHECK_ALLOC_FAILED(GC_MALLOC(U_SSIZE_MAX + 1024), "SSIZE_MAX+1024"); CHECK_ALLOC_FAILED(GC_MALLOC(SIZE_MAX - 1024), "SIZE_MAX-1024"); CHECK_ALLOC_FAILED(GC_MALLOC(SIZE_MAX - 16), "SIZE_MAX-16"); CHECK_ALLOC_FAILED(GC_MALLOC(SIZE_MAX - 8), "SIZE_MAX-8"); CHECK_ALLOC_FAILED(GC_MALLOC(SIZE_MAX - 4), "SIZE_MAX-4"); CHECK_ALLOC_FAILED(GC_MALLOC(SIZE_MAX), "SIZE_MAX"); #endif printf("SUCCEEDED\n"); return 0; }