Bug 1316206 - RefPtr construction/assignment from nullptr - r=froydnj
authorGerald Squelart <gsquelart@mozilla.com>
Thu, 10 Nov 2016 07:58:10 +1100
changeset 364697 d78a1d9f6a4a82a3f134c095ead3d6ecf95ec204
parent 364696 2635cff0413bd1d4c6b0be57b579aa41393ad1ab
child 364698 9380a01deaf545a1ef339caaf15ffb951c158681
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-beta@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1316206
milestone52.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 1316206 - RefPtr construction/assignment from nullptr - r=froydnj Added constructor and operator= from a nullptr, bypassing the incoming pointer check. Note that the constructor is 'explicit', because one particular use in nsBaseHashtable is doing a 'return 0' into a templated type that is a RefPtr in many cases. Making this new constructor explicit removes it from consideration in this case. As it's not strictly necessary to have it MOZ_IMPLICIT (but could still be nice), I will tackle that in the patch after next. Also changed all zeroes into nullptr when relevant in RefPtr.h (other system- wide affected files will be updated in following patch.) MozReview-Commit-ID: Ds4CEv9hZWI
mfbt/RefPtr.h
--- a/mfbt/RefPtr.h
+++ b/mfbt/RefPtr.h
@@ -77,17 +77,17 @@ public:
     if (mRawPtr) {
       ConstRemovingRefPtrTraits<T>::Release(mRawPtr);
     }
   }
 
   // Constructors
 
   RefPtr()
-    : mRawPtr(0)
+    : mRawPtr(nullptr)
     // default constructor
   {
   }
 
   RefPtr(const RefPtr<T>& aSmartPtr)
     : mRawPtr(aSmartPtr.mRawPtr)
     // copy-constructor
   {
@@ -107,16 +107,21 @@ public:
   MOZ_IMPLICIT RefPtr(T* aRawPtr)
     : mRawPtr(aRawPtr)
   {
     if (mRawPtr) {
       ConstRemovingRefPtrTraits<T>::AddRef(mRawPtr);
     }
   }
 
+  explicit RefPtr(decltype(nullptr))
+    : mRawPtr(nullptr)
+  {
+  }
+
   template <typename I>
   MOZ_IMPLICIT RefPtr(already_AddRefed<I>& aSmartPtr)
     : mRawPtr(aSmartPtr.take())
     // construct from |already_AddRefed|
   {
   }
 
   template <typename I>
@@ -151,16 +156,23 @@ public:
 
   // Defined in StaticPtr.h
   template<class U>
   MOZ_IMPLICIT RefPtr(const mozilla::StaticRefPtr<U>& aOther);
 
   // Assignment operators
 
   RefPtr<T>&
+  operator=(decltype(nullptr))
+  {
+    assign_assuming_AddRef(nullptr);
+    return *this;
+  }
+
+  RefPtr<T>&
   operator=(const RefPtr<T>& aRhs)
   // copy assignment operator
   {
     assign_with_AddRef(aRhs.mRawPtr);
     return *this;
   }
 
   template <typename I>
@@ -238,32 +250,32 @@ public:
     mRawPtr = temp;
   }
 
   already_AddRefed<T>
   forget()
   // return the value of mRawPtr and null out mRawPtr. Useful for
   // already_AddRefed return values.
   {
-    T* temp = 0;
+    T* temp = nullptr;
     swap(temp);
     return already_AddRefed<T>(temp);
   }
 
   template <typename I>
   void
   forget(I** aRhs)
   // Set the target of aRhs to the value of mRawPtr and null out mRawPtr.
   // Useful to avoid unnecessary AddRef/Release pairs with "out"
   // parameters where aRhs bay be a T** or an I** where I is a base class
   // of T.
   {
     MOZ_ASSERT(aRhs, "Null pointer passed to forget!");
     *aRhs = mRawPtr;
-    mRawPtr = 0;
+    mRawPtr = nullptr;
   }
 
   T*
   get() const
   /*
     Prefer the implicit conversion provided automatically by |operator T*() const|.
     Use |get()| to resolve ambiguity or to get a castable pointer.
   */
@@ -298,17 +310,17 @@ public:
   // 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,
+    MOZ_ASSERT(mRawPtr != nullptr,
                "You can't dereference a NULL RefPtr with operator->().");
     return get();
   }
 
   template <typename R, typename... Args>
   class Proxy
   {
     typedef R (T::*member_function)(Args...);
@@ -325,17 +337,17 @@ public:
     {
       return ((*mRawPtr).*mFunction)(mozilla::Forward<ActualArgs>(aArgs)...);
     }
   };
 
   template <typename R, typename... Args>
   Proxy<R, Args...> operator->*(R (T::*aFptr)(Args...)) const
   {
-    MOZ_ASSERT(mRawPtr != 0,
+    MOZ_ASSERT(mRawPtr != nullptr,
                "You can't dereference a NULL RefPtr with operator->*().");
     return Proxy<R, Args...>(get(), aFptr);
   }
 
   RefPtr<T>*
   get_address()
   // This is not intended to be used by clients.  See |address_of|
   // below.
@@ -350,25 +362,25 @@ public:
   {
     return this;
   }
 
 public:
   T&
   operator*() const
   {
-    MOZ_ASSERT(mRawPtr != 0,
+    MOZ_ASSERT(mRawPtr != nullptr,
                "You can't dereference a NULL RefPtr with operator*().");
     return *get();
   }
 
   T**
   StartAssignment()
   {
-    assign_assuming_AddRef(0);
+    assign_assuming_AddRef(nullptr);
     return reinterpret_cast<T**>(&mRawPtr);
   }
 private:
   // This helper class makes |RefPtr<const T>| possible by casting away
   // the constness from the pointer when calling AddRef() and Release().
   //
   // This is necessary because AddRef() and Release() implementations can't
   // generally expected to be const themselves (without heavy use of |mutable|