Skip to content

Commit

Permalink
Merge pull request #4451 from pravblockc/backports-v0.20-pr1
Browse files Browse the repository at this point in the history
Merge bitcoin#17708: prevector: avoid misaligned member accesses
  • Loading branch information
UdjinM6 committed Sep 28, 2021
2 parents 80cf742 + 3063d17 commit d9c523e
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/bls/bls.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class CBLSWrapper
friend class CBLSPublicKey;
friend class CBLSSignature;

bool fLegacy;
bool fLegacy{true};

protected:
ImplType impl;
Expand Down
19 changes: 12 additions & 7 deletions src/prevector.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

#include <compat.h>

#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.
Expand Down Expand Up @@ -149,14 +148,20 @@ class prevector {
};

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; }
Expand Down Expand Up @@ -560,13 +565,13 @@ class prevector {
if (v.size() != s) {
v.resize(s);
}
::memmove(v.data(), &*b, s);
if (!v.empty()) {
::memmove(v.data(), &*b, s);
}
} else {
v.assign(&*b, &*e);
}
}
};

#pragma pack(pop)

#endif // BITCOIN_PREVECTOR_H
4 changes: 2 additions & 2 deletions test/sanitizer_suppressions/ubsan
Original file line number Diff line number Diff line change
@@ -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
Expand Down

0 comments on commit d9c523e

Please sign in to comment.