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
This commit is contained in:
Wladimir J. van der Laan 2020-02-12 17:48:22 +01:00 committed by pbattu
parent 4ffd42de63
commit 56a75722c9
2 changed files with 11 additions and 8 deletions

View File

@ -17,7 +17,6 @@
#include <compat.h> #include <compat.h>
#pragma pack(push, 1)
/** Implements a drop-in replacement for std::vector<T> which stores up to N /** 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 * elements directly (without heap allocation). The types Size and Diff are
* used to store element counts, and can be any unsigned + signed type. * used to store element counts, and can be any unsigned + signed type.
@ -149,14 +148,20 @@ public:
}; };
private: private:
size_type _size = 0; #pragma pack(push, 1)
union direct_or_indirect { union direct_or_indirect {
char direct[sizeof(T) * N]; char direct[sizeof(T) * N];
struct { struct {
size_type capacity;
char* indirect; 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; } 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; } const T* direct_ptr(difference_type pos) const { return reinterpret_cast<const T*>(_union.direct) + pos; }
@ -567,6 +572,4 @@ public:
} }
}; };
#pragma pack(pop)
#endif // BITCOIN_PREVECTOR_H #endif // BITCOIN_PREVECTOR_H

View File

@ -1,5 +1,5 @@
alignment:move.h # -fsanitize=undefined suppressions
alignment:prevector.h # =================================
bool:wallet/wallet.cpp bool:wallet/wallet.cpp
float-divide-by-zero:policy/fees.cpp float-divide-by-zero:policy/fees.cpp
float-divide-by-zero:validation.cpp float-divide-by-zero:validation.cpp