1 // RUN: %clang_scudo %s -o %t 2 // RUN: %run %t pointers 2>&1 3 // RUN: %run %t contents 2>&1 4 // RUN: not %run %t memalign 2>&1 | FileCheck %s 5 6 // Tests that our reallocation function returns the same pointer when the 7 // requested size can fit into the previously allocated chunk. Also tests that 8 // a new chunk is returned if the size is greater, and that the contents of the 9 // chunk are left unchanged. 10 // As a final test, make sure that a chunk allocated by memalign cannot be 11 // reallocated. 12 13 #include <assert.h> 14 #include <malloc.h> 15 #include <string.h> 16 17 #include <vector> 18 19 int main(int argc, char **argv) 20 { 21 void *p, *old_p; 22 // Those sizes will exercise both allocators (Primary & Secondary). 23 std::vector<size_t> sizes{1, 1 << 5, 1 << 10, 1 << 15, 1 << 20}; 24 25 assert(argc == 2); 26 for (size_t size : sizes) { 27 if (!strcmp(argv[1], "pointers")) { 28 old_p = p = realloc(nullptr, size); 29 if (!p) 30 return 1; 31 size = malloc_usable_size(p); 32 // Our realloc implementation will return the same pointer if the size 33 // requested is lower than or equal to the usable size of the associated 34 // chunk. 35 p = realloc(p, size - 1); 36 if (p != old_p) 37 return 1; 38 p = realloc(p, size); 39 if (p != old_p) 40 return 1; 41 // And a new one if the size is greater. 42 p = realloc(p, size + 1); 43 if (p == old_p) 44 return 1; 45 // A size of 0 will free the chunk and return nullptr. 46 p = realloc(p, 0); 47 if (p) 48 return 1; 49 old_p = nullptr; 50 } 51 if (!strcmp(argv[1], "contents")) { 52 p = realloc(nullptr, size); 53 if (!p) 54 return 1; 55 for (int i = 0; i < size; i++) 56 reinterpret_cast<char *>(p)[i] = 'A'; 57 p = realloc(p, size + 1); 58 // The contents of the reallocated chunk must match the original one. 59 for (int i = 0; i < size; i++) 60 if (reinterpret_cast<char *>(p)[i] != 'A') 61 return 1; 62 } 63 if (!strcmp(argv[1], "memalign")) { 64 // A chunk coming from memalign cannot be reallocated. 65 p = memalign(16, size); 66 if (!p) 67 return 1; 68 p = realloc(p, size); 69 free(p); 70 } 71 } 72 return 0; 73 } 74 75 // CHECK: ERROR: invalid chunk type when reallocating address 76