Commit 9d518a68 authored by Stephan Hartmann's avatar Stephan Hartmann Committed by Commit Bot

GCC: fix __has_builtin defines for non-clang compilers

Defining __has_builtin to 0 for non-clang compilers in base headers can
lead to wrong detection of features. For example in base/location.h
checking for __has_builtin macros succeeds for non-clang compilers,
because base/check_op.h defines __has_builtin to 0 and is included
before base/location.h. Instead of defining __has_builtin to 0 for
non-clang compilers, define an independent preprocessor symbol that
reflects support for requested feature. Undefine the symbol to avoid
collision.

While we're at it fix base/memory/aligned_memory.h too.

Bug: 819294
Change-Id: Iac40dc44e7356b600e7d06aa4ccd1294bb09ebce
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2224252Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Commit-Queue: François Doray <fdoray@chromium.org>
Cr-Commit-Position: refs/heads/master@{#773784}
parent ae5b6def
......@@ -48,8 +48,10 @@ BASE_EXPORT char* StreamValToStr(const void* v,
void (*stream_func)(std::ostream&,
const void*));
#ifndef __has_builtin
#define __has_builtin(x) 0 // Compatibility with non-clang compilers.
#ifdef __has_builtin
#define SUPPORTS_BUILTIN_ADDRESSOF (__has_builtin(__builtin_addressof))
#else
#define SUPPORTS_BUILTIN_ADDRESSOF 0
#endif
template <typename T>
......@@ -65,7 +67,7 @@ CheckOpValueStr(const T& v) {
// operator& might be overloaded, so do the std::addressof dance.
// __builtin_addressof is preferred since it also handles Obj-C ARC pointers.
// Some casting is still needed, because T might be volatile.
#if __has_builtin(__builtin_addressof)
#if SUPPORTS_BUILTIN_ADDRESSOF
const void* vp = const_cast<const void*>(
reinterpret_cast<const volatile void*>(__builtin_addressof(v)));
#else
......@@ -75,6 +77,8 @@ CheckOpValueStr(const T& v) {
return StreamValToStr(vp, f);
}
#undef SUPPORTS_BUILTIN_ADDRESSOF
// Overload for types that have no operator<< but do have .ToString() defined.
template <typename T>
inline typename std::enable_if<
......
......@@ -57,13 +57,15 @@ struct AlignedFreeDeleter {
}
};
#ifndef __has_builtin
#define __has_builtin(x) 0 // Compatibility with non-clang compilers.
#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 __has_builtin(__builtin_is_aligned)
#if SUPPORTS_BUILTIN_IS_ALIGNED
return __builtin_is_aligned(val, alignment);
#else
DCHECK(!((alignment - 1) & alignment))
......@@ -72,6 +74,8 @@ inline bool IsAligned(uintptr_t val, size_t alignment) {
#endif
}
#undef SUPPORTS_BUILTIN_IS_ALIGNED
inline bool IsAligned(void* val, size_t alignment) {
return IsAligned(reinterpret_cast<uintptr_t>(val), alignment);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment