Bug 1953243 - introduce gsl::Pointer and gsl::Owner semantic to some mfbt / xpcom types r=nika,xpcom-reviewers
The combination of [[gsl::Owner]], [[gsl::Pointer]] and [[clang::lifetimebound]] attributes makes it possible for clang to detect some basic form of lifetime issues. Those are expressed in terms of MOZ_GSL_OWNER, MOZ_GSL_POINTER and MOZ_LIFETIME_BOUND. Differential Revision: https://phabricator.services.mozilla.com/D241077
This commit is contained in:
committed by
sguelton@mozilla.com
parent
1ca99ab9ac
commit
41e238ca0a
@@ -23,7 +23,7 @@ namespace mozilla::dom::binding_detail {
|
||||
// or point at the buffer of an nsAString whose lifetime is longer than that of
|
||||
// the FakeString.
|
||||
template <typename CharT>
|
||||
struct FakeString {
|
||||
struct MOZ_GSL_OWNER FakeString {
|
||||
using char_type = CharT;
|
||||
using string_type = nsTString<CharT>;
|
||||
using size_type = typename string_type::size_type;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
namespace mozilla {
|
||||
|
||||
template <typename T, size_t _Length>
|
||||
class Array {
|
||||
class MOZ_GSL_OWNER Array {
|
||||
T mArr[_Length];
|
||||
|
||||
public:
|
||||
@@ -39,14 +39,14 @@ class Array {
|
||||
"parameter Length");
|
||||
}
|
||||
|
||||
constexpr T& operator[](size_t aIndex) {
|
||||
constexpr T& operator[](size_t aIndex) MOZ_LIFETIME_BOUND {
|
||||
if (MOZ_UNLIKELY(aIndex >= Length)) {
|
||||
detail::InvalidArrayIndex_CRASH(aIndex, Length);
|
||||
}
|
||||
return mArr[aIndex];
|
||||
}
|
||||
|
||||
constexpr const T& operator[](size_t aIndex) const {
|
||||
constexpr const T& operator[](size_t aIndex) const MOZ_LIFETIME_BOUND {
|
||||
if (MOZ_UNLIKELY(aIndex >= Length)) {
|
||||
detail::InvalidArrayIndex_CRASH(aIndex, Length);
|
||||
}
|
||||
|
||||
@@ -451,6 +451,39 @@
|
||||
# define MOZ_NO_STACK_PROTECTOR /* no support */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* MOZ_GSL_OWNER indicates that objects of the type this annotation is attached
|
||||
* to own some kind of resources, generally memory.
|
||||
*
|
||||
* See: https://clang.llvm.org/docs/AttributeReference.html#owner
|
||||
*/
|
||||
#if defined(__clang__) && defined(__has_cpp_attribute)
|
||||
# if __has_cpp_attribute(gsl::Owner)
|
||||
# define MOZ_GSL_OWNER [[gsl::Owner]]
|
||||
# else
|
||||
# define MOZ_GSL_OWNER /* nothing */
|
||||
# endif
|
||||
#else
|
||||
# define MOZ_GSL_OWNER /* nothing */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* MOZ_GSL_POINTER indicates that objects of the type this annotation is
|
||||
* attached to provide a non-owning view on some kind of resources, generally
|
||||
* memory.
|
||||
*
|
||||
* See: https://clang.llvm.org/docs/AttributeReference.html#pointer
|
||||
*/
|
||||
#if defined(__clang__) && defined(__has_cpp_attribute)
|
||||
# if __has_cpp_attribute(gsl::Pointer)
|
||||
# define MOZ_GSL_POINTER [[gsl::Pointer]]
|
||||
# else
|
||||
# define MOZ_GSL_POINTER /* nothing */
|
||||
# endif
|
||||
#else
|
||||
# define MOZ_GSL_POINTER /* nothing */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* MOZ_LIFETIME_BOUND indicates that objects that are referred to by that
|
||||
* parameter may also be referred to by the return value of the annotated
|
||||
|
||||
@@ -250,8 +250,8 @@ class JSONWriter {
|
||||
static constexpr Span<const char> scTopObjectEndString = MakeStringSpan("}");
|
||||
static constexpr Span<const char> scTrueString = MakeStringSpan("true");
|
||||
|
||||
JSONWriteFunc& mWriter;
|
||||
const UniquePtr<JSONWriteFunc> mMaybeOwnedWriter;
|
||||
JSONWriteFunc& mWriter;
|
||||
Vector<bool, 8> mNeedComma; // do we need a comma at depth N?
|
||||
Vector<bool, 8> mNeedNewlines; // do we need newlines at depth N?
|
||||
size_t mDepth; // the current nesting depth
|
||||
@@ -352,8 +352,8 @@ class JSONWriter {
|
||||
|
||||
explicit JSONWriter(UniquePtr<JSONWriteFunc> aWriter,
|
||||
CollectionStyle aStyle = MultiLineStyle)
|
||||
: mWriter(*aWriter),
|
||||
mMaybeOwnedWriter(std::move(aWriter)),
|
||||
: mMaybeOwnedWriter(std::move(aWriter)),
|
||||
mWriter(*mMaybeOwnedWriter),
|
||||
mNeedComma(),
|
||||
mNeedNewlines(),
|
||||
mDepth(0) {
|
||||
@@ -365,7 +365,7 @@ class JSONWriter {
|
||||
|
||||
// Returns the JSONWriteFunc passed in at creation, for temporary use. The
|
||||
// JSONWriter object still owns the JSONWriteFunc.
|
||||
JSONWriteFunc& WriteFunc() const { return mWriter; }
|
||||
JSONWriteFunc& WriteFunc() const MOZ_LIFETIME_BOUND { return mWriter; }
|
||||
|
||||
// For all the following functions, the "Prints:" comment indicates what the
|
||||
// basic output looks like. However, it doesn't indicate the whitespace and
|
||||
|
||||
23
mfbt/Maybe.h
23
mfbt/Maybe.h
@@ -360,7 +360,7 @@ constexpr Maybe<U> Some(T&& aValue);
|
||||
* functions |Some()| and |Nothing()|.
|
||||
*/
|
||||
template <class T>
|
||||
class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS Maybe
|
||||
class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS MOZ_GSL_OWNER Maybe
|
||||
: private detail::MaybeStorage<T>,
|
||||
public detail::Maybe_CopyMove_Enabler<T> {
|
||||
template <typename, bool, bool, bool>
|
||||
@@ -575,23 +575,24 @@ class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS Maybe
|
||||
constexpr const T* operator->() const;
|
||||
|
||||
/* Returns the contents of this Maybe<T> by ref. Unsafe unless |isSome()|. */
|
||||
constexpr T& ref() &;
|
||||
constexpr const T& ref() const&;
|
||||
constexpr T&& ref() &&;
|
||||
constexpr const T&& ref() const&&;
|
||||
constexpr T& ref() & MOZ_LIFETIME_BOUND;
|
||||
constexpr const T& ref() const& MOZ_LIFETIME_BOUND;
|
||||
constexpr T&& ref() && MOZ_LIFETIME_BOUND;
|
||||
constexpr const T&& ref() const&& MOZ_LIFETIME_BOUND;
|
||||
|
||||
/*
|
||||
* Returns the contents of this Maybe<T> by ref. If |isNothing()|, returns
|
||||
* the default value provided.
|
||||
*/
|
||||
constexpr T& refOr(T& aDefault) {
|
||||
constexpr T& refOr(T& aDefault MOZ_LIFETIME_BOUND) MOZ_LIFETIME_BOUND {
|
||||
if (isSome()) {
|
||||
return ref();
|
||||
}
|
||||
return aDefault;
|
||||
}
|
||||
|
||||
constexpr const T& refOr(const T& aDefault) const {
|
||||
constexpr const T& refOr(const T& aDefault MOZ_LIFETIME_BOUND) const
|
||||
MOZ_LIFETIME_BOUND {
|
||||
if (isSome()) {
|
||||
return ref();
|
||||
}
|
||||
@@ -618,10 +619,10 @@ class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS Maybe
|
||||
return aFunc();
|
||||
}
|
||||
|
||||
constexpr T& operator*() &;
|
||||
constexpr const T& operator*() const&;
|
||||
constexpr T&& operator*() &&;
|
||||
constexpr const T&& operator*() const&&;
|
||||
constexpr T& operator*() & MOZ_LIFETIME_BOUND;
|
||||
constexpr const T& operator*() const& MOZ_LIFETIME_BOUND;
|
||||
constexpr T&& operator*() && MOZ_LIFETIME_BOUND;
|
||||
constexpr const T&& operator*() const&& MOZ_LIFETIME_BOUND;
|
||||
|
||||
/* If |isSome()|, runs the provided function or functor on the contents of
|
||||
* this Maybe. */
|
||||
|
||||
33
mfbt/Span.h
33
mfbt/Span.h
@@ -365,7 +365,7 @@ class extent_type<dynamic_extent> {
|
||||
* Subspan etc.
|
||||
*/
|
||||
template <class ElementType, size_t Extent /* = dynamic_extent */>
|
||||
class Span {
|
||||
class MOZ_GSL_POINTER Span {
|
||||
public:
|
||||
// constants and types
|
||||
using element_type = ElementType;
|
||||
@@ -405,12 +405,14 @@ class Span {
|
||||
/**
|
||||
* Constructor for pointer and length.
|
||||
*/
|
||||
constexpr Span(pointer aPtr, index_type aLength) : storage_(aPtr, aLength) {}
|
||||
constexpr Span(pointer aPtr MOZ_LIFETIME_BOUND, index_type aLength)
|
||||
: storage_(aPtr, aLength) {}
|
||||
|
||||
/**
|
||||
* Constructor for start pointer and pointer past end.
|
||||
*/
|
||||
constexpr Span(pointer aStartPtr, pointer aEndPtr)
|
||||
constexpr Span(pointer aStartPtr MOZ_LIFETIME_BOUND,
|
||||
pointer aEndPtr MOZ_LIFETIME_BOUND)
|
||||
: storage_(aStartPtr, std::distance(aStartPtr, aEndPtr)) {}
|
||||
|
||||
/**
|
||||
@@ -438,7 +440,7 @@ class Span {
|
||||
* Constructor for C array.
|
||||
*/
|
||||
template <size_t N>
|
||||
constexpr MOZ_IMPLICIT Span(element_type (&aArr)[N])
|
||||
constexpr MOZ_IMPLICIT Span(element_type (&aArr MOZ_LIFETIME_BOUND)[N])
|
||||
: storage_(&aArr[0], span_details::extent_type<N>()) {}
|
||||
|
||||
// Implicit constructors for char* and char16_t* pointers are deleted in order
|
||||
@@ -463,7 +465,8 @@ class Span {
|
||||
*/
|
||||
template <size_t N,
|
||||
class ArrayElementType = std::remove_const_t<element_type>>
|
||||
constexpr MOZ_IMPLICIT Span(std::array<ArrayElementType, N>& aArr)
|
||||
constexpr MOZ_IMPLICIT Span(
|
||||
std::array<ArrayElementType, N>& aArr MOZ_LIFETIME_BOUND)
|
||||
: storage_(&aArr[0], span_details::extent_type<N>()) {}
|
||||
|
||||
/**
|
||||
@@ -471,7 +474,8 @@ class Span {
|
||||
*/
|
||||
template <size_t N>
|
||||
constexpr MOZ_IMPLICIT Span(
|
||||
const std::array<std::remove_const_t<element_type>, N>& aArr)
|
||||
const std::array<std::remove_const_t<element_type>, N>& aArr
|
||||
MOZ_LIFETIME_BOUND)
|
||||
: storage_(&aArr[0], span_details::extent_type<N>()) {}
|
||||
|
||||
/**
|
||||
@@ -479,7 +483,8 @@ class Span {
|
||||
*/
|
||||
template <size_t N,
|
||||
class ArrayElementType = std::remove_const_t<element_type>>
|
||||
constexpr MOZ_IMPLICIT Span(mozilla::Array<ArrayElementType, N>& aArr)
|
||||
constexpr MOZ_IMPLICIT Span(
|
||||
mozilla::Array<ArrayElementType, N>& aArr MOZ_LIFETIME_BOUND)
|
||||
: storage_(&aArr[0], span_details::extent_type<N>()) {}
|
||||
|
||||
/**
|
||||
@@ -487,7 +492,8 @@ class Span {
|
||||
*/
|
||||
template <size_t N>
|
||||
constexpr MOZ_IMPLICIT Span(
|
||||
const mozilla::Array<std::remove_const_t<element_type>, N>& aArr)
|
||||
const mozilla::Array<std::remove_const_t<element_type>, N>& aArr
|
||||
MOZ_LIFETIME_BOUND)
|
||||
: storage_(&aArr[0], span_details::extent_type<N>()) {}
|
||||
|
||||
/**
|
||||
@@ -496,15 +502,17 @@ class Span {
|
||||
template <size_t N, class Enum,
|
||||
class ArrayElementType = std::remove_const_t<element_type>>
|
||||
constexpr MOZ_IMPLICIT Span(
|
||||
mozilla::EnumeratedArray<Enum, ArrayElementType, N>& aArr)
|
||||
mozilla::EnumeratedArray<Enum, ArrayElementType, N>& aArr
|
||||
MOZ_LIFETIME_BOUND)
|
||||
: storage_(&aArr[Enum(0)], span_details::extent_type<N>()) {}
|
||||
|
||||
/**
|
||||
* Constructor for const mozilla::EnumeratedArray.
|
||||
*/
|
||||
template <size_t N, class Enum>
|
||||
constexpr MOZ_IMPLICIT Span(const mozilla::EnumeratedArray<
|
||||
Enum, std::remove_const_t<element_type>, N>& aArr)
|
||||
constexpr MOZ_IMPLICIT Span(
|
||||
const mozilla::EnumeratedArray<Enum, std::remove_const_t<element_type>,
|
||||
N>& aArr MOZ_LIFETIME_BOUND)
|
||||
: storage_(&aArr[Enum(0)], span_details::extent_type<N>()) {}
|
||||
|
||||
/**
|
||||
@@ -512,7 +520,8 @@ class Span {
|
||||
*/
|
||||
template <class ArrayElementType = std::add_pointer<element_type>,
|
||||
class DeleterType>
|
||||
constexpr Span(const mozilla::UniquePtr<ArrayElementType, DeleterType>& aPtr,
|
||||
constexpr Span(const mozilla::UniquePtr<ArrayElementType, DeleterType>& aPtr
|
||||
MOZ_LIFETIME_BOUND,
|
||||
index_type aLength)
|
||||
: storage_(aPtr.get(), aLength) {}
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ struct PointerType {
|
||||
* |UniquePtr&&| argument.
|
||||
*/
|
||||
template <typename T, class D>
|
||||
class UniquePtr {
|
||||
class MOZ_GSL_OWNER UniquePtr {
|
||||
public:
|
||||
typedef T ElementType;
|
||||
typedef D DeleterType;
|
||||
@@ -214,12 +214,13 @@ class UniquePtr {
|
||||
/**
|
||||
* Construct a UniquePtr containing |aPtr|.
|
||||
*/
|
||||
explicit UniquePtr(Pointer aPtr) : mTuple(aPtr, DeleterType()) {
|
||||
explicit UniquePtr(Pointer aPtr MOZ_LIFETIME_BOUND)
|
||||
: mTuple(aPtr, DeleterType()) {
|
||||
static_assert(!std::is_pointer_v<D>, "must provide a deleter instance");
|
||||
static_assert(!std::is_reference_v<D>, "must provide a deleter instance");
|
||||
}
|
||||
|
||||
UniquePtr(Pointer aPtr,
|
||||
UniquePtr(Pointer aPtr MOZ_LIFETIME_BOUND,
|
||||
std::conditional_t<std::is_reference_v<D>, D, const D&> aD1)
|
||||
: mTuple(aPtr, aD1) {}
|
||||
|
||||
@@ -273,21 +274,21 @@ class UniquePtr {
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::add_lvalue_reference_t<T> operator*() const {
|
||||
std::add_lvalue_reference_t<T> operator*() const MOZ_LIFETIME_BOUND {
|
||||
MOZ_ASSERT(get(), "dereferencing a UniquePtr containing nullptr with *");
|
||||
return *get();
|
||||
}
|
||||
Pointer operator->() const {
|
||||
Pointer operator->() const MOZ_LIFETIME_BOUND {
|
||||
MOZ_ASSERT(get(), "dereferencing a UniquePtr containing nullptr with ->");
|
||||
return get();
|
||||
}
|
||||
|
||||
explicit operator bool() const { return get() != nullptr; }
|
||||
|
||||
Pointer get() const { return ptr(); }
|
||||
Pointer get() const MOZ_LIFETIME_BOUND { return ptr(); }
|
||||
|
||||
DeleterType& get_deleter() { return del(); }
|
||||
const DeleterType& get_deleter() const { return del(); }
|
||||
DeleterType& get_deleter() MOZ_LIFETIME_BOUND { return del(); }
|
||||
const DeleterType& get_deleter() const MOZ_LIFETIME_BOUND { return del(); }
|
||||
|
||||
[[nodiscard]] Pointer release() {
|
||||
Pointer p = ptr();
|
||||
|
||||
@@ -567,7 +567,8 @@ struct VariantIndex {
|
||||
* instead.
|
||||
*/
|
||||
template <typename... Ts>
|
||||
class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS MOZ_NON_PARAM Variant {
|
||||
class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS
|
||||
MOZ_NON_PARAM MOZ_GSL_OWNER Variant {
|
||||
friend struct IPC::ParamTraits<mozilla::Variant<Ts...>>;
|
||||
friend struct mozilla::ipc::IPDLParamTraits<mozilla::Variant<Ts...>>;
|
||||
|
||||
@@ -739,7 +740,7 @@ class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS MOZ_NON_PARAM Variant {
|
||||
|
||||
/** Mutable lvalue-reference. */
|
||||
template <typename T>
|
||||
T& as() & {
|
||||
T& as() & MOZ_LIFETIME_BOUND {
|
||||
static_assert(
|
||||
detail::SelectVariantType<T, Ts...>::count == 1,
|
||||
"provided a type not uniquely found in this Variant's type list");
|
||||
@@ -748,7 +749,7 @@ class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS MOZ_NON_PARAM Variant {
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
typename detail::Nth<N, Ts...>::Type& as() & {
|
||||
typename detail::Nth<N, Ts...>::Type& as() & MOZ_LIFETIME_BOUND {
|
||||
static_assert(N < sizeof...(Ts),
|
||||
"provided an index outside of this Variant's type list");
|
||||
MOZ_RELEASE_ASSERT(is<N>());
|
||||
@@ -757,7 +758,7 @@ class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS MOZ_NON_PARAM Variant {
|
||||
|
||||
/** Immutable const lvalue-reference. */
|
||||
template <typename T>
|
||||
const T& as() const& {
|
||||
const T& as() const& MOZ_LIFETIME_BOUND {
|
||||
static_assert(detail::SelectVariantType<T, Ts...>::count == 1,
|
||||
"provided a type not found in this Variant's type list");
|
||||
MOZ_RELEASE_ASSERT(is<T>());
|
||||
@@ -765,7 +766,7 @@ class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS MOZ_NON_PARAM Variant {
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
const typename detail::Nth<N, Ts...>::Type& as() const& {
|
||||
const typename detail::Nth<N, Ts...>::Type& as() const& MOZ_LIFETIME_BOUND {
|
||||
static_assert(N < sizeof...(Ts),
|
||||
"provided an index outside of this Variant's type list");
|
||||
MOZ_RELEASE_ASSERT(is<N>());
|
||||
@@ -774,7 +775,7 @@ class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS MOZ_NON_PARAM Variant {
|
||||
|
||||
/** Mutable rvalue-reference. */
|
||||
template <typename T>
|
||||
T&& as() && {
|
||||
T&& as() && MOZ_LIFETIME_BOUND {
|
||||
static_assert(
|
||||
detail::SelectVariantType<T, Ts...>::count == 1,
|
||||
"provided a type not uniquely found in this Variant's type list");
|
||||
@@ -783,7 +784,7 @@ class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS MOZ_NON_PARAM Variant {
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
typename detail::Nth<N, Ts...>::Type&& as() && {
|
||||
typename detail::Nth<N, Ts...>::Type&& as() && MOZ_LIFETIME_BOUND {
|
||||
static_assert(N < sizeof...(Ts),
|
||||
"provided an index outside of this Variant's type list");
|
||||
MOZ_RELEASE_ASSERT(is<N>());
|
||||
@@ -793,7 +794,7 @@ class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS MOZ_NON_PARAM Variant {
|
||||
|
||||
/** Immutable const rvalue-reference. */
|
||||
template <typename T>
|
||||
const T&& as() const&& {
|
||||
const T&& as() const&& MOZ_LIFETIME_BOUND {
|
||||
static_assert(detail::SelectVariantType<T, Ts...>::count == 1,
|
||||
"provided a type not found in this Variant's type list");
|
||||
MOZ_RELEASE_ASSERT(is<T>());
|
||||
@@ -801,7 +802,7 @@ class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS MOZ_NON_PARAM Variant {
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
const typename detail::Nth<N, Ts...>::Type&& as() const&& {
|
||||
const typename detail::Nth<N, Ts...>::Type&& as() const&& MOZ_LIFETIME_BOUND {
|
||||
static_assert(N < sizeof...(Ts),
|
||||
"provided an index outside of this Variant's type list");
|
||||
MOZ_RELEASE_ASSERT(is<N>());
|
||||
|
||||
@@ -339,7 +339,7 @@ struct VectorTesting;
|
||||
*/
|
||||
template <typename T, size_t MinInlineCapacity = 0,
|
||||
class AllocPolicy = MallocAllocPolicy>
|
||||
class MOZ_NON_PARAM Vector final : private AllocPolicy {
|
||||
class MOZ_NON_PARAM MOZ_GSL_OWNER Vector final : private AllocPolicy {
|
||||
/* utilities */
|
||||
static constexpr bool kElemIsPod =
|
||||
std::is_trivial_v<T> && std::is_standard_layout_v<T>;
|
||||
|
||||
@@ -2742,7 +2742,8 @@ inline void ImplCycleCollectionIndexedContainer(nsTArray_Impl<E, Alloc>& aField,
|
||||
// file for more details.
|
||||
//
|
||||
template <class E>
|
||||
class nsTArray : public nsTArray_Impl<E, nsTArrayInfallibleAllocator> {
|
||||
class MOZ_GSL_OWNER nsTArray
|
||||
: public nsTArray_Impl<E, nsTArrayInfallibleAllocator> {
|
||||
public:
|
||||
using InfallibleAlloc = nsTArrayInfallibleAllocator;
|
||||
using base_type = nsTArray_Impl<E, InfallibleAlloc>;
|
||||
@@ -2963,7 +2964,7 @@ class nsTArray : public nsTArray_Impl<E, nsTArrayInfallibleAllocator> {
|
||||
};
|
||||
|
||||
template <class E>
|
||||
class CopyableTArray : public nsTArray<E> {
|
||||
class MOZ_GSL_OWNER CopyableTArray : public nsTArray<E> {
|
||||
public:
|
||||
using nsTArray<E>::nsTArray;
|
||||
|
||||
@@ -3007,7 +3008,8 @@ class CopyableTArray : public nsTArray<E> {
|
||||
// FallibleTArray is a fallible vector class.
|
||||
//
|
||||
template <class E>
|
||||
class FallibleTArray : public nsTArray_Impl<E, nsTArrayFallibleAllocator> {
|
||||
class MOZ_GSL_OWNER FallibleTArray
|
||||
: public nsTArray_Impl<E, nsTArrayFallibleAllocator> {
|
||||
public:
|
||||
typedef nsTArray_Impl<E, nsTArrayFallibleAllocator> base_type;
|
||||
typedef FallibleTArray<E> self_type;
|
||||
@@ -3040,7 +3042,7 @@ class FallibleTArray : public nsTArray_Impl<E, nsTArrayFallibleAllocator> {
|
||||
// Storing more than N elements is fine, but it will cause a heap allocation.
|
||||
//
|
||||
template <class E, size_t N>
|
||||
class MOZ_NON_MEMMOVABLE AutoTArray : public nsTArray<E> {
|
||||
class MOZ_NON_MEMMOVABLE MOZ_GSL_OWNER AutoTArray : public nsTArray<E> {
|
||||
static_assert(N != 0, "AutoTArray<E, 0> should be specialized");
|
||||
|
||||
public:
|
||||
|
||||
@@ -38,7 +38,7 @@ static_assert(sizeof(nsTLiteralString<char16_t>) == sizeof(nsTString<char16_t>),
|
||||
/**
|
||||
* A helper class that converts a UTF-16 string to ASCII in a lossy manner
|
||||
*/
|
||||
class NS_LossyConvertUTF16toASCII : public nsAutoCString {
|
||||
class MOZ_GSL_OWNER NS_LossyConvertUTF16toASCII : public nsAutoCString {
|
||||
public:
|
||||
explicit NS_LossyConvertUTF16toASCII(const char16ptr_t aString) {
|
||||
LossyAppendUTF16toASCII(mozilla::MakeStringSpan(aString), *this);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* duration of its use.
|
||||
*/
|
||||
template <typename T>
|
||||
class nsTDependentString : public nsTString<T> {
|
||||
class MOZ_GSL_POINTER nsTDependentString : public nsTString<T> {
|
||||
public:
|
||||
typedef nsTDependentString<T> self_type;
|
||||
typedef nsTString<T> base_string_type;
|
||||
@@ -57,9 +57,11 @@ class nsTDependentString : public nsTString<T> {
|
||||
* constructors
|
||||
*/
|
||||
|
||||
nsTDependentString(const char_type* aStart, const char_type* aEnd);
|
||||
nsTDependentString(const char_type* aStart MOZ_LIFETIME_BOUND,
|
||||
const char_type* aEnd MOZ_LIFETIME_BOUND);
|
||||
|
||||
nsTDependentString(const char_type* aData, size_type aLength)
|
||||
nsTDependentString(const char_type* aData MOZ_LIFETIME_BOUND,
|
||||
size_type aLength)
|
||||
: string_type(const_cast<char_type*>(aData), aLength,
|
||||
DataFlags::TERMINATED, ClassFlags(0)) {
|
||||
this->AssertValidDependentString();
|
||||
@@ -67,11 +69,11 @@ class nsTDependentString : public nsTString<T> {
|
||||
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
|
||||
nsTDependentString(char16ptr_t aData, size_type aLength)
|
||||
nsTDependentString(char16ptr_t aData MOZ_LIFETIME_BOUND, size_type aLength)
|
||||
: nsTDependentString(static_cast<const char16_t*>(aData), aLength) {}
|
||||
#endif
|
||||
|
||||
explicit nsTDependentString(const char_type* aData)
|
||||
explicit nsTDependentString(const char_type* aData MOZ_LIFETIME_BOUND)
|
||||
: string_type(const_cast<char_type*>(aData), char_traits::length(aData),
|
||||
DataFlags::TERMINATED, ClassFlags(0)) {
|
||||
string_type::AssertValidDependentString();
|
||||
@@ -79,11 +81,12 @@ class nsTDependentString : public nsTString<T> {
|
||||
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
|
||||
explicit nsTDependentString(char16ptr_t aData)
|
||||
explicit nsTDependentString(char16ptr_t aData MOZ_LIFETIME_BOUND)
|
||||
: nsTDependentString(static_cast<const char16_t*>(aData)) {}
|
||||
#endif
|
||||
|
||||
nsTDependentString(const string_type& aStr, index_type aStartPos)
|
||||
nsTDependentString(const string_type& aStr MOZ_LIFETIME_BOUND,
|
||||
index_type aStartPos)
|
||||
: string_type() {
|
||||
Rebind(aStr, aStartPos);
|
||||
}
|
||||
@@ -107,11 +110,12 @@ class nsTDependentString : public nsTString<T> {
|
||||
*/
|
||||
|
||||
using nsTString<T>::Rebind;
|
||||
void Rebind(const char_type* aData) {
|
||||
void Rebind(const char_type* aData MOZ_LIFETIME_BOUND) {
|
||||
Rebind(aData, char_traits::length(aData));
|
||||
}
|
||||
|
||||
void Rebind(const char_type* aStart, const char_type* aEnd);
|
||||
void Rebind(const char_type* aStart MOZ_LIFETIME_BOUND,
|
||||
const char_type* aEnd MOZ_LIFETIME_BOUND);
|
||||
void Rebind(const string_type&, index_type aStartPos);
|
||||
|
||||
private:
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
* nsDependentCSubstring for narrow characters
|
||||
*/
|
||||
template <typename T>
|
||||
class nsTDependentSubstring : public nsTSubstring<T> {
|
||||
class MOZ_GSL_POINTER nsTDependentSubstring : public nsTSubstring<T> {
|
||||
public:
|
||||
typedef nsTDependentSubstring<T> self_type;
|
||||
typedef nsTSubstring<T> substring_type;
|
||||
@@ -67,26 +67,30 @@ class nsTDependentSubstring : public nsTSubstring<T> {
|
||||
Rebind(aStr, aStartPos, aLength);
|
||||
}
|
||||
|
||||
nsTDependentSubstring(const char_type* aData, size_type aLength)
|
||||
nsTDependentSubstring(const char_type* aData MOZ_LIFETIME_BOUND,
|
||||
size_type aLength)
|
||||
: substring_type(const_cast<char_type*>(aData), aLength, DataFlags(0),
|
||||
ClassFlags(0)) {}
|
||||
|
||||
explicit nsTDependentSubstring(mozilla::Span<const char_type> aData)
|
||||
explicit nsTDependentSubstring(
|
||||
mozilla::Span<const char_type> aData MOZ_LIFETIME_BOUND)
|
||||
: nsTDependentSubstring(aData.Elements(), aData.Length()) {}
|
||||
|
||||
nsTDependentSubstring(const char_type* aStart, const char_type* aEnd);
|
||||
nsTDependentSubstring(const char_type* aStart MOZ_LIFETIME_BOUND,
|
||||
const char_type* aEnd MOZ_LIFETIME_BOUND);
|
||||
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
|
||||
nsTDependentSubstring(char16ptr_t aData, size_type aLength)
|
||||
nsTDependentSubstring(char16ptr_t aData MOZ_LIFETIME_BOUND, size_type aLength)
|
||||
: nsTDependentSubstring(static_cast<const char16_t*>(aData), aLength) {}
|
||||
|
||||
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
|
||||
nsTDependentSubstring(char16ptr_t aStart, char16ptr_t aEnd);
|
||||
nsTDependentSubstring(char16ptr_t aStart MOZ_LIFETIME_BOUND,
|
||||
char16ptr_t aEnd MOZ_LIFETIME_BOUND);
|
||||
#endif
|
||||
|
||||
nsTDependentSubstring(const const_iterator& aStart,
|
||||
const const_iterator& aEnd);
|
||||
nsTDependentSubstring(const const_iterator& aStart MOZ_LIFETIME_BOUND,
|
||||
const const_iterator& aEnd MOZ_LIFETIME_BOUND);
|
||||
|
||||
// Create a nsTDependentSubstring to be bound later
|
||||
nsTDependentSubstring() : substring_type() {}
|
||||
@@ -129,26 +133,28 @@ inline const nsTDependentSubstring<T> Substring(
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const nsTDependentSubstring<T> Substring(const T* aData,
|
||||
size_t aLength) {
|
||||
inline const nsTDependentSubstring<T> Substring(
|
||||
const T* aData MOZ_LIFETIME_BOUND, size_t aLength) {
|
||||
return nsTDependentSubstring<T>(aData, aLength);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const nsTDependentSubstring<T> Substring(const T* aStart, const T* aEnd);
|
||||
const nsTDependentSubstring<T> Substring(const T* aStart MOZ_LIFETIME_BOUND,
|
||||
const T* aEnd MOZ_LIFETIME_BOUND);
|
||||
|
||||
extern template const nsTDependentSubstring<char> Substring(const char* aStart,
|
||||
const char* aEnd);
|
||||
extern template const nsTDependentSubstring<char> Substring(
|
||||
const char* aStart MOZ_LIFETIME_BOUND, const char* aEnd MOZ_LIFETIME_BOUND);
|
||||
|
||||
extern template const nsTDependentSubstring<char16_t> Substring(
|
||||
const char16_t* aStart, const char16_t* aEnd);
|
||||
const char16_t* aStart MOZ_LIFETIME_BOUND,
|
||||
const char16_t* aEnd MOZ_LIFETIME_BOUND);
|
||||
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
inline const nsTDependentSubstring<char16_t> Substring(char16ptr_t aData,
|
||||
size_t aLength);
|
||||
inline const nsTDependentSubstring<char16_t> Substring(
|
||||
char16ptr_t aData MOZ_LIFETIME_BOUND, size_t aLength);
|
||||
|
||||
const nsTDependentSubstring<char16_t> Substring(char16ptr_t aStart,
|
||||
char16ptr_t aEnd);
|
||||
const nsTDependentSubstring<char16_t> Substring(
|
||||
char16ptr_t aStart MOZ_LIFETIME_BOUND, char16ptr_t aEnd MOZ_LIFETIME_BOUND);
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
@@ -158,8 +164,8 @@ inline const nsTDependentSubstring<T> StringHead(const nsTSubstring<T>& aStr,
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const nsTDependentSubstring<T> StringTail(const nsTSubstring<T>& aStr,
|
||||
size_t aCount) {
|
||||
inline const nsTDependentSubstring<T> StringTail(
|
||||
const nsTSubstring<T>& aStr MOZ_LIFETIME_BOUND, size_t aCount) {
|
||||
return nsTDependentSubstring<T>(aStr, aStr.Length() - aCount, aCount);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* to denote a null-terminated string.
|
||||
*/
|
||||
template <typename T>
|
||||
class nsTString : public nsTSubstring<T> {
|
||||
class MOZ_GSL_OWNER nsTString : public nsTSubstring<T> {
|
||||
public:
|
||||
typedef nsTString<T> self_type;
|
||||
|
||||
@@ -255,7 +255,7 @@ struct fmt::formatter<nsTString<Char>, Char>
|
||||
* nsAutoCStringN / nsTAutoCString for narrow characters
|
||||
*/
|
||||
template <typename T, size_t N>
|
||||
class MOZ_NON_MEMMOVABLE nsTAutoStringN : public nsTString<T> {
|
||||
class MOZ_NON_MEMMOVABLE MOZ_GSL_OWNER nsTAutoStringN : public nsTString<T> {
|
||||
public:
|
||||
typedef nsTAutoStringN<T, N> self_type;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user