69 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			69 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
// RUN: %clang_scudo %s -lstdc++ -o %t
 | 
						|
// RUN:     %run %t pointers 2>&1
 | 
						|
// RUN:     %run %t contents 2>&1
 | 
						|
// RUN: not %run %t memalign 2>&1 | FileCheck %s
 | 
						|
 | 
						|
// Tests that our reallocation function returns the same pointer when the
 | 
						|
// requested size can fit into the previously allocated chunk. Also tests that
 | 
						|
// a new chunk is returned if the size is greater, and that the contents of the
 | 
						|
// chunk are left unchanged.
 | 
						|
// As a final test, make sure that a chunk allocated by memalign cannot be
 | 
						|
// reallocated.
 | 
						|
 | 
						|
#include <assert.h>
 | 
						|
#include <malloc.h>
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
#include <vector>
 | 
						|
 | 
						|
int main(int argc, char **argv)
 | 
						|
{
 | 
						|
  void *p, *old_p;
 | 
						|
  // Those sizes will exercise both allocators (Primary & Secondary).
 | 
						|
  std::vector<size_t> sizes{1, 16, 1024, 32768, 1 << 16, 1 << 17, 1 << 20};
 | 
						|
 | 
						|
  assert(argc == 2);
 | 
						|
 | 
						|
  for (size_t size : sizes) {
 | 
						|
    if (!strcmp(argv[1], "pointers")) {
 | 
						|
      old_p = p = realloc(nullptr, size);
 | 
						|
      assert(p);
 | 
						|
      size = malloc_usable_size(p);
 | 
						|
      // Our realloc implementation will return the same pointer if the size
 | 
						|
      // requested is lower than or equal to the usable size of the associated
 | 
						|
      // chunk.
 | 
						|
      p = realloc(p, size - 1);
 | 
						|
      assert(p == old_p);
 | 
						|
      p = realloc(p, size);
 | 
						|
      assert(p == old_p);
 | 
						|
      // And a new one if the size is greater.
 | 
						|
      p = realloc(p, size + 1);
 | 
						|
      assert(p != old_p);
 | 
						|
      // A size of 0 will free the chunk and return nullptr.
 | 
						|
      p = realloc(p, 0);
 | 
						|
      assert(!p);
 | 
						|
      old_p = nullptr;
 | 
						|
    }
 | 
						|
    if (!strcmp(argv[1], "contents")) {
 | 
						|
      p = realloc(nullptr, size);
 | 
						|
      assert(p);
 | 
						|
      for (int i = 0; i < size; i++)
 | 
						|
        reinterpret_cast<char *>(p)[i] = 'A';
 | 
						|
      p = realloc(p, size + 1);
 | 
						|
      // The contents of the reallocated chunk must match the original one.
 | 
						|
      for (int i = 0; i < size; i++)
 | 
						|
        assert(reinterpret_cast<char *>(p)[i] == 'A');
 | 
						|
    }
 | 
						|
    if (!strcmp(argv[1], "memalign")) {
 | 
						|
      // A chunk coming from memalign cannot be reallocated.
 | 
						|
      p = memalign(16, size);
 | 
						|
      assert(p);
 | 
						|
      p = realloc(p, size);
 | 
						|
      free(p);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
// CHECK: ERROR: invalid chunk type when reallocating address
 |