summaryrefslogtreecommitdiff
path: root/tests/malloc_test.cpp
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2016-02-11 15:51:31 -0800
committerChristopher Ferris <cferris@google.com>2016-02-12 17:30:30 -0800
commit72df6708c829a4c6494936fdfbda6dc7e68e647b (patch)
tree17ede0d54b6f50c3598a3fcec56f50754067690d /tests/malloc_test.cpp
parent72bca4b4105e24058f3f2eca024382bedb122a30 (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.cpp70
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;
+}