mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Bug 1414901 - part 2 - poison Maybe<T> instances when not in use; r=Waldo
This commit is contained in:
parent
2ac6e45b48
commit
2bd0c8e0a2
47
mfbt/Maybe.h
47
mfbt/Maybe.h
@ -12,8 +12,10 @@
|
||||
#include "mozilla/Alignment.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/MemoryChecking.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/OperatorNewExtensions.h"
|
||||
#include "mozilla/Poison.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include <new> // for placement new
|
||||
@ -24,6 +26,27 @@ namespace mozilla {
|
||||
|
||||
struct Nothing { };
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct MaybePoisoner
|
||||
{
|
||||
static const size_t N = sizeof(T);
|
||||
|
||||
static void poison(void* aPtr)
|
||||
{
|
||||
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
// Avoid MOZ_ASSERT in mozWritePoison.
|
||||
if (N >= sizeof(uintptr_t)) {
|
||||
mozWritePoison(aPtr, N);
|
||||
}
|
||||
#endif
|
||||
MOZ_MAKE_MEM_UNDEFINED(aPtr, N);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/*
|
||||
* Maybe is a container class which contains either zero or one elements. It
|
||||
* serves two roles. It can represent values which are *semantically* optional,
|
||||
@ -93,19 +116,32 @@ class MOZ_NON_PARAM MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS Maybe
|
||||
void* data() { return mStorage; }
|
||||
const void* data() const { return mStorage; }
|
||||
|
||||
void poisonData()
|
||||
{
|
||||
detail::MaybePoisoner<T>::poison(data());
|
||||
}
|
||||
|
||||
public:
|
||||
using ValueType = T;
|
||||
|
||||
Maybe() : mIsSome(false) { }
|
||||
Maybe() : mIsSome(false)
|
||||
{
|
||||
poisonData();
|
||||
}
|
||||
~Maybe() { reset(); }
|
||||
|
||||
MOZ_IMPLICIT Maybe(Nothing) : mIsSome(false) { }
|
||||
MOZ_IMPLICIT Maybe(Nothing) : mIsSome(false)
|
||||
{
|
||||
poisonData();
|
||||
}
|
||||
|
||||
Maybe(const Maybe& aOther)
|
||||
: mIsSome(false)
|
||||
{
|
||||
if (aOther.mIsSome) {
|
||||
emplace(*aOther);
|
||||
} else {
|
||||
poisonData();
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,6 +157,8 @@ public:
|
||||
{
|
||||
if (aOther.isSome()) {
|
||||
emplace(*aOther);
|
||||
} else {
|
||||
poisonData();
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,6 +168,8 @@ public:
|
||||
if (aOther.mIsSome) {
|
||||
emplace(Move(*aOther));
|
||||
aOther.reset();
|
||||
} else {
|
||||
poisonData();
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,6 +186,8 @@ public:
|
||||
if (aOther.isSome()) {
|
||||
emplace(Move(*aOther));
|
||||
aOther.reset();
|
||||
} else {
|
||||
poisonData();
|
||||
}
|
||||
}
|
||||
|
||||
@ -445,6 +487,7 @@ public:
|
||||
if (isSome()) {
|
||||
ref().T::~T();
|
||||
mIsSome = false;
|
||||
poisonData();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user