Skip to content

Commit a67cc55

Browse files
committed
Merge branch 'gh47926-safe-arith' into exp-csv-fuzz-safe-arith
2 parents a5fa5ee + 342a945 commit a67cc55

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

cpp/src/arrow/util/int_util_overflow.h

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
namespace arrow {
3131
namespace internal {
3232

33-
// static inline bool check_add_int32_int32(int32_t a, int32_t b, int32_t* ret)
34-
3533
// Define functions AddWithOverflow, SubtractWithOverflow, MultiplyWithOverflow
3634
// with the signature `bool(T u, T v, T* out)` where T is an integer type.
3735
// On overflow, these functions return true. Otherwise, false is returned
@@ -63,46 +61,69 @@ using transformed_int_t =
6361
template <typename Int>
6462
using upscaled_int32_t = transformed_int_t<Int, int32_t, uint32_t>;
6563

66-
// TODO use builtins on clang/gcc
64+
// Use GCC/CLang builtins for checked arithmetic, promising better performance
65+
// than SafeInt's hand-written implementations.
66+
#if defined __has_builtin
67+
# if __has_builtin(__builtin_object_size)
68+
# define USE_CHECKED_ARITHMETIC_BUILTINS 1
69+
# else
70+
# define USE_CHECKED_ARITHMETIC_BUILTINS 0
71+
# endif
72+
#endif
6773

6874
template <typename Int>
6975
[[nodiscard]] bool AddWithOverflowGeneric(Int u, Int v, Int* out) {
76+
#if USE_CHECKED_ARITHMETIC_BUILTINS
77+
return __builtin_add_overflow(u, v, out);
78+
#else
7079
if constexpr (sizeof(Int) < 4) {
7180
auto r =
72-
static_cast<upscaled_int32_t<Int>>(u) + static_cast<upscaled_int32_t<Int>>(v);
81+
static_cast<upscaled_int32_t<Int> >(u) + static_cast<upscaled_int32_t<Int> >(v);
7382
*out = static_cast<Int>(r);
7483
return r != *out;
7584
} else {
7685
return SafeIntAddWithOverflow(u, v, out);
7786
}
87+
#endif
7888
}
7989

8090
template <typename Int>
8191
[[nodiscard]] bool SubtractWithOverflowGeneric(Int u, Int v, Int* out) {
92+
#if USE_CHECKED_ARITHMETIC_BUILTINS
93+
return __builtin_sub_overflow(u, v, out);
94+
#else
8295
if constexpr (sizeof(Int) < 4) {
8396
auto r =
84-
static_cast<upscaled_int32_t<Int>>(u) - static_cast<upscaled_int32_t<Int>>(v);
97+
static_cast<upscaled_int32_t<Int> >(u) - static_cast<upscaled_int32_t<Int> >(v);
8598
*out = static_cast<Int>(r);
8699
return r != *out;
87100
} else {
88101
return SafeIntSubtractWithOverflow(u, v, out);
89102
}
103+
#endif
90104
}
91105

92106
template <typename Int>
93107
[[nodiscard]] bool MultiplyWithOverflowGeneric(Int u, Int v, Int* out) {
108+
#if USE_CHECKED_ARITHMETIC_BUILTINS
109+
return __builtin_mul_overflow(u, v, out);
110+
#else
94111
if constexpr (sizeof(Int) < 4) {
95112
auto r =
96-
static_cast<upscaled_int32_t<Int>>(u) * static_cast<upscaled_int32_t<Int>>(v);
113+
static_cast<upscaled_int32_t<Int> >(u) * static_cast<upscaled_int32_t<Int> >(v);
97114
*out = static_cast<Int>(r);
98115
return r != *out;
99116
} else {
100117
return SafeIntMultiplyWithOverflow(u, v, out);
101118
}
119+
#endif
102120
}
103121

104122
template <typename Int>
105123
[[nodiscard]] bool DivideWithOverflowGeneric(Int u, Int v, Int* out) {
124+
if (v == 0) {
125+
return true;
126+
}
106127
if constexpr (sizeof(Int) < 4) {
107128
using UpscaledInt = upscaled_int32_t<Int>;
108129
UpscaledInt r;

cpp/src/arrow/vendored/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ add_subdirectory(datetime)
2121
add_subdirectory(double-conversion)
2222
add_subdirectory(pcg)
2323
add_subdirectory(portable-snippets)
24+
add_subdirectory(safeint)
2425
add_subdirectory(xxhash)

0 commit comments

Comments
 (0)