Skip to content

Commit e6977cc

Browse files
committed
perf: use builtin unsigned long overflow check
1 parent 132342b commit e6977cc

File tree

2 files changed

+18
-9
lines changed

2 files changed

+18
-9
lines changed

pandas/_libs/include/pandas/portable.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,18 @@ The full license is in the LICENSE file, distributed with this software.
4444
#define checked_int64_add(a, b, res) LongLongAdd(a, b, res)
4545
#define checked_int64_sub(a, b, res) LongLongSub(a, b, res)
4646
#define checked_int64_mul(a, b, res) LongLongMult(a, b, res)
47+
#define checked_uint64_add(a, b, res) ULongLongAdd(a, b, res)
48+
#define checked_uint64_sub(a, b, res) ULongLongSub(a, b, res)
49+
#define checked_uint64_mul(a, b, res) ULongLongMult(a, b, res)
4750
#else
4851
#if defined __has_builtin
4952
#if __has_builtin(__builtin_add_overflow)
5053
#define checked_int64_add(a, b, res) __builtin_add_overflow(a, b, res)
5154
#define checked_int64_sub(a, b, res) __builtin_sub_overflow(a, b, res)
5255
#define checked_int64_mul(a, b, res) __builtin_mul_overflow(a, b, res)
56+
#define checked_uint64_add(a, b, res) __builtin_add_overflow(a, b, res)
57+
#define checked_uint64_sub(a, b, res) __builtin_sub_overflow(a, b, res)
58+
#define checked_uint64_mul(a, b, res) __builtin_mul_overflow(a, b, res)
5359
#else
5460
_Static_assert(0,
5561
"Overflow checking not detected; please try a newer compiler");

pandas/_libs/src/parser/tokenizer.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1898,14 +1898,6 @@ static int power_int(int base, int exponent) {
18981898
return result * base;
18991899
}
19001900

1901-
static inline uint64_t add_uint_check_overflow(uint64_t lhs, uint64_t rhs,
1902-
uint64_t mul_lhs) {
1903-
if (lhs > (UINT_MAX - rhs) / mul_lhs) {
1904-
errno = ERANGE;
1905-
}
1906-
return lhs * mul_lhs + rhs;
1907-
}
1908-
19091901
int64_t str_to_int64(const char *p_item, int64_t int_min, int64_t int_max,
19101902
int *error, char tsep) {
19111903
if (!p_item || *p_item == '\0') {
@@ -2008,7 +2000,18 @@ uint64_t str_to_uint64(uint_state *state, const char *p_item, int64_t int_max,
20082000
uint64_t next_part = strtoull(endptr, &new_end, 10);
20092001
ptrdiff_t digits = new_end - endptr;
20102002
uint64_t mul_result = power_int(10, (int)digits);
2011-
result = add_uint_check_overflow(result, next_part, mul_result);
2003+
2004+
// result * mul_result
2005+
if (checked_uint64_mul(result, mul_result, &result)) {
2006+
// overflow
2007+
errno = ERANGE;
2008+
}
2009+
// result + next_part
2010+
if (checked_uint64_add(result, next_part, &result)) {
2011+
// overflow
2012+
errno = ERANGE;
2013+
}
2014+
20122015
endptr = new_end;
20132016
}
20142017

0 commit comments

Comments
 (0)