1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 07:17:35 +00:00

AK: Stop allowing implicit downcast with RefPtr and NonnullRefPtr

We were allowing this dangerous kind of thing:

RefPtr<Base> base;
RefPtr<Derived> derived = base;

This patch changes the {Nonnull,}RefPtr constructors so this is no
longer possible.

To downcast one of these pointers, there is now static_ptr_cast<T>:

RefPtr<Derived> derived = static_ptr_cast<Derived>(base);

Fixing this exposed a ton of cowboy-downcasts in various places,
which we're now forced to fix. :^)
This commit is contained in:
Andreas Kling 2020-04-05 11:11:07 +02:00
parent 058c614110
commit 1d468ed6d3
11 changed files with 68 additions and 54 deletions

View file

@ -71,20 +71,20 @@ public:
}
template<typename U>
RefPtr(const NonnullRefPtr<U>& other)
: m_ptr(static_cast<T*>(const_cast<U*>(other.ptr())))
: m_ptr(const_cast<U*>(other.ptr()))
{
ASSERT(m_ptr);
m_ptr->ref();
}
template<typename U>
RefPtr(NonnullRefPtr<U>&& other)
: m_ptr(static_cast<T*>(&other.leak_ref()))
: m_ptr(&other.leak_ref())
{
ASSERT(m_ptr);
}
template<typename U>
RefPtr(RefPtr<U>&& other)
: m_ptr(static_cast<T*>(other.leak_ref()))
: m_ptr(other.leak_ref())
{
}
RefPtr(const RefPtr& other)
@ -94,7 +94,7 @@ public:
}
template<typename U>
RefPtr(const RefPtr<U>& other)
: m_ptr(static_cast<T*>(const_cast<U*>(other.ptr())))
: m_ptr(const_cast<U*>(other.ptr()))
{
ref_if_not_null(m_ptr);
}
@ -282,6 +282,19 @@ struct Traits<RefPtr<T>> : public GenericTraits<RefPtr<T>> {
static bool equals(const RefPtr<T>& a, const RefPtr<T>& b) { return a.ptr() == b.ptr(); }
};
template<typename T, typename U>
inline NonnullRefPtr<T> static_ptr_cast(const NonnullRefPtr<U>& ptr)
{
return NonnullRefPtr<T>(static_cast<const T&>(*ptr));
}
template<typename T, typename U>
inline RefPtr<T> static_ptr_cast(const RefPtr<U>& ptr)
{
return RefPtr<T>(static_cast<const T*>(ptr.ptr()));
}
}
using AK::RefPtr;
using AK::static_ptr_cast;