diff options
Diffstat (limited to 'deps/icu-small/source/common/putilimp.h')
-rw-r--r-- | deps/icu-small/source/common/putilimp.h | 69 |
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 023e06879a0..f744746b1f0 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); |