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
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index d3a9d01..8fba1c4 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -430,3 +430,73 @@
   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;
+}