Bug 1179451 - Part 5: Delete nsRefPtr<T>::operator T*()&&. r=froydnj
authorAryeh Gregor <ayg@aryeh.name>
Thu, 13 Aug 2015 15:22:48 +0300
changeset 257841 b6c0a8f95b52cd5e6fd56a36ab62b3973c64ea32
parent 257840 aef5d038f5734d5eded84ba9d77982df6963988f
child 257842 d9a56e97c6b1a4184deaf3f9c7b8a8872bd7fd21
push id29230
push userryanvm@gmail.com
push dateFri, 14 Aug 2015 19:16:25 +0000
treeherdermozilla-central@09dd35dd1193 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1179451
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1179451 - Part 5: Delete nsRefPtr<T>::operator T*()&&. r=froydnj
mfbt/nsRefPtr.h
widget/android/nsWindow.cpp
--- a/mfbt/nsRefPtr.h
+++ b/mfbt/nsRefPtr.h
@@ -2,16 +2,28 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_nsRefPtr_h
 #define mozilla_nsRefPtr_h
 
+#if defined(_MSC_VER) && _MSC_VER >= 1900
+#  define MOZ_HAVE_REF_QUALIFIERS
+#elif defined(__clang__)
+// All supported Clang versions
+#  define MOZ_HAVE_REF_QUALIFIERS
+#elif defined(__GNUC__)
+#  include "mozilla/Compiler.h"
+#  if MOZ_GCC_VERSION_AT_LEAST(4, 8, 1)
+#    define MOZ_HAVE_REF_QUALIFIERS
+#  endif
+#endif
+
 #include "mozilla/AlreadyAddRefed.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 
 /*****************************************************************************/
 
 // template <class T> class nsRefPtrGetterAddRefs;
 
@@ -236,28 +248,44 @@ public:
     Prefer the implicit conversion provided automatically by |operator T*() const|.
     Use |get()| to resolve ambiguity or to get a castable pointer.
   */
   {
     return const_cast<T*>(mRawPtr);
   }
 
   operator T*() const
+#ifdef MOZ_HAVE_REF_QUALIFIERS
+  &
+#endif
   /*
     ...makes an |nsRefPtr| act like its underlying raw pointer type whenever it
     is used in a context where a raw pointer is expected.  It is this operator
     that makes an |nsRefPtr| substitutable for a raw pointer.
 
     Prefer the implicit use of this operator to calling |get()|, except where
     necessary to resolve ambiguity.
   */
   {
     return get();
   }
 
+#ifdef MOZ_HAVE_REF_QUALIFIERS
+  // Don't allow implicit conversion of temporary nsRefPtr to raw pointer,
+  // because the refcount might be one and the pointer will immediately become
+  // invalid.
+  operator T*() const && = delete;
+
+  // These are needed to avoid the deleted operator above.  XXX Why is operator!
+  // needed separately?  Shouldn't the compiler prefer using the non-deleted
+  // operator bool instead of the deleted operator T*?
+  explicit operator bool() const { return !!mRawPtr; }
+  bool operator!() const { return !mRawPtr; }
+#endif
+
   T*
   operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN
   {
     MOZ_ASSERT(mRawPtr != 0,
                "You can't dereference a NULL nsRefPtr with operator->().");
     return get();
   }
 
@@ -566,9 +594,13 @@ operator!=(::detail::nsRefPtrZero* aLhs,
 template <class T>
 inline already_AddRefed<T>
 do_AddRef(T*&& aObj)
 {
   nsRefPtr<T> ref(aObj);
   return ref.forget();
 }
 
+#ifdef MOZ_HAVE_REF_QUALIFIERS
+#undef MOZ_HAVE_REF_QUALIFIERS
+#endif
+
 #endif /* mozilla_nsRefPtr_h */
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -2045,17 +2045,17 @@ nsWindow::NotifyIMEInternal(const IMENot
             RemoveIMEComposition();
             GeckoAppShell::NotifyIME(REQUEST_TO_COMMIT_COMPOSITION);
             return NS_OK;
 
         case REQUEST_TO_CANCEL_COMPOSITION:
             ALOGIME("IME: REQUEST_TO_CANCEL_COMPOSITION");
 
             // Cancel composition on Gecko side
-            if (GetIMEComposition()) {
+            if (!!GetIMEComposition()) {
                 nsRefPtr<nsWindow> kungFuDeathGrip(this);
 
                 WidgetCompositionEvent compositionCommitEvent(
                                          true, NS_COMPOSITION_COMMIT, this);
                 InitEvent(compositionCommitEvent, nullptr);
                 // Dispatch it with empty mData value for canceling the
                 // composition
                 DispatchEvent(&compositionCommitEvent);