summaryrefslogtreecommitdiff
path: root/deps/icu-small/source/common/putilimp.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/icu-small/source/common/putilimp.h')
-rw-r--r--deps/icu-small/source/common/putilimp.h69
1 files changed, 50 insertions, 19 deletions
diff --git a/deps/icu-small/source/common/putilimp.h b/deps/icu-small/source/common/putilimp.h
index 023e06879a..f744746b1f 100644
--- a/deps/icu-small/source/common/putilimp.h
+++ b/deps/icu-small/source/common/putilimp.h
@@ -94,7 +94,7 @@ typedef size_t uintptr_t;
# define U_NL_LANGINFO_CODESET CODESET
#endif
-#ifdef U_TZSET
+#if defined(U_TZSET) || defined(U_HAVE_TZSET)
/* Use the predefined value. */
#elif U_PLATFORM_USES_ONLY_WIN32_API
// UWP doesn't support tzset or environment variables for tz
@@ -132,7 +132,7 @@ typedef size_t uintptr_t;
# define U_TIMEZONE timezone
#endif
-#ifdef U_TZNAME
+#if defined(U_TZNAME) || defined(U_HAVE_TZNAME)
/* Use the predefined value. */
#elif U_PLATFORM_USES_ONLY_WIN32_API
/* not usable on all windows platforms */
@@ -204,30 +204,18 @@ typedef size_t uintptr_t;
/**
* \def U_HAVE_STD_ATOMICS
- * Defines whether the standard C++11 <atomic> is available.
- * ICU will use this when available,
- * otherwise will fall back to compiler or platform specific alternatives.
+ * Defines whether to use the standard C++11 <atomic> functions
+ * If false, ICU will fall back to compiler or platform specific alternatives.
+ * Note: support for these fall back options for atomics will be removed in a future version
+ * of ICU, and the use of C++ 11 atomics will be required.
* @internal
*/
#ifdef U_HAVE_STD_ATOMICS
/* Use the predefined value. */
-#elif U_CPLUSPLUS_VERSION < 11
- /* Not C++11, disable use of atomics */
-# define U_HAVE_STD_ATOMICS 0
-#elif __clang__ && __clang_major__==3 && __clang_minor__<=1
- /* Clang 3.1, has atomic variable initializer bug. */
-# define U_HAVE_STD_ATOMICS 0
#else
- /* U_HAVE_ATOMIC is typically set by an autoconf test of #include <atomic> */
- /* Can be set manually, or left undefined, on platforms without autoconf. */
-# if defined(U_HAVE_ATOMIC) && U_HAVE_ATOMIC
-# define U_HAVE_STD_ATOMICS 1
-# else
-# define U_HAVE_STD_ATOMICS 0
-# endif
+# define U_HAVE_STD_ATOMICS 1
#endif
-
/**
* \def U_HAVE_CLANG_ATOMICS
* Defines whether Clang c11 style built-in atomics are available.
@@ -586,6 +574,49 @@ U_INTERNAL void * U_EXPORT2 uprv_maximumPtr(void *base);
# endif
#endif
+
+#ifdef __cplusplus
+/**
+ * Pin a buffer capacity such that doing pointer arithmetic
+ * on the destination pointer and capacity cannot overflow.
+ *
+ * The pinned capacity must fulfill the following conditions (for positive capacities):
+ * - dest + capacity is a valid pointer according to the machine arcitecture (AS/400, 64-bit, etc.)
+ * - (dest + capacity) >= dest
+ * - The size (in bytes) of T[capacity] does not exceed 0x7fffffff
+ *
+ * @param dest the destination buffer pointer.
+ * @param capacity the requested buffer capacity, in units of type T.
+ * @return the pinned capacity.
+ * @internal
+ */
+template <typename T>
+inline int32_t pinCapacity(T *dest, int32_t capacity) {
+ if (capacity <= 0) { return capacity; }
+
+ uintptr_t destInt = (uintptr_t)dest;
+ uintptr_t maxInt;
+
+# if U_PLATFORM == U_PF_OS390 && !defined(_LP64)
+ // We have 31-bit pointers.
+ maxInt = 0x7fffffff;
+# elif U_PLATFORM == U_PF_OS400
+ maxInt = (uintptr_t)uprv_maximumPtr((void *)dest);
+# else
+ maxInt = destInt + 0x7fffffffu;
+ if (maxInt < destInt) {
+ // Less than 2GB to the end of the address space.
+ // Pin to that to prevent address overflow.
+ maxInt = (uintptr_t)-1;
+ }
+# endif
+
+ uintptr_t maxBytes = maxInt - destInt; // max. 2GB
+ int32_t maxCapacity = (int32_t)(maxBytes / sizeof(T));
+ return capacity <= maxCapacity ? capacity : maxCapacity;
+}
+#endif // __cplusplus
+
/* Dynamic Library Functions */
typedef void (UVoidFunction)(void);