From f2076c6a4c9c14538d71a3ef9c9e4fd40ee6ee00 Mon Sep 17 00:00:00 2001 From: Stephan Hartmann Date: Sun, 31 May 2020 11:46:05 +0000 Subject: [PATCH] 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 --- diff --git a/base/check_op.h b/base/check_op.h index 04b0c6f..28f4263a 100644 --- a/base/check_op.h +++ b/base/check_op.h @@ -48,8 +48,10 @@ 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 @@ -65,7 +67,7 @@ // 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( reinterpret_cast(__builtin_addressof(v))); #else @@ -75,6 +77,8 @@ return StreamValToStr(vp, f); } +#undef SUPPORTS_BUILTIN_ADDRESSOF + // Overload for types that have no operator<< but do have .ToString() defined. template inline typename std::enable_if< diff --git a/base/memory/aligned_memory.h b/base/memory/aligned_memory.h index d1cba0c..a0d9f13 100644 --- a/base/memory/aligned_memory.h +++ b/base/memory/aligned_memory.h @@ -57,13 +57,15 @@ } }; -#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 @@ #endif } +#undef SUPPORTS_BUILTIN_IS_ALIGNED + inline bool IsAligned(void* val, size_t alignment) { return IsAligned(reinterpret_cast(val), alignment); }