]> granicus.if.org Git - icu/commitdiff
ICU-13725 Fixing NumberFormatter std::move test failure on MSVC.
authorShane Carr <shane@unicode.org>
Thu, 26 Apr 2018 03:38:17 +0000 (03:38 +0000)
committerShane Carr <shane@unicode.org>
Thu, 26 Apr 2018 03:38:17 +0000 (03:38 +0000)
X-SVN-Rev: 41282

icu4c/source/i18n/number_fluent.cpp
icu4c/source/i18n/unicode/numberformatter.h

index c0aacf46b5d27eb98069c7a1c19ba63a152c6de4..bc43defaa3cf8a687548254700600114a9075550 100644 (file)
@@ -378,13 +378,11 @@ LocalizedNumberFormatter::LocalizedNumberFormatter(LocalizedNumberFormatter&& sr
 
 LocalizedNumberFormatter::LocalizedNumberFormatter(NFS<LNF>&& src) U_NOEXCEPT
         : NFS<LNF>(std::move(src)) {
-    // For the move operators, copy over the call count and compiled formatter.
-    auto&& srcAsLNF = static_cast<LNF&&>(src);
-    fCompiled = srcAsLNF.fCompiled;
-    uprv_memcpy(fUnsafeCallCount, srcAsLNF.fUnsafeCallCount, sizeof(fUnsafeCallCount));
-    // Reset the source object to leave it in a safe state.
-    srcAsLNF.fCompiled = nullptr;
-    uprv_memset(srcAsLNF.fUnsafeCallCount, 0, sizeof(fUnsafeCallCount));
+    // For the move operators, copy over the compiled formatter.
+    // Note: if the formatter is not compiled, call count information is lost.
+    if (static_cast<LNF&&>(src).fCompiled != nullptr) {
+        lnfMoveHelper(static_cast<LNF&&>(src));
+    }
 }
 
 LocalizedNumberFormatter& LocalizedNumberFormatter::operator=(const LNF& other) {
@@ -395,13 +393,31 @@ LocalizedNumberFormatter& LocalizedNumberFormatter::operator=(const LNF& other)
 
 LocalizedNumberFormatter& LocalizedNumberFormatter::operator=(LNF&& src) U_NOEXCEPT {
     NFS<LNF>::operator=(static_cast<NFS<LNF>&&>(src));
-    // For the move operators, copy over the call count and compiled formatter.
+    // For the move operators, copy over the compiled formatter.
+    // Note: if the formatter is not compiled, call count information is lost.
+    if (static_cast<LNF&&>(src).fCompiled != nullptr) {
+        // Formatter is compiled
+        lnfMoveHelper(static_cast<LNF&&>(src));
+    } else {
+        // Reset to default values.
+        auto* callCount = reinterpret_cast<u_atomic_int32_t*>(fUnsafeCallCount);
+        umtx_storeRelease(*callCount, 0);
+        fCompiled = nullptr;
+    }
+    return *this;
+}
+
+void LocalizedNumberFormatter::lnfMoveHelper(LNF&& src) {
+    // Copy over the compiled formatter and set call count to INT32_MIN as in computeCompiled().
+    // Don't copy the call count directly because doing so requires a loadAcquire/storeRelease.
+    // The bits themselves appear to be platform-dependent, so copying them might not be safe.
+    auto* callCount = reinterpret_cast<u_atomic_int32_t*>(fUnsafeCallCount);
+    umtx_storeRelease(*callCount, INT32_MIN);
     fCompiled = src.fCompiled;
-    uprv_memcpy(fUnsafeCallCount, src.fUnsafeCallCount, sizeof(fUnsafeCallCount));
     // Reset the source object to leave it in a safe state.
+    auto* srcCallCount = reinterpret_cast<u_atomic_int32_t*>(src.fUnsafeCallCount);
+    umtx_storeRelease(*srcCallCount, 0);
     src.fCompiled = nullptr;
-    uprv_memset(src.fUnsafeCallCount, 0, sizeof(fUnsafeCallCount));
-    return *this;
 }
 
 
index 9b3a1ed72965d15e12d187725592e09c1d83c24e..d09ab365a87ca61fb43994198aa8102c85c30b51 100644 (file)
@@ -2293,6 +2293,8 @@ class U_I18N_API LocalizedNumberFormatter
 
     LocalizedNumberFormatter(impl::MacroProps &&macros, const Locale &locale);
 
+    void lnfMoveHelper(LocalizedNumberFormatter&& src);
+
     /**
      * @return true if the compiled formatter is available.
      */