mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-18 15:55:36 +00:00
Bug 1531638 - Make Vector::begin() always return a non-null pointer, to accommodate users that need/want this. r=froydnj
Differential Revision: https://phabricator.services.mozilla.com/D21825 --HG-- extra : rebase_source : 5682d209aef3c10b204678c8865758708f2a7e3e
This commit is contained in:
parent
a18b131623
commit
70e73da609
@ -403,7 +403,14 @@ class MOZ_NON_PARAM Vector final : private AllocPolicy {
|
||||
: CapacityAndReserved(aCapacity, aReserved) {}
|
||||
CRAndStorage() = default;
|
||||
|
||||
T* storage() { return nullptr; }
|
||||
T* storage() {
|
||||
// If this returns |nullptr|, functions like |Vector::begin()| would too,
|
||||
// breaking callers that pass a vector's elements as pointer/length to
|
||||
// code that bounds its operation by length but (even just as a sanity
|
||||
// check) always wants a non-null pointer. Fake up an aligned, non-null
|
||||
// pointer to support these callers.
|
||||
return reinterpret_cast<T*>(sizeof(T));
|
||||
}
|
||||
};
|
||||
|
||||
CRAndStorage<kInlineCapacity, 0> mTail;
|
||||
|
@ -506,6 +506,67 @@ static_assert(sizeof(Vector<Incomplete, 0>) ==
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
static void TestVectorBeginNonNull() {
|
||||
// Vector::begin() should never return nullptr, to accommodate callers that
|
||||
// (either for hygiene, or for semantic reasons) need a non-null pointer even
|
||||
// for zero elements.
|
||||
|
||||
Vector<bool, 0> bvec0;
|
||||
MOZ_RELEASE_ASSERT(bvec0.length() == 0);
|
||||
MOZ_RELEASE_ASSERT(bvec0.begin() != nullptr);
|
||||
|
||||
Vector<bool, 1> bvec1;
|
||||
MOZ_RELEASE_ASSERT(bvec1.length() == 0);
|
||||
MOZ_RELEASE_ASSERT(bvec1.begin() != nullptr);
|
||||
|
||||
Vector<bool, 64> bvec64;
|
||||
MOZ_RELEASE_ASSERT(bvec64.length() == 0);
|
||||
MOZ_RELEASE_ASSERT(bvec64.begin() != nullptr);
|
||||
|
||||
Vector<int, 0> ivec0;
|
||||
MOZ_RELEASE_ASSERT(ivec0.length() == 0);
|
||||
MOZ_RELEASE_ASSERT(ivec0.begin() != nullptr);
|
||||
|
||||
Vector<int, 1> ivec1;
|
||||
MOZ_RELEASE_ASSERT(ivec1.length() == 0);
|
||||
MOZ_RELEASE_ASSERT(ivec1.begin() != nullptr);
|
||||
|
||||
Vector<int, 64> ivec64;
|
||||
MOZ_RELEASE_ASSERT(ivec64.length() == 0);
|
||||
MOZ_RELEASE_ASSERT(ivec64.begin() != nullptr);
|
||||
|
||||
Vector<long, 0> lvec0;
|
||||
MOZ_RELEASE_ASSERT(lvec0.length() == 0);
|
||||
MOZ_RELEASE_ASSERT(lvec0.begin() != nullptr);
|
||||
|
||||
Vector<long, 1> lvec1;
|
||||
MOZ_RELEASE_ASSERT(lvec1.length() == 0);
|
||||
MOZ_RELEASE_ASSERT(lvec1.begin() != nullptr);
|
||||
|
||||
Vector<long, 64> lvec64;
|
||||
MOZ_RELEASE_ASSERT(lvec64.length() == 0);
|
||||
MOZ_RELEASE_ASSERT(lvec64.begin() != nullptr);
|
||||
|
||||
// Vector<T, N> doesn't guarantee N inline elements -- the actual count is
|
||||
// capped so that any Vector fits in a not-crazy amount of space -- so the
|
||||
// code below won't overflow stacks or anything crazy.
|
||||
struct VeryBig {
|
||||
int array[16 * 1024 * 1024];
|
||||
};
|
||||
|
||||
Vector<VeryBig, 0> vbvec0;
|
||||
MOZ_RELEASE_ASSERT(vbvec0.length() == 0);
|
||||
MOZ_RELEASE_ASSERT(vbvec0.begin() != nullptr);
|
||||
|
||||
Vector<VeryBig, 1> vbvec1;
|
||||
MOZ_RELEASE_ASSERT(vbvec1.length() == 0);
|
||||
MOZ_RELEASE_ASSERT(vbvec1.begin() != nullptr);
|
||||
|
||||
Vector<VeryBig, 64> vbvec64;
|
||||
MOZ_RELEASE_ASSERT(vbvec64.length() == 0);
|
||||
MOZ_RELEASE_ASSERT(vbvec64.begin() != nullptr);
|
||||
}
|
||||
|
||||
int main() {
|
||||
VectorTesting::testReserved();
|
||||
VectorTesting::testConstRange();
|
||||
@ -516,4 +577,5 @@ int main() {
|
||||
VectorTesting::testReplaceRawBuffer();
|
||||
VectorTesting::testInsert();
|
||||
VectorTesting::testPodResizeToFit();
|
||||
TestVectorBeginNonNull();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user