Update third_party/base/memory/aligned_memory.*.

Port the following CLs:
crrev.com/756778: Add IsAligned helpers, but not IsPageAligned() to
                  avoid dragging in more Chromium headers.
crrev.com/773784: GCC fix for IsAligned().
crrev.com/776967: Clean up CL.

Change-Id: If2138b0e1e0cd3465d55e069a4e6b0808fc4ce4e
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/70476
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/third_party/base/memory/aligned_memory.cc b/third_party/base/memory/aligned_memory.cc
index b4cd54f..3cacf3f 100644
--- a/third_party/base/memory/aligned_memory.cc
+++ b/third_party/base/memory/aligned_memory.cc
@@ -16,23 +16,25 @@
 
 void* AlignedAlloc(size_t size, size_t alignment) {
   DCHECK(size > 0U);
-  DCHECK_EQ(alignment & (alignment - 1), 0U);
+  DCHECK(bits::IsPowerOfTwo(alignment));
   DCHECK_EQ(alignment % sizeof(void*), 0U);
   void* ptr = nullptr;
 #if defined(COMPILER_MSVC)
   ptr = _aligned_malloc(size, alignment);
-// Android technically supports posix_memalign(), but does not expose it in
-// the current version of the library headers used by Chrome.  Luckily,
-// memalign() on Android returns pointers which can safely be used with
-// free(), so we can use it instead.  Issue filed to document this:
-// http://code.google.com/p/android/issues/detail?id=35391
 #elif defined(OS_ANDROID)
+  // Android technically supports posix_memalign(), but does not expose it in
+  // the current version of the library headers used by Chrome.  Luckily,
+  // memalign() on Android returns pointers which can safely be used with
+  // free(), so we can use it instead.  Issue filed to document this:
+  // http://code.google.com/p/android/issues/detail?id=35391
   ptr = memalign(alignment, size);
 #else
-  if (int ret = posix_memalign(&ptr, alignment, size)) {
+  int ret = posix_memalign(&ptr, alignment, size);
+  if (ret != 0) {
     ptr = nullptr;
   }
 #endif
+
   // Since aligned allocations may fail for non-memory related reasons, force a
   // crash if we encounter a failed allocation; maintaining consistent behavior
   // with a normal allocation failure in Chrome.
@@ -40,7 +42,7 @@
     CHECK(false);
   }
   // Sanity check alignment just to be safe.
-  DCHECK_EQ(reinterpret_cast<uintptr_t>(ptr) & (alignment - 1), 0U);
+  DCHECK(IsAligned(ptr, alignment));
   return ptr;
 }
 
diff --git a/third_party/base/memory/aligned_memory.h b/third_party/base/memory/aligned_memory.h
index 59510e7..06241a5 100644
--- a/third_party/base/memory/aligned_memory.h
+++ b/third_party/base/memory/aligned_memory.h
@@ -12,7 +12,7 @@
 
 #include "build/build_config.h"
 #include "third_party/base/base_export.h"
-#include "third_party/base/compiler_specific.h"
+#include "third_party/base/bits.h"
 
 #if defined(COMPILER_MSVC)
 #include <malloc.h>
@@ -56,6 +56,28 @@
   }
 };
 
+#ifdef __has_builtin
+#define SUPPORTS_BUILTIN_IS_ALIGNED (__has_builtin(__builtin_is_aligned))
+#else
+#define SUPPORTS_BUILTIN_IS_ALIGNED 0
+#endif
+
+inline bool IsAligned(uintptr_t val, size_t alignment) {
+  // If the compiler supports builtin alignment checks prefer them.
+#if SUPPORTS_BUILTIN_IS_ALIGNED
+  return __builtin_is_aligned(val, alignment);
+#else
+  DCHECK(bits::IsPowerOfTwo(alignment));
+  return (val & (alignment - 1)) == 0;
+#endif
+}
+
+#undef SUPPORTS_BUILTIN_IS_ALIGNED
+
+inline bool IsAligned(void* val, size_t alignment) {
+  return IsAligned(reinterpret_cast<uintptr_t>(val), alignment);
+}
+
 }  // namespace base
 }  // namespace pdfium