Skip to content

Commit 2bdc476

Browse files
committed
Merge #17708: prevector: avoid misaligned member accesses
5f26855 test: Remove ubsan alignment suppressions (Wladimir J. van der Laan) 9d933ef 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 5f26855 practicalswift: ACK 5f26855 jonatack: ACK 5f26855 Tree-SHA512: 98d112d6856f683d5b212410b73f3071d2994f1efb046a2418a35890aa1cf1aa7c96a960fc2e963fa15241e861093c1ea41951cf5b4b5431f88345eb1dd0a98a
2 parents d4fc9ae + 5f26855 commit 2bdc476

File tree

2 files changed

+9
-7
lines changed

2 files changed

+9
-7
lines changed

src/prevector.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include <type_traits>
1616
#include <utility>
1717

18-
#pragma pack(push, 1)
1918
/** Implements a drop-in replacement for std::vector<T> which stores up to N
2019
* elements directly (without heap allocation). The types Size and Diff are
2120
* used to store element counts, and can be any unsigned + signed type.
@@ -147,14 +146,20 @@ class prevector {
147146
};
148147

149148
private:
150-
size_type _size = 0;
149+
#pragma pack(push, 1)
151150
union direct_or_indirect {
152151
char direct[sizeof(T) * N];
153152
struct {
154-
size_type capacity;
155153
char* indirect;
154+
size_type capacity;
156155
};
157-
} _union = {};
156+
};
157+
#pragma pack(pop)
158+
alignas(char*) direct_or_indirect _union = {};
159+
size_type _size = 0;
160+
161+
static_assert(alignof(char*) % alignof(size_type) == 0 && sizeof(char*) % alignof(size_type) == 0, "size_type cannot have more restrictive alignment requirement than pointer");
162+
static_assert(alignof(char*) % alignof(T) == 0, "value_type T cannot have more restrictive alignment requirement than pointer");
158163

159164
T* direct_ptr(difference_type pos) { return reinterpret_cast<T*>(_union.direct) + pos; }
160165
const T* direct_ptr(difference_type pos) const { return reinterpret_cast<const T*>(_union.direct) + pos; }
@@ -523,6 +528,5 @@ class prevector {
523528
return item_ptr(0);
524529
}
525530
};
526-
#pragma pack(pop)
527531

528532
#endif // BITCOIN_PREVECTOR_H

test/sanitizer_suppressions/ubsan

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# -fsanitize=undefined suppressions
22
# =================================
3-
alignment:move.h
4-
alignment:prevector.h
53
float-divide-by-zero:policy/fees.cpp
64
float-divide-by-zero:validation.cpp
75
float-divide-by-zero:wallet/wallet.cpp

0 commit comments

Comments
 (0)