Bug 1010756 - Helpful errors for using nsCOMPtr on non-XPCOM types; r=froydnj

This commit is contained in:
Aryeh Gregor 2015-08-12 18:43:10 +03:00
parent fbabfccef9
commit eb2a6135d7
2 changed files with 29 additions and 1 deletions

View File

@ -199,7 +199,6 @@ SmsRequestChild::Recv__delete__(const MessageReply& aReply)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mReplyRequest);
nsCOMPtr<SmsMessage> message;
switch(aReply.type()) {
case MessageReply::TReplyMessageSend: {
const MobileMessageData& data =

View File

@ -339,6 +339,12 @@ protected:
// template<class T> class nsGetterAddRefs;
// Helper for assert_validity method
template<class T>
char (&TestForIID(decltype(&NS_GET_TEMPLATE_IID(T))))[2];
template<class T>
char TestForIID(...);
template<class T>
class nsCOMPtr final
#ifdef NSCAP_FEATURE_USE_BASE
@ -379,6 +385,15 @@ private:
T* MOZ_OWNING_REF mRawPtr;
#endif
void assert_validity()
{
static_assert(1 < sizeof(TestForIID<T>(nullptr)), "nsCOMPtr only works "
"for types with IIDs. Either use nsRefPtr; add an IID to "
"your type with NS_DECLARE_STATIC_IID_ACCESSOR/"
"NS_DEFINE_STATIC_IID_ACCESSOR; or make the nsCOMPtr point "
"to a base class with an IID.");
}
public:
typedef T element_type;
@ -412,12 +427,14 @@ public:
nsCOMPtr()
: NSCAP_CTOR_BASE(0)
{
assert_validity();
NSCAP_LOG_ASSIGNMENT(this, 0);
}
nsCOMPtr(const nsCOMPtr<T>& aSmartPtr)
: NSCAP_CTOR_BASE(aSmartPtr.mRawPtr)
{
assert_validity();
if (mRawPtr) {
NSCAP_ADDREF(this, mRawPtr);
}
@ -427,6 +444,7 @@ public:
MOZ_IMPLICIT nsCOMPtr(T* aRawPtr)
: NSCAP_CTOR_BASE(aRawPtr)
{
assert_validity();
if (mRawPtr) {
NSCAP_ADDREF(this, mRawPtr);
}
@ -437,6 +455,7 @@ public:
MOZ_IMPLICIT nsCOMPtr(already_AddRefed<T>& aSmartPtr)
: NSCAP_CTOR_BASE(aSmartPtr.take())
{
assert_validity();
NSCAP_LOG_ASSIGNMENT(this, mRawPtr);
NSCAP_ASSERT_NO_QUERY_NEEDED();
}
@ -445,6 +464,7 @@ public:
MOZ_IMPLICIT nsCOMPtr(already_AddRefed<T>&& aSmartPtr)
: NSCAP_CTOR_BASE(aSmartPtr.take())
{
assert_validity();
NSCAP_LOG_ASSIGNMENT(this, mRawPtr);
NSCAP_ASSERT_NO_QUERY_NEEDED();
}
@ -454,6 +474,7 @@ public:
MOZ_IMPLICIT nsCOMPtr(already_AddRefed<U>& aSmartPtr)
: NSCAP_CTOR_BASE(static_cast<T*>(aSmartPtr.take()))
{
assert_validity();
// But make sure that U actually inherits from T.
static_assert(mozilla::IsBaseOf<T, U>::value,
"U is not a subclass of T");
@ -466,6 +487,7 @@ public:
MOZ_IMPLICIT nsCOMPtr(already_AddRefed<U>&& aSmartPtr)
: NSCAP_CTOR_BASE(static_cast<T*>(aSmartPtr.take()))
{
assert_validity();
// But make sure that U actually inherits from T.
static_assert(mozilla::IsBaseOf<T, U>::value,
"U is not a subclass of T");
@ -477,6 +499,7 @@ public:
MOZ_IMPLICIT nsCOMPtr(const nsQueryInterface aQI)
: NSCAP_CTOR_BASE(0)
{
assert_validity();
NSCAP_LOG_ASSIGNMENT(this, 0);
assign_from_qi(aQI, NS_GET_TEMPLATE_IID(T));
}
@ -485,6 +508,7 @@ public:
MOZ_IMPLICIT nsCOMPtr(const nsQueryInterfaceWithError& aQI)
: NSCAP_CTOR_BASE(0)
{
assert_validity();
NSCAP_LOG_ASSIGNMENT(this, 0);
assign_from_qi_with_error(aQI, NS_GET_TEMPLATE_IID(T));
}
@ -493,6 +517,7 @@ public:
MOZ_IMPLICIT nsCOMPtr(const nsGetServiceByCID aGS)
: NSCAP_CTOR_BASE(0)
{
assert_validity();
NSCAP_LOG_ASSIGNMENT(this, 0);
assign_from_gs_cid(aGS, NS_GET_TEMPLATE_IID(T));
}
@ -501,6 +526,7 @@ public:
MOZ_IMPLICIT nsCOMPtr(const nsGetServiceByCIDWithError& aGS)
: NSCAP_CTOR_BASE(0)
{
assert_validity();
NSCAP_LOG_ASSIGNMENT(this, 0);
assign_from_gs_cid_with_error(aGS, NS_GET_TEMPLATE_IID(T));
}
@ -509,6 +535,7 @@ public:
MOZ_IMPLICIT nsCOMPtr(const nsGetServiceByContractID aGS)
: NSCAP_CTOR_BASE(0)
{
assert_validity();
NSCAP_LOG_ASSIGNMENT(this, 0);
assign_from_gs_contractid(aGS, NS_GET_TEMPLATE_IID(T));
}
@ -517,6 +544,7 @@ public:
MOZ_IMPLICIT nsCOMPtr(const nsGetServiceByContractIDWithError& aGS)
: NSCAP_CTOR_BASE(0)
{
assert_validity();
NSCAP_LOG_ASSIGNMENT(this, 0);
assign_from_gs_contractid_with_error(aGS, NS_GET_TEMPLATE_IID(T));
}
@ -526,6 +554,7 @@ public:
MOZ_IMPLICIT nsCOMPtr(const nsCOMPtr_helper& aHelper)
: NSCAP_CTOR_BASE(0)
{
assert_validity();
NSCAP_LOG_ASSIGNMENT(this, 0);
assign_from_helper(aHelper, NS_GET_TEMPLATE_IID(T));
NSCAP_ASSERT_NO_QUERY_NEEDED();