mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
Bug 558410 - silence strict aliasing warnings (r=jorendorff)
--HG-- extra : rebase_source : c6cad8a5461e685f31f5959aa69635be57c807d4
This commit is contained in:
parent
04a7e441fc
commit
ee07742078
@ -249,6 +249,28 @@ class SystemAllocPolicy
|
||||
void reportAllocOverflow() const {}
|
||||
};
|
||||
|
||||
/*
|
||||
* This utility pales in comparison to Boost's aligned_storage. The utility
|
||||
* simply assumes that uint64_t is enough alignment for anyone. This may need
|
||||
* to be extended one day...
|
||||
*
|
||||
* As an important side effect, pulling the storage into this template is
|
||||
* enough obfuscation to confuse gcc's strict-aliasing analysis into not giving
|
||||
* false negatives when we cast from the char buffer to whatever type we've
|
||||
* constructed using the bytes.
|
||||
*/
|
||||
template <size_t nbytes>
|
||||
struct AlignedStorage
|
||||
{
|
||||
union U {
|
||||
char bytes[nbytes];
|
||||
uint64_t _;
|
||||
} u;
|
||||
|
||||
const void *addr() const { return u.bytes; }
|
||||
void *addr() { return u.bytes; }
|
||||
};
|
||||
|
||||
/*
|
||||
* Small utility for lazily constructing objects without using dynamic storage.
|
||||
* When a LazilyConstructed<T> is constructed, it is |empty()|, i.e., no value
|
||||
@ -260,45 +282,42 @@ class SystemAllocPolicy
|
||||
template <class T>
|
||||
class LazilyConstructed
|
||||
{
|
||||
union {
|
||||
uint64 align;
|
||||
char bytes[sizeof(T) + 1];
|
||||
};
|
||||
AlignedStorage<sizeof(T)> storage;
|
||||
bool constructed;
|
||||
|
||||
T &asT() { return *reinterpret_cast<T *>(bytes); }
|
||||
char & constructed() { return bytes[sizeof(T)]; }
|
||||
T &asT() { return *reinterpret_cast<T *>(storage.addr()); }
|
||||
|
||||
public:
|
||||
LazilyConstructed() { constructed() = false; }
|
||||
~LazilyConstructed() { if (constructed()) asT().~T(); }
|
||||
LazilyConstructed() { constructed = false; }
|
||||
~LazilyConstructed() { if (constructed) asT().~T(); }
|
||||
|
||||
bool empty() const { return !constructed(); }
|
||||
bool empty() const { return !constructed; }
|
||||
|
||||
void construct() {
|
||||
JS_ASSERT(!constructed());
|
||||
new(bytes) T();
|
||||
constructed() = true;
|
||||
JS_ASSERT(!constructed);
|
||||
new(storage.addr()) T();
|
||||
constructed = true;
|
||||
}
|
||||
|
||||
template <class T1>
|
||||
void construct(const T1 &t1) {
|
||||
JS_ASSERT(!constructed());
|
||||
new(bytes) T(t1);
|
||||
constructed() = true;
|
||||
JS_ASSERT(!constructed);
|
||||
new(storage.addr()) T(t1);
|
||||
constructed = true;
|
||||
}
|
||||
|
||||
template <class T1, class T2>
|
||||
void construct(const T1 &t1, const T2 &t2) {
|
||||
JS_ASSERT(!constructed());
|
||||
new(bytes) T(t1, t2);
|
||||
constructed() = true;
|
||||
JS_ASSERT(!constructed);
|
||||
new(storage.addr()) T(t1, t2);
|
||||
constructed = true;
|
||||
}
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
void construct(const T1 &t1, const T2 &t2, const T3 &t3) {
|
||||
JS_ASSERT(!constructed());
|
||||
new(bytes) T(t1, t2, t3);
|
||||
constructed() = true;
|
||||
JS_ASSERT(!constructed);
|
||||
new(storage.addr()) T(t1, t2, t3);
|
||||
constructed = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -208,7 +208,7 @@ class Vector : AllocPolicy
|
||||
/*
|
||||
* Since a vector either stores elements inline or in a heap-allocated
|
||||
* buffer, reuse the storage. mLengthOrCapacity serves as the union
|
||||
* discriminator. In inline mode (when elements are stored in u.mBuf),
|
||||
* discriminator. In inline mode (when elements are stored in u.storage),
|
||||
* mLengthOrCapacity holds the vector's length. In heap mode (when elements
|
||||
* are stored in [u.ptrs.mBegin, u.ptrs.mEnd)), mLengthOrCapacity holds the
|
||||
* vector's capacity.
|
||||
@ -228,22 +228,7 @@ class Vector : AllocPolicy
|
||||
|
||||
union {
|
||||
BufferPtrs ptrs;
|
||||
char mBuf[sInlineBytes];
|
||||
|
||||
#if __GNUC__
|
||||
/*
|
||||
* GCC thinks there is a strict aliasing warning since mBuf is a char
|
||||
* array but we read and write to it as a T array. This is not an error
|
||||
* since there are no reads and writes to the mBuf memory except those
|
||||
* that treat it as a T array. Sadly,
|
||||
* #pragma GCC diagnostic ignore "-Wstrict-aliasing"
|
||||
* doesn't silence the warning. Type punning is allowed through a union
|
||||
* of the involved types, so, for now, this error can be silenced by
|
||||
* adding each offending T to this union. (This won't work for non-POD
|
||||
* T's, but there don't seem to be any with warnings yet...)
|
||||
*/
|
||||
jschar unused1_;
|
||||
#endif
|
||||
AlignedStorage<sInlineBytes> storage;
|
||||
} u;
|
||||
|
||||
/* Only valid when usingInlineStorage() */
|
||||
@ -259,12 +244,12 @@ class Vector : AllocPolicy
|
||||
|
||||
T *inlineBegin() const {
|
||||
JS_ASSERT(usingInlineStorage());
|
||||
return (T *)u.mBuf;
|
||||
return (T *)u.storage.addr();
|
||||
}
|
||||
|
||||
T *inlineEnd() const {
|
||||
JS_ASSERT(usingInlineStorage());
|
||||
return (T *)u.mBuf + mLengthOrCapacity;
|
||||
return (T *)u.storage.addr() + mLengthOrCapacity;
|
||||
}
|
||||
|
||||
/* Only valid when !usingInlineStorage() */
|
||||
|
Loading…
Reference in New Issue
Block a user