Index: base/template_util.h |
diff --git a/base/template_util.h b/base/template_util.h |
index 1bfc1ac814a23ceb186a9fcf6fa5924281d92783..0dc6c952826b1e7cc03d1834327465847ffb6dfb 100644 |
--- a/base/template_util.h |
+++ b/base/template_util.h |
@@ -23,6 +23,23 @@ |
#define CR_USE_FALLBACKS_FOR_OLD_GLIBCXX |
#endif |
+// Some chromeos bots are using experimental 5.0 for some reason |
+// which has partial support for type_traits, but misses a smaller subset |
+// while removing some of the older non-standard stuff. |
+#define CR_GLIBCXX_5_0_0 20150123 |
+#if defined(__GLIBCXX__) && (__GLIBCXX__ == CR_GLIBCXX_5_0_0) |
+#define CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX |
+#endif |
+ |
+// This hacks around using gcc with libc++ which has some incompatibilies. |
+// - is_trivially_* doesn't work: https://llvm.org/bugs/show_bug.cgi?id=27538 |
+// TODO(danakj): Remove this when android builders are all using a newer version |
+// of gcc, or the android ndk is updated to a newer libc++ that works with older |
+// gcc versions. |
+#if !defined(__clang__) && defined(_LIBCPP_VERSION) |
+#define CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX |
+#endif |
+ |
namespace base { |
template <class T> struct is_non_const_reference : std::false_type {}; |
@@ -126,8 +143,53 @@ template <class T> |
using is_trivially_destructible = std::is_trivially_destructible<T>; |
#endif |
+// is_trivially_copyable is especially hard to get right. |
+// - Older versions of libstdc++ will fail to have it like they do for other |
+// type traits. In this case we should provide it based on compiler |
+// intrinsics. This is covered by the CR_USE_FALLBACKS_FOR_OLD_GLIBCXX define. |
+// - An experimental release of gcc includes most of type_traits but misses |
+// is_trivially_copyable, so we still have to avoid using libstdc++ in this |
+// case, which is covered by CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX. |
+// - When compiling libc++ from before r239653, with a gcc compiler, the |
+// std::is_trivially_copyable can fail. So we need to work around that by not |
+// using the one in libc++ in this case. This is covered by the |
+// CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX define, and is discussed in |
+// https://llvm.org/bugs/show_bug.cgi?id=27538#c1 where they point out that |
+// in libc++'s commit r239653 this is fixed by libc++ checking for gcc 5.1. |
+// - In both of the above cases we are using the gcc compiler. When defining |
+// this ourselves on compiler intrinsics, the __is_trivially_copyable() |
+// intrinsic is not available on gcc before version 5.1 (see the discussion in |
+// https://llvm.org/bugs/show_bug.cgi?id=27538#c1 again), so we must check for |
+// that version. |
+// - When __is_trivially_copyable() is not available because we are on gcc older |
+// than 5.1, we need to fall back to something, so we use __has_trivial_copy() |
+// instead based on what was done one-off in bit_cast() previously. |
+ |
+// TODO(crbug.com/554293): Remove this when all platforms have this in the std |
+// namespace and it works with gcc as needed. |
+#if defined(CR_USE_FALLBACKS_FOR_OLD_GLIBCXX) || \ |
+ defined(CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX) || \ |
+ defined(CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX) |
+template <typename T> |
+struct is_trivially_copyable { |
+// TODO(danakj): Remove this when android builders are all using a newer version |
+// of gcc, or the android ndk is updated to a newer libc++ that does this for |
+// us. |
+#if _GNUC_VER >= 501 |
+ static constexpr bool value = __is_trivially_copyable(T); |
+#else |
+ static constexpr bool value = __has_trivial_copy(T); |
+#endif |
+}; |
+#else |
+template <class T> |
+using is_trivially_copyable = std::is_trivially_copyable<T>; |
+#endif |
+ |
} // namespace base |
#undef CR_USE_FALLBACKS_FOR_OLD_GLIBCXX |
+#undef CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX |
+#undef CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX |
#endif // BASE_TEMPLATE_UTIL_H_ |