Skip to content

Commit 261f4e2

Browse files
committed
shared/util.h: Use generic for size_t arithmetic
This improves support for rare systems like s390 in 31 bit mode, where the size of size_t is equals uint32_t, yet types still differ. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
1 parent ca9a7f4 commit 261f4e2

1 file changed

Lines changed: 26 additions & 14 deletions

File tree

shared/util.h

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,21 @@ static inline bool uadd64_overflow(uint64_t a, uint64_t b, uint64_t *res)
118118
#endif
119119
}
120120

121+
static inline bool simple_uaddsz_overflow(size_t a, size_t b, size_t *res)
122+
{
123+
*res = a + b;
124+
return SIZE_MAX - a < b;
125+
}
126+
127+
#define optimized_uaddsz_overflow(a, b, res) \
128+
_Generic((res), \
129+
uint32_t *: uadd32_overflow, \
130+
uint64_t *: uadd64_overflow, \
131+
default: simple_uaddsz_overflow)(a, b, res)
132+
121133
static inline bool uaddsz_overflow(size_t a, size_t b, size_t *res)
122134
{
123-
#if __SIZEOF_SIZE_T__ == 8
124-
return uadd64_overflow(a, b, res);
125-
#elif __SIZEOF_SIZE_T__ == 4
126-
return uadd32_overflow(a, b, res);
127-
#else
128-
#error "Unknown sizeof(size_t)"
129-
#endif
135+
return optimized_uaddsz_overflow(a, b, res);
130136
}
131137

132138
static inline bool umul32_overflow(uint32_t a, uint32_t b, uint32_t *res)
@@ -162,15 +168,21 @@ static inline bool umulll_overflow(unsigned long long a, unsigned long long b,
162168
#endif
163169
}
164170

171+
static inline bool simple_umulsz_overflow(size_t a, size_t b, size_t *res)
172+
{
173+
*res = a * b;
174+
return SIZE_MAX / a < b;
175+
}
176+
177+
#define optimized_umulsz_overflow(a, b, res) \
178+
_Generic((res), \
179+
uint32_t *: umul32_overflow, \
180+
uint64_t *: umul64_overflow, \
181+
default: simple_umulsz_overflow)(a, b, res)
182+
165183
static inline bool umulsz_overflow(size_t a, size_t b, size_t *res)
166184
{
167-
#if __SIZEOF_SIZE_T__ == 8
168-
return umul64_overflow(a, b, res);
169-
#elif __SIZEOF_SIZE_T__ == 4
170-
return umul32_overflow(a, b, res);
171-
#else
172-
#error "Unknown sizeof(size_t)"
173-
#endif
185+
return optimized_umulsz_overflow(a, b, res);
174186
}
175187

176188
#define TAKE_PTR(x) \

0 commit comments

Comments
 (0)