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
--- 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|