Skip to content

Commit

Permalink
Avoid potential UB from an unused invalid pointer address.
Browse files Browse the repository at this point in the history
This primarily happens when doing big jumps through a 2D array; regular pointer
arithmetic on a 1D array should be safe as they never need to do these jumps.
  • Loading branch information
LTLA committed Jul 21, 2024
1 parent bb737eb commit 694be04
Showing 1 changed file with 10 additions and 7 deletions.
17 changes: 10 additions & 7 deletions include/tatami/dense/transpose.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,18 @@ void transpose(const Input_* input, size_t nrow, size_t ncol, size_t input_strid
while (row_start < nrow) {
size_t row_end = row_start + std::min(block, nrow - row_start);

auto input2 = input + col_start + row_start * input_stride;
auto output2 = output + col_start * output_stride + row_start;
// We use offsets instead of directly performing pointer
// arithmetic, to avoid creating an invalid pointer address (which
// is UB, even if unused) after the last inner loop iteration.
size_t input_offset = col_start + row_start * input_stride;
size_t output_offset = col_start * output_stride + row_start;

for (size_t c = col_start; c < col_end; ++c, ++input2, output2 += output_stride) {
auto input_copy = input2;
auto output_copy = output2;
for (size_t c = col_start; c < col_end; ++c, ++input_offset, output_offset += output_stride) {
auto input_offset_copy = input_offset;
auto output_offset_copy = output_offset;

for (size_t r = row_start; r < row_end; ++r, input_copy += input_stride, ++output_copy) {
*output_copy = *input_copy;
for (size_t r = row_start; r < row_end; ++r, input_offset_copy += input_stride, ++output_offset_copy) {
output[output_offset_copy] = input[input_offset_copy];
}
}

Expand Down

0 comments on commit 694be04

Please sign in to comment.