From 948aa59b70ff9cca95aecec56d3658a04b8bdcc3 Mon Sep 17 00:00:00 2001
From: Jose Dapena Paz <jose.dapena@lge.com>
Date: Thu, 29 Aug 2019 17:31:18 +0200
Subject: [PATCH] Cherry-pick "Do not override clang compiler internal
 builtins" in ICU

Merge
https://github.com/unicode-org/icu/pull/770

This is required to avoid breaking builtins detection in chromium code
that includes ICU.

Bug: 819294
Change-Id: Ia4c8978fc30131903de50be6995ff5aebad5c1e5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/deps/icu/+/1716752
Reviewed-by: Jungshik Shin <jshin@chromium.org>
---
 README.chromium                  |   7 +++
 patches/clang_builtins.patch     | 102 +++++++++++++++++++++++++++++++
 source/common/unicode/platform.h |  57 +++++++++++------
 3 files changed, 147 insertions(+), 19 deletions(-)
 create mode 100644 patches/clang_builtins.patch

diff --git a/README.chromium b/README.chromium
index 375d7edfc..f3b07c8b9 100644
--- a/README.chromium
+++ b/README.chromium
@@ -325,3 +325,10 @@ D. Local Modifications
     https://unicode-org.atlassian.net/browse/ICU-20729
   - upstream PR:
     https://github.com/unicode-org/icu/pull/712
+
+18. Do not override clang compiler internal builtins
+  - patches/clang_builtins.patch
+  - upstream bug:
+    https://unicode-org.atlassian.net/browse/ICU-20784
+  - upstream PR:
+    https://github.com/unicode-org/icu/pull/770
diff --git a/patches/clang_builtins.patch b/patches/clang_builtins.patch
new file mode 100644
index 000000000..7aef7cc4b
--- /dev/null
+++ b/patches/clang_builtins.patch
@@ -0,0 +1,102 @@
+diff --git a/source/common/unicode/platform.h b/source/common/unicode/platform.h
+index a3623f5d..715c92b5 100644
+--- a/source/common/unicode/platform.h
++++ b/source/common/unicode/platform.h
+@@ -414,26 +414,40 @@
+ #endif
+ 
+ /* Compatibility with compilers other than clang: http://clang.llvm.org/docs/LanguageExtensions.html */
+-#ifndef __has_attribute
+-#    define __has_attribute(x) 0
++#ifdef __has_attribute
++#   define UPRV_HAS_ATTRIBUTE(x) __has_attribute(x)
++#else
++#   define UPRV_HAS_ATTRIBUTE(x) 0
+ #endif
+-#ifndef __has_cpp_attribute
+-#    define __has_cpp_attribute(x) 0
++#ifdef __has_cpp_attribute
++#   define UPRV_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
++#else
++#   define UPRV_HAS_CPP_ATTRIBUTE(x) 0
+ #endif
+-#ifndef __has_declspec_attribute
+-#    define __has_declspec_attribute(x) 0
++#ifdef __has_declspec_attribute
++#   define UPRV_HAS_DECLSPEC_ATTRIBUTE(x) __has_declspec_attribute(x)
++#else
++#   define UPRV_HAS_DECLSPEC_ATTRIBUTE(x) 0
+ #endif
+-#ifndef __has_builtin
+-#    define __has_builtin(x) 0
++#ifdef __has_builtin
++#   define UPRV_HAS_BUILTIN(x) __has_builtin(x)
++#else
++#   define UPRV_HAS_BUILTIN(x) 0
+ #endif
+-#ifndef __has_feature
+-#    define __has_feature(x) 0
++#ifdef __has_feature
++#   define UPRV_HAS_FEATURE(x) __has_feature(x)
++#else
++#   define UPRV_HAS_FEATURE(x) 0
+ #endif
+-#ifndef __has_extension
+-#    define __has_extension(x) 0
++#ifdef __has_extension
++#   define UPRV_HAS_EXTENSION(x) __has_extension(x)
++#else
++#   define UPRV_HAS_EXTENSION(x) 0
+ #endif
+-#ifndef __has_warning
+-#    define __has_warning(x) 0
++#ifdef __has_warning
++#   define UPRV_HAS_WARNING(x) __has_warning(x)
++#else
++#   define UPRV_HAS_WARNING(x) 0
+ #endif
+ 
+ /**
+@@ -452,7 +466,9 @@
+  * Attribute to specify the size of the allocated buffer for malloc-like functions
+  * @internal
+  */
+-#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || __has_attribute(alloc_size)
++#if (defined(__GNUC__) &&                                            \
++        (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || \
++        UPRV_HAS_ATTRIBUTE(alloc_size)
+ #   define U_ALLOC_SIZE_ATTR(X) __attribute__ ((alloc_size(X)))
+ #   define U_ALLOC_SIZE_ATTR2(X,Y) __attribute__ ((alloc_size(X,Y)))
+ #else
+@@ -516,8 +532,9 @@ namespace std {
+ #elif defined(__clang__)
+     // Test for compiler vs. feature separately.
+     // Other compilers might choke on the feature test.
+-#   if __has_cpp_attribute(clang::fallthrough) || \
+-            (__has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough"))
++#    if UPRV_HAS_CPP_ATTRIBUTE(clang::fallthrough) || \
++             (UPRV_HAS_FEATURE(cxx_attributes) &&     \
++             UPRV_HAS_WARNING("-Wimplicit-fallthrough"))
+ #       define U_FALLTHROUGH [[clang::fallthrough]]
+ #   endif
+ #elif defined(__GNUC__) && (__GNUC__ >= 7)
+@@ -786,7 +803,8 @@ namespace std {
+     /* Use the predefined value. */
+ #elif defined(U_STATIC_IMPLEMENTATION)
+ #   define U_EXPORT
+-#elif defined(_MSC_VER) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))
++#elif defined(_MSC_VER) || (UPRV_HAS_DECLSPEC_ATTRIBUTE(dllexport) && \
++                            UPRV_HAS_DECLSPEC_ATTRIBUTE(dllimport))
+ #   define U_EXPORT __declspec(dllexport)
+ #elif defined(__GNUC__)
+ #   define U_EXPORT __attribute__((visibility("default")))
+@@ -810,7 +828,8 @@ namespace std {
+ 
+ #ifdef U_IMPORT
+     /* Use the predefined value. */
+-#elif defined(_MSC_VER) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))
++#elif defined(_MSC_VER) || (UPRV_HAS_DECLSPEC_ATTRIBUTE(dllexport) && \
++                            UPRV_HAS_DECLSPEC_ATTRIBUTE(dllimport))
+     /* Windows needs to export/import data. */
+ #   define U_IMPORT __declspec(dllimport)
+ #else
diff --git a/source/common/unicode/platform.h b/source/common/unicode/platform.h
index a3623f5da..715c92b52 100644
--- a/source/common/unicode/platform.h
+++ b/source/common/unicode/platform.h
@@ -414,26 +414,40 @@
 #endif
 
 /* Compatibility with compilers other than clang: http://clang.llvm.org/docs/LanguageExtensions.html */
-#ifndef __has_attribute
-#    define __has_attribute(x) 0
+#ifdef __has_attribute
+#   define UPRV_HAS_ATTRIBUTE(x) __has_attribute(x)
+#else
+#   define UPRV_HAS_ATTRIBUTE(x) 0
 #endif
-#ifndef __has_cpp_attribute
-#    define __has_cpp_attribute(x) 0
+#ifdef __has_cpp_attribute
+#   define UPRV_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
+#else
+#   define UPRV_HAS_CPP_ATTRIBUTE(x) 0
 #endif
-#ifndef __has_declspec_attribute
-#    define __has_declspec_attribute(x) 0
+#ifdef __has_declspec_attribute
+#   define UPRV_HAS_DECLSPEC_ATTRIBUTE(x) __has_declspec_attribute(x)
+#else
+#   define UPRV_HAS_DECLSPEC_ATTRIBUTE(x) 0
 #endif
-#ifndef __has_builtin
-#    define __has_builtin(x) 0
+#ifdef __has_builtin
+#   define UPRV_HAS_BUILTIN(x) __has_builtin(x)
+#else
+#   define UPRV_HAS_BUILTIN(x) 0
 #endif
-#ifndef __has_feature
-#    define __has_feature(x) 0
+#ifdef __has_feature
+#   define UPRV_HAS_FEATURE(x) __has_feature(x)
+#else
+#   define UPRV_HAS_FEATURE(x) 0
 #endif
-#ifndef __has_extension
-#    define __has_extension(x) 0
+#ifdef __has_extension
+#   define UPRV_HAS_EXTENSION(x) __has_extension(x)
+#else
+#   define UPRV_HAS_EXTENSION(x) 0
 #endif
-#ifndef __has_warning
-#    define __has_warning(x) 0
+#ifdef __has_warning
+#   define UPRV_HAS_WARNING(x) __has_warning(x)
+#else
+#   define UPRV_HAS_WARNING(x) 0
 #endif
 
 /**
@@ -452,7 +466,9 @@
  * Attribute to specify the size of the allocated buffer for malloc-like functions
  * @internal
  */
-#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || __has_attribute(alloc_size)
+#if (defined(__GNUC__) &&                                            \
+        (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || \
+        UPRV_HAS_ATTRIBUTE(alloc_size)
 #   define U_ALLOC_SIZE_ATTR(X) __attribute__ ((alloc_size(X)))
 #   define U_ALLOC_SIZE_ATTR2(X,Y) __attribute__ ((alloc_size(X,Y)))
 #else
@@ -516,8 +532,9 @@ namespace std {
 #elif defined(__clang__)
     // Test for compiler vs. feature separately.
     // Other compilers might choke on the feature test.
-#   if __has_cpp_attribute(clang::fallthrough) || \
-            (__has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough"))
+#    if UPRV_HAS_CPP_ATTRIBUTE(clang::fallthrough) || \
+             (UPRV_HAS_FEATURE(cxx_attributes) &&     \
+             UPRV_HAS_WARNING("-Wimplicit-fallthrough"))
 #       define U_FALLTHROUGH [[clang::fallthrough]]
 #   endif
 #elif defined(__GNUC__) && (__GNUC__ >= 7)
@@ -786,7 +803,8 @@ namespace std {
     /* Use the predefined value. */
 #elif defined(U_STATIC_IMPLEMENTATION)
 #   define U_EXPORT
-#elif defined(_MSC_VER) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))
+#elif defined(_MSC_VER) || (UPRV_HAS_DECLSPEC_ATTRIBUTE(dllexport) && \
+                            UPRV_HAS_DECLSPEC_ATTRIBUTE(dllimport))
 #   define U_EXPORT __declspec(dllexport)
 #elif defined(__GNUC__)
 #   define U_EXPORT __attribute__((visibility("default")))
@@ -810,7 +828,8 @@ namespace std {
 
 #ifdef U_IMPORT
     /* Use the predefined value. */
-#elif defined(_MSC_VER) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))
+#elif defined(_MSC_VER) || (UPRV_HAS_DECLSPEC_ATTRIBUTE(dllexport) && \
+                            UPRV_HAS_DECLSPEC_ATTRIBUTE(dllimport))
     /* Windows needs to export/import data. */
 #   define U_IMPORT __declspec(dllimport)
 #else
-- 
GitLab