diff options
author | Christopher Ferris <cferris@google.com> | 2016-02-11 15:51:31 -0800 |
---|---|---|
committer | Christopher Ferris <cferris@google.com> | 2016-02-12 17:30:30 -0800 |
commit | 72df6708c829a4c6494936fdfbda6dc7e68e647b (patch) | |
tree | 17ede0d54b6f50c3598a3fcec56f50754067690d /tests/malloc_test.cpp | |
parent | 72bca4b4105e24058f3f2eca024382bedb122a30 (diff) |
Fix the default alignment of the allocations.
In order to enforce this constraint:
The pointer returned if the allocation succeeds shall be suitably
aligned so that it may be assigned to a pointer to any type of object
and then used to access such an object in the space allocated.
Force all allocations on 32 bit systems to have 8 byte alignment,
and all allocations on 64 bit systems to have 16 byte alignment.
Add a test to verify that the allocator returns the correct alignments.
Bug: 26739265
Change-Id: I9af53279617408676b94e4ec6481b3ed7ffafc6a
Diffstat (limited to 'tests/malloc_test.cpp')
-rw-r--r-- | tests/malloc_test.cpp | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp index d3a9d01e4..8fba1c449 100644 --- a/tests/malloc_test.cpp +++ b/tests/malloc_test.cpp @@ -430,3 +430,73 @@ TEST(malloc, realloc_0) { void* p2 = realloc(p, 0); ASSERT_TRUE(p2 == nullptr); } + +constexpr size_t MAX_LOOPS = 200; + +// Make sure that memory returned by malloc is aligned to allow these data types. +TEST(malloc, verify_alignment) { + uint32_t** values_32 = new uint32_t*[MAX_LOOPS]; + uint64_t** values_64 = new uint64_t*[MAX_LOOPS]; + long double** values_ldouble = new long double*[MAX_LOOPS]; + // Use filler to attempt to force the allocator to get potentially bad alignments. + void** filler = new void*[MAX_LOOPS]; + + for (size_t i = 0; i < MAX_LOOPS; i++) { + // Check uint32_t pointers. + filler[i] = malloc(1); + ASSERT_TRUE(filler[i] != nullptr); + + values_32[i] = reinterpret_cast<uint32_t*>(malloc(sizeof(uint32_t))); + ASSERT_TRUE(values_32[i] != nullptr); + *values_32[i] = i; + ASSERT_EQ(*values_32[i], i); + ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_32[i]) & (sizeof(uint32_t) - 1)); + + free(filler[i]); + } + + for (size_t i = 0; i < MAX_LOOPS; i++) { + // Check uint64_t pointers. + filler[i] = malloc(1); + ASSERT_TRUE(filler[i] != nullptr); + + values_64[i] = reinterpret_cast<uint64_t*>(malloc(sizeof(uint64_t))); + ASSERT_TRUE(values_64[i] != nullptr); + *values_64[i] = 0x1000 + i; + ASSERT_EQ(*values_64[i], 0x1000 + i); + ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_64[i]) & (sizeof(uint64_t) - 1)); + + free(filler[i]); + } + + for (size_t i = 0; i < MAX_LOOPS; i++) { + // Check long double pointers. + filler[i] = malloc(1); + ASSERT_TRUE(filler[i] != nullptr); + + values_ldouble[i] = reinterpret_cast<long double*>(malloc(sizeof(long double))); + ASSERT_TRUE(values_ldouble[i] != nullptr); + *values_ldouble[i] = 5.5 + i; + ASSERT_DOUBLE_EQ(*values_ldouble[i], 5.5 + i); + // 32 bit glibc has a long double size of 12 bytes, so hardcode the + // required alignment to 0x7. +#if !defined(__BIONIC__) && !defined(__LP64__) + ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & 0x7); +#else + ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & (sizeof(long double) - 1)); +#endif + + free(filler[i]); + } + + for (size_t i = 0; i < MAX_LOOPS; i++) { + free(values_32[i]); + free(values_64[i]); + free(values_ldouble[i]); + } + + delete[] filler; + delete[] values_32; + delete[] values_64; + delete[] values_ldouble; +} |