diff options
author | Wladimir J. van der Laan <laanwj@protonmail.com> | 2020-02-12 17:48:22 +0100 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@protonmail.com> | 2020-02-12 17:48:30 +0100 |
commit | 2bdc476d4d23256d8396bb9051a511f540d87392 (patch) | |
tree | 0c53a9b7c3b0522801db923d85c52876f3940f40 | |
parent | d4fc9aeb8b6a66d8d40ab93547c8b1390458d638 (diff) | |
parent | 5f26855f109af53a336d5f98ed0ae584e7a31f84 (diff) |
Merge #17708: prevector: avoid misaligned member accesses
5f26855f109af53a336d5f98ed0ae584e7a31f84 test: Remove ubsan alignment suppressions (Wladimir J. van der Laan)
9d933ef9191417b4b7d29eaa3c3a571f814acc8e prevector: avoid misaligned member accesses (Anthony Towns)
Pull request description:
Ensure prevector data is appropriately aligned. Earlier discussion in #17530.
**Edit laanwj**: In contrast to #17530, it does this without increase in size of any of the coin cache data structures (x86_64, clang)
| Struct | (size,align) before | (size,align) after |
| ------------- | ------------- | ------- |
| Coin | 48, 8 | 48, 8 |
| CCoinsCacheEntry | 56, 8 | 56, 8 |
| CScript | 32, 1 | 32, 8 |
ACKs for top commit:
laanwj:
ACK 5f26855f109af53a336d5f98ed0ae584e7a31f84
practicalswift:
ACK 5f26855f109af53a336d5f98ed0ae584e7a31f84
jonatack:
ACK 5f26855f109af53a336d5f98ed0ae584e7a31f84
Tree-SHA512: 98d112d6856f683d5b212410b73f3071d2994f1efb046a2418a35890aa1cf1aa7c96a960fc2e963fa15241e861093c1ea41951cf5b4b5431f88345eb1dd0a98a
-rw-r--r-- | src/prevector.h | 14 | ||||
-rw-r--r-- | test/sanitizer_suppressions/ubsan | 2 |
2 files changed, 9 insertions, 7 deletions
diff --git a/src/prevector.h b/src/prevector.h index f4ece738a8..09debedc4f 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -15,7 +15,6 @@ #include <type_traits> #include <utility> -#pragma pack(push, 1) /** Implements a drop-in replacement for std::vector<T> 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. @@ -147,14 +146,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<T*>(_union.direct) + pos; } const T* direct_ptr(difference_type pos) const { return reinterpret_cast<const T*>(_union.direct) + pos; } @@ -523,6 +528,5 @@ public: return item_ptr(0); } }; -#pragma pack(pop) #endif // BITCOIN_PREVECTOR_H diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan index 098dd29260..b3d9b9e6ec 100644 --- a/test/sanitizer_suppressions/ubsan +++ b/test/sanitizer_suppressions/ubsan @@ -1,7 +1,5 @@ # -fsanitize=undefined suppressions # ================================= -alignment:move.h -alignment:prevector.h float-divide-by-zero:policy/fees.cpp float-divide-by-zero:validation.cpp float-divide-by-zero:wallet/wallet.cpp |