Skip to content

Commit aeb6486

Browse files
authored
GH-48339: [C++] Enhance functions in util/ubsan.h to support types without a default constructor (#48429)
### Rationale for this change `arrow::util::SafeLoadAs`, `arrow::util::SafeLoad`, and `arrow::util::SafeCopy` do not work correctly for types that do not have a default constructor. ### What changes are included in this PR? Changed the behavior of the above-mentioned functions to support types that do not have a default constructor. ### Are these changes tested? Yes. ### Are there any user-facing changes? No. * GitHub Issue: #48339 Authored-by: arash andishgar <[email protected]> Signed-off-by: Antoine Pitrou <[email protected]>
1 parent d09233a commit aeb6486

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

cpp/src/arrow/util/ubsan.h

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <memory>
2424
#include <type_traits>
2525

26+
#include "arrow/util/aligned_storage.h"
2627
#include "arrow/util/macros.h"
2728

2829
namespace arrow {
@@ -55,26 +56,35 @@ inline T* MakeNonNull(T* maybe_null = NULLPTR) {
5556
template <typename T>
5657
inline std::enable_if_t<std::is_trivially_copyable_v<T>, T> SafeLoadAs(
5758
const uint8_t* unaligned) {
58-
std::remove_const_t<T> ret;
59-
std::memcpy(&ret, unaligned, sizeof(T));
60-
return ret;
59+
using Type = std::remove_const_t<T>;
60+
arrow::internal::AlignedStorage<Type> raw_data;
61+
std::memcpy(raw_data.get(), unaligned, sizeof(T));
62+
auto data = *raw_data.get();
63+
raw_data.destroy();
64+
return data;
6165
}
6266

6367
template <typename T>
6468
inline std::enable_if_t<std::is_trivially_copyable_v<T>, T> SafeLoad(const T* unaligned) {
65-
std::remove_const_t<T> ret;
66-
std::memcpy(&ret, static_cast<const void*>(unaligned), sizeof(T));
67-
return ret;
69+
using Type = std::remove_const_t<T>;
70+
arrow::internal::AlignedStorage<Type> raw_data;
71+
std::memcpy(raw_data.get(), static_cast<const void*>(unaligned), sizeof(T));
72+
auto data = *raw_data.get();
73+
raw_data.destroy();
74+
return data;
6875
}
6976

7077
template <typename U, typename T>
7178
inline std::enable_if_t<std::is_trivially_copyable_v<T> &&
7279
std::is_trivially_copyable_v<U> && sizeof(T) == sizeof(U),
7380
U>
7481
SafeCopy(T value) {
75-
std::remove_const_t<U> ret;
76-
std::memcpy(&ret, static_cast<const void*>(&value), sizeof(T));
77-
return ret;
82+
using TypeU = std::remove_const_t<U>;
83+
arrow::internal::AlignedStorage<TypeU> raw_data;
84+
std::memcpy(raw_data.get(), static_cast<const void*>(&value), sizeof(T));
85+
auto data = *raw_data.get();
86+
raw_data.destroy();
87+
return data;
7888
}
7989

8090
template <typename T>

0 commit comments

Comments
 (0)