Skip to content

Commit 9ca7395

Browse files
authored
Merge pull request ClickHouse#80145 from ClickHouse/fix-podarray-null-alignment
Fix UBSan failure on non-aligned PODArray null pointer
2 parents 07bf38d + 340ce2f commit 9ca7395

File tree

2 files changed

+5
-3
lines changed

2 files changed

+5
-3
lines changed

src/Common/PODArray.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ ALWAYS_INLINE size_t minimum_memory_for_elements(size_t num_elements, size_t ele
4242

4343

4444
/// Used for left padding of PODArray when empty
45-
const char empty_pod_array[empty_pod_array_size]{};
45+
alignas(std::max_align_t) const char empty_pod_array[empty_pod_array_size]{};
4646

4747
template class PODArray<UInt8, 4096, Allocator<false>, PADDING_FOR_SIMD - 1, PADDING_FOR_SIMD>;
4848
template class PODArray<UInt16, 4096, Allocator<false>, PADDING_FOR_SIMD - 1, PADDING_FOR_SIMD>;

src/Common/PODArray.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <cstddef>
1616
#include <cstdlib>
1717
#include <cstring>
18+
#include <numeric>
1819

1920
#ifndef NDEBUG
2021
#include <sys/mman.h>
@@ -67,7 +68,7 @@ namespace DB
6768
* TODO Allow greater alignment than alignof(T). Example: array of char aligned to page size.
6869
*/
6970
static constexpr size_t empty_pod_array_size = 1024;
70-
extern const char empty_pod_array[empty_pod_array_size];
71+
alignas(std::max_align_t) extern const char empty_pod_array[empty_pod_array_size];
7172

7273
namespace PODArrayDetails
7374
{
@@ -92,11 +93,12 @@ class PODArrayBase : private boost::noncopyable, private TAllocator /// empty
9293
/// Round padding up to an whole number of elements to simplify arithmetic.
9394
static constexpr size_t pad_right = integerRoundUp(pad_right_, ELEMENT_SIZE);
9495
/// pad_left is also rounded up to 16 bytes to maintain alignment of allocated memory.
95-
static constexpr size_t pad_left = integerRoundUp(integerRoundUp(pad_left_, ELEMENT_SIZE), 16);
96+
static constexpr size_t pad_left = integerRoundUp(pad_left_, std::lcm(ELEMENT_SIZE, 16));
9697
/// Empty array will point to this static memory as padding and begin/end.
9798
static constexpr char * null = const_cast<char *>(empty_pod_array) + pad_left;
9899

99100
static_assert(pad_left <= empty_pod_array_size && "Left Padding exceeds empty_pod_array_size. Is the element size too large?");
101+
static_assert(pad_left % ELEMENT_SIZE == 0, "pad_left must be multiple of element alignment");
100102

101103
// If we are using allocator with inline memory, the minimal size of
102104
// array must be in sync with the size of this memory.

0 commit comments

Comments
 (0)