]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/common/ucnv.cpp
ICU-66108.tar.gz
[apple/icu.git] / icuSources / common / ucnv.cpp
index 4e57619f5009f2e5044dd8eafe01d1bfa2dc63e2..5dcf35e043850e85eb63e7d780af007a45f9a5f1 100644 (file)
@@ -25,6 +25,8 @@
 
 #if !UCONFIG_NO_CONVERSION
 
+#include <memory>
+
 #include "unicode/ustring.h"
 #include "unicode/ucnv.h"
 #include "unicode/ucnv_err.h"
@@ -158,7 +160,6 @@ ucnv_safeClone(const UConverter* cnv, void *stackBuffer, int32_t *pBufferSize, U
     UConverter *localConverter, *allocatedConverter;
     int32_t stackBufferSize;
     int32_t bufferSizeNeeded;
-    char *stackBufferChars = (char *)stackBuffer;
     UErrorCode cbErr;
     UConverterToUnicodeArgs toUArgs = {
         sizeof(UConverterToUnicodeArgs),
@@ -224,23 +225,22 @@ ucnv_safeClone(const UConverter* cnv, void *stackBuffer, int32_t *pBufferSize, U
         }
     }
 
-
-    /* Pointers on 64-bit platforms need to be aligned
-     * on a 64-bit boundary in memory.
+    /* Adjust (if necessary) the stackBuffer pointer to be aligned correctly for a UConverter.
+     * TODO(Jira ICU-20736) Redo this using std::align() once g++4.9 compatibility is no longer needed.
      */
-    if (U_ALIGNMENT_OFFSET(stackBuffer) != 0) {
-        int32_t offsetUp = (int32_t)U_ALIGNMENT_OFFSET_UP(stackBufferChars);
-        if(stackBufferSize > offsetUp) {
-            stackBufferSize -= offsetUp;
-            stackBufferChars += offsetUp;
+    if (stackBuffer) {
+        uintptr_t p = reinterpret_cast<uintptr_t>(stackBuffer);
+        uintptr_t aligned_p = (p + alignof(UConverter) - 1) & ~(alignof(UConverter) - 1);
+        ptrdiff_t pointerAdjustment = aligned_p - p;
+        if (bufferSizeNeeded + pointerAdjustment <= stackBufferSize) {
+            stackBuffer = reinterpret_cast<void *>(aligned_p);
+            stackBufferSize -= static_cast<int32_t>(pointerAdjustment);
         } else {
             /* prevent using the stack buffer but keep the size > 0 so that we do not just preflight */
             stackBufferSize = 1;
         }
     }
 
-    stackBuffer = (void *)stackBufferChars;
-    
     /* Now, see if we must allocate any memory */
     if (stackBufferSize < bufferSizeNeeded || stackBuffer == NULL)
     {
@@ -475,7 +475,7 @@ ucnv_setSubstString(UConverter *cnv,
                     const UChar *s,
                     int32_t length,
                     UErrorCode *err) {
-    UAlignedMemory cloneBuffer[U_CNV_SAFECLONE_BUFFERSIZE / sizeof(UAlignedMemory) + 1];
+    alignas(UConverter) char cloneBuffer[U_CNV_SAFECLONE_BUFFERSIZE];
     char chars[UCNV_ERROR_BUFFER_LENGTH];
 
     UConverter *clone;