diff --git a/src/prevector.h b/src/prevector.h index 133930ed4b..aeaf66b265 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -17,7 +17,6 @@ #include -#pragma pack(push, 1) /** Implements a drop-in replacement for std::vector which stores up to N * elements directly (without heap allocation). The types Size and Diff are * used to store element counts, and can be any unsigned + signed type. @@ -149,14 +148,20 @@ public: }; private: - size_type _size = 0; +#pragma pack(push, 1) union direct_or_indirect { char direct[sizeof(T) * N]; struct { - size_type capacity; char* indirect; + size_type capacity; }; - } _union = {}; + }; +#pragma pack(pop) + alignas(char*) direct_or_indirect _union = {}; + size_type _size = 0; + + static_assert(alignof(char*) % alignof(size_type) == 0 && sizeof(char*) % alignof(size_type) == 0, "size_type cannot have more restrictive alignment requirement than pointer"); + static_assert(alignof(char*) % alignof(T) == 0, "value_type T cannot have more restrictive alignment requirement than pointer"); T* direct_ptr(difference_type pos) { return reinterpret_cast(_union.direct) + pos; } const T* direct_ptr(difference_type pos) const { return reinterpret_cast(_union.direct) + pos; } @@ -567,6 +572,4 @@ public: } }; -#pragma pack(pop) - #endif // BITCOIN_PREVECTOR_H diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan index d55119b266..baa213f768 100644 --- a/test/sanitizer_suppressions/ubsan +++ b/test/sanitizer_suppressions/ubsan @@ -1,5 +1,5 @@ -alignment:move.h -alignment:prevector.h +# -fsanitize=undefined suppressions +# ================================= bool:wallet/wallet.cpp float-divide-by-zero:policy/fees.cpp float-divide-by-zero:validation.cpp