diff options
Diffstat (limited to 'tests/alloc.c')
-rw-r--r-- | tests/alloc.c | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/tests/alloc.c b/tests/alloc.c index f91b428..4aae515 100644 --- a/tests/alloc.c +++ b/tests/alloc.c @@ -10,27 +10,45 @@ #include <stdlib.h> #include <stdint.h> +struct flexible { + alignas(64) int foo[8]; + int bar[]; +}; + +/** Check varena_realloc() poisoning for a size combination. */ +static struct flexible *check_varena_realloc(struct varena *varena, struct flexible *flexy, size_t old_count, size_t new_count) { + flexy = varena_realloc(varena, flexy, old_count, new_count); + bfs_everify(flexy); + + for (size_t i = 0; i < new_count; ++i) { + if (i < old_count) { + bfs_check(flexy->bar[i] == (int)i); + } else { + flexy->bar[i] = i; + } + } + + return flexy; +} + void check_alloc(void) { + // Check aligned allocation + void *ptr; + bfs_everify((ptr = zalloc(64, 129))); + bfs_check((uintptr_t)ptr % 64 == 0); + bfs_echeck((ptr = xrealloc(ptr, 64, 129, 65))); + bfs_check((uintptr_t)ptr % 64 == 0); + free(ptr); + // Check sizeof_flex() - struct flexible { - alignas(64) int foo[8]; - int bar[]; - }; bfs_check(sizeof_flex(struct flexible, bar, 0) >= sizeof(struct flexible)); bfs_check(sizeof_flex(struct flexible, bar, 16) % alignof(struct flexible) == 0); - size_t too_many = SIZE_MAX / sizeof(int) + 1; + // volatile to suppress -Walloc-size-larger-than + volatile size_t too_many = SIZE_MAX / sizeof(int) + 1; bfs_check(sizeof_flex(struct flexible, bar, too_many) == align_floor(alignof(struct flexible), SIZE_MAX)); - // Corner case: sizeof(type) > align_ceil(alignof(type), offsetof(type, member)) - // Doesn't happen in typical ABIs - bfs_check(flex_size(8, 16, 4, 4, 1) == 16); - // Make sure we detect allocation size overflows -#if __GNUC__ && !__clang__ -# pragma GCC diagnostic ignored "-Walloc-size-larger-than=" -#endif - bfs_check(ALLOC_ARRAY(int, too_many) == NULL && errno == EOVERFLOW); bfs_check(ZALLOC_ARRAY(int, too_many) == NULL && errno == EOVERFLOW); bfs_check(ALLOC_FLEX(struct flexible, bar, too_many) == NULL && errno == EOVERFLOW); @@ -41,10 +59,20 @@ void check_alloc(void) { VARENA_INIT(&varena, struct flexible, bar); for (size_t i = 0; i < 256; ++i) { - bfs_verify(varena_alloc(&varena, i)); + bfs_everify(varena_alloc(&varena, i)); struct arena *arena = &varena.arenas[varena.narenas - 1]; bfs_check(arena->size >= sizeof_flex(struct flexible, bar, i)); } + // Check varena_realloc() (un)poisoning + struct flexible *flexy = varena_alloc(&varena, 160); + bfs_everify(flexy); + + flexy = check_varena_realloc(&varena, flexy, 0, 160); + flexy = check_varena_realloc(&varena, flexy, 160, 192); + flexy = check_varena_realloc(&varena, flexy, 192, 160); + flexy = check_varena_realloc(&varena, flexy, 160, 320); + flexy = check_varena_realloc(&varena, flexy, 320, 96); + varena_destroy(&varena); } |