mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-26 11:22:52 -04:00
chg: dev: Improve C23 compatibility
Use C23 stdckdint.h when available and define ckd_{mul,add,sub} shims to __builtin_{mul,add,sub}_overflow(). Require all the __builtin functions to be supported to further simplify the non-C23 implementation. Rename the <stdbit.h>-shims in <isc/bit.h> to their C23 names.
Merge branch 'ondrej/use-stdckdint.h-if-available' into 'main'
See merge request isc-projects/bind9!10818
This commit is contained in:
commit
bfbc58063a
11 changed files with 63 additions and 102 deletions
|
|
@ -319,7 +319,7 @@ keymgr_prepublication_time(dns_dnsseckey_t *key, dns_kasp_t *kasp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (ISC_OVERFLOW_ADD(active, klifetime, &retire)) {
|
||||
if (ckd_add(&retire, active, klifetime)) {
|
||||
log_key_overflow(key->key, "retire");
|
||||
retire = UINT32_MAX;
|
||||
}
|
||||
|
|
@ -442,7 +442,7 @@ keymgr_key_update_lifetime(dns_dnsseckey_t *key, dns_kasp_t *kasp,
|
|||
uint32_t a = now;
|
||||
uint32_t inactive;
|
||||
(void)dst_key_gettime(key->key, DST_TIME_ACTIVATE, &a);
|
||||
if (ISC_OVERFLOW_ADD(a, lifetime, &inactive)) {
|
||||
if (ckd_add(&inactive, a, lifetime)) {
|
||||
log_key_overflow(key->key, "inactive");
|
||||
inactive = UINT32_MAX;
|
||||
}
|
||||
|
|
@ -1986,7 +1986,7 @@ keymgr_key_rollover(dns_kasp_key_t *kaspkey, dns_dnsseckey_t *active_key,
|
|||
if (lifetime > 0) {
|
||||
uint32_t inactive;
|
||||
|
||||
if (ISC_OVERFLOW_ADD(active, lifetime, &inactive)) {
|
||||
if (ckd_add(&inactive, active, lifetime)) {
|
||||
log_key_overflow(new_key->key, "inactive");
|
||||
inactive = UINT32_MAX;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -495,10 +495,10 @@ static dns_qpcell_t
|
|||
next_capacity(uint32_t prev_capacity, uint32_t size) {
|
||||
/*
|
||||
* Request size was floored at 2 because builtin_clz used to be 0.
|
||||
* We keep this behavior because ISC_LEADING_ZEROS(0) = 32.
|
||||
* We keep this behavior because stdc_leading_zeros(0) = 32.
|
||||
*/
|
||||
size = ISC_MAX3(size, prev_capacity, 2U);
|
||||
uint32_t log2 = 32U - ISC_LEADING_ZEROS(size - 1U);
|
||||
uint32_t log2 = 32U - stdc_leading_zeros(size - 1U);
|
||||
|
||||
return 1U << ISC_CLAMP(log2, QP_CHUNK_LOG_MIN, QP_CHUNK_LOG_MAX);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -753,7 +753,7 @@ static inline dns_qpweight_t
|
|||
branch_count_bitmap_before(dns_qpnode_t *n, dns_qpshift_t bit) {
|
||||
uint64_t mask = (1ULL << bit) - 1 - TAG_MASK;
|
||||
uint64_t bitmap = branch_index(n) & mask;
|
||||
return (dns_qpweight_t)ISC_POPCOUNT(bitmap);
|
||||
return (dns_qpweight_t)stdc_count_zeros(bitmap);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ makeslab(dns_rdataset_t *rdataset, isc_mem_t *mctx, isc_region_t *region,
|
|||
*/
|
||||
nalloc = nitems;
|
||||
|
||||
RUNTIME_CHECK(!ISC_OVERFLOW_MUL(nalloc, sizeof(rdata[0]), &rdatasize));
|
||||
RUNTIME_CHECK(!ckd_mul(&rdatasize, nalloc, sizeof(rdata[0])));
|
||||
rdata = isc_mem_get(mctx, rdatasize);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1095,7 +1095,7 @@ diff_keys(const dns_rpz_cidr_key_t *key1, dns_rpz_prefix_t prefix1,
|
|||
for (i = 0; bit < maxbit; i++, bit += DNS_RPZ_CIDR_WORD_BITS) {
|
||||
delta = key1->w[i] ^ key2->w[i];
|
||||
if (delta != 0) {
|
||||
bit += ISC_LEADING_ZEROS(delta);
|
||||
bit += stdc_leading_zeros(delta);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ static inline uint
|
|||
value_to_key(const isc_histo_t *hg, uint64_t value) {
|
||||
/* ensure that denormal numbers are all in chunk zero */
|
||||
uint64_t chunked = value | CHUNKSIZE(hg);
|
||||
int clz = ISC_LEADING_ZEROS(chunked);
|
||||
int clz = stdc_leading_zeros(chunked);
|
||||
/* actually 1 less than the exponent except for denormals */
|
||||
uint exponent = 63 - hg->sigbits - clz;
|
||||
/* mantissa has leading bit set except for denormals */
|
||||
|
|
|
|||
|
|
@ -19,26 +19,16 @@
|
|||
#include <isc/attributes.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#ifndef __has_header
|
||||
#define __has_header(x) 0
|
||||
#endif
|
||||
|
||||
#if __has_header(<stdbit.h>)
|
||||
|
||||
#include <stdbit.h>
|
||||
|
||||
#define ISC_POPCOUNT(x) stdc_count_zeros(x)
|
||||
#define ISC_LEADING_ZEROS(x) stdc_leading_zeros(x)
|
||||
#define ISC_TRAILING_ZEROS(x) stdc_trailing_zeros(x)
|
||||
#define ISC_LEADING_ONES(x) stdc_leading_ones(x)
|
||||
#define ISC_TRAILING_ONES(x) stdc_trailing_ones(x)
|
||||
|
||||
#else /* __has_header(<stdbit.h>) */
|
||||
|
||||
#ifdef HAVE_BUILTIN_POPCOUNTG
|
||||
#define ISC_POPCOUNT(x) __builtin_popcountg(x)
|
||||
#define stdc_count_zeros(x) __builtin_popcountg(x)
|
||||
#else /* HAVE_BUILTIN_POPCOUNTG */
|
||||
#define ISC_POPCOUNT(x) \
|
||||
#define stdc_count_zeros(x) \
|
||||
_Generic((x), \
|
||||
unsigned int: __builtin_popcount, \
|
||||
unsigned long: __builtin_popcountl, \
|
||||
|
|
@ -46,9 +36,9 @@
|
|||
#endif /* HAVE_BUILTIN_POPCOUNTG */
|
||||
|
||||
#ifdef HAVE_BUILTIN_CLZG
|
||||
#define ISC_LEADING_ZEROS(x) __builtin_clzg(x, (int)(sizeof(x) * 8))
|
||||
#define stdc_leading_zeros(x) __builtin_clzg(x, (int)(sizeof(x) * 8))
|
||||
#else /* HAVE_BUILTIN_CLZG */
|
||||
#define ISC_LEADING_ZEROS(x) \
|
||||
#define stdc_leading_zeros(x) \
|
||||
(((x) == 0) ? (sizeof(x) * 8) \
|
||||
: _Generic((x), \
|
||||
unsigned int: __builtin_clz, \
|
||||
|
|
@ -57,9 +47,9 @@
|
|||
#endif /* HAVE_BUILTIN_CLZG */
|
||||
|
||||
#ifdef HAVE_BUILTIN_CTZG
|
||||
#define ISC_TRAILING_ZEROS(x) __builtin_ctzg(x, (int)sizeof(x) * 8)
|
||||
#define stdc_trailing_zeros(x) __builtin_ctzg(x, (int)sizeof(x) * 8)
|
||||
#else /* HAVE_BUILTIN_CTZG */
|
||||
#define ISC_TRAILING_ZEROS(x) \
|
||||
#define stdc_trailing_zeros(x) \
|
||||
(((x) == 0) ? (sizeof(x) * 8) \
|
||||
: _Generic((x), \
|
||||
unsigned int: __builtin_ctz, \
|
||||
|
|
@ -67,8 +57,8 @@
|
|||
unsigned long long: __builtin_ctzll)(x))
|
||||
#endif /* HAVE_BUILTIN_CTZG */
|
||||
|
||||
#define ISC_LEADING_ONES(x) ISC_LEADING_ZEROS(~(x))
|
||||
#define ISC_TRAILING_ONES(x) ISC_TRAILING_ZEROS(~(x))
|
||||
#define stdc_leading_ones(x) stdc_leading_zeros(~(x))
|
||||
#define stdc_trailing_ones(x) stdc_trailing_zeros(~(x))
|
||||
|
||||
#endif /* __has_header(<stdbit.h>) */
|
||||
|
||||
|
|
|
|||
|
|
@ -17,81 +17,45 @@
|
|||
|
||||
#include <isc/util.h>
|
||||
|
||||
/*
|
||||
* It is awkward to support signed numbers as well, so keep it simple
|
||||
* (with a safety check).
|
||||
*/
|
||||
#define ISC_OVERFLOW_IS_UNSIGNED(a) \
|
||||
({ \
|
||||
STATIC_ASSERT((typeof(a))-1 > 0, \
|
||||
"overflow checks require unsigned types"); \
|
||||
(a); \
|
||||
#if HAVE_STDCKDINT_H
|
||||
#include <stdckdint.h>
|
||||
|
||||
#else /* HAVE_STDCKDINT_H */
|
||||
|
||||
#define ckd_mul(cp, a, b) __builtin_mul_overflow(a, b, cp)
|
||||
#define ckd_add(cp, a, b) __builtin_add_overflow(a, b, cp)
|
||||
#define ckd_sub(cp, a, b) __builtin_sub_overflow(a, b, cp)
|
||||
|
||||
#endif /* HAVE_STDCKDINT_H */
|
||||
|
||||
#define ISC_CHECKED_MUL(a, b) \
|
||||
({ \
|
||||
typeof(a) _c; \
|
||||
bool _overflow = ckd_mul(&_c, a, b); \
|
||||
INSIST(!_overflow); \
|
||||
_c; \
|
||||
})
|
||||
|
||||
#define ISC_OVERFLOW_UINT_MAX(a) ISC_OVERFLOW_IS_UNSIGNED((typeof(a))-1)
|
||||
|
||||
#define ISC_OVERFLOW_UINT_MIN(a) ISC_OVERFLOW_IS_UNSIGNED(0)
|
||||
|
||||
/*
|
||||
* Return true on overflow, e.g.
|
||||
*
|
||||
* bool overflow = ISC_OVERFLOW_MUL(count, sizeof(array[0]), &bytes);
|
||||
* INSIST(!overflow);
|
||||
*/
|
||||
|
||||
#if HAVE_BUILTIN_MUL_OVERFLOW
|
||||
#define ISC_OVERFLOW_MUL(a, b, cp) __builtin_mul_overflow(a, b, cp)
|
||||
#else
|
||||
#define ISC_OVERFLOW_MUL(a, b, cp) \
|
||||
((ISC_OVERFLOW_UINT_MAX(a) / (b) > (a)) ? (*(cp) = (a) * (b), false) \
|
||||
: true)
|
||||
#endif
|
||||
|
||||
#if HAVE_BUILTIN_ADD_OVERFLOW
|
||||
#define ISC_OVERFLOW_ADD(a, b, cp) __builtin_add_overflow(a, b, cp)
|
||||
#else
|
||||
#define ISC_OVERFLOW_ADD(a, b, cp) \
|
||||
((ISC_OVERFLOW_UINT_MAX(a) - (b) > (a)) ? (*(cp) = (a) + (b), false) \
|
||||
: true)
|
||||
#endif
|
||||
|
||||
#if HAVE_BUILTIN_SUB_OVERFLOW
|
||||
#define ISC_OVERFLOW_SUB(a, b, cp) __builtin_sub_overflow(a, b, cp)
|
||||
#else
|
||||
#define ISC_OVERFLOW_SUB(a, b, cp) \
|
||||
((ISC_OVERFLOW_UINT_MIN(a) + (b) < (a)) ? (*(cp) = (a) - (b), false) \
|
||||
: true)
|
||||
#endif
|
||||
|
||||
#define ISC_CHECKED_MUL(a, b) \
|
||||
({ \
|
||||
typeof(a) _c; \
|
||||
bool _overflow = ISC_OVERFLOW_MUL(a, b, &_c); \
|
||||
INSIST(!_overflow); \
|
||||
_c; \
|
||||
#define ISC_CHECKED_ADD(a, b) \
|
||||
({ \
|
||||
typeof(a) _c; \
|
||||
bool _overflow = ckd_add(&_c, a, b); \
|
||||
INSIST(!_overflow); \
|
||||
_c; \
|
||||
})
|
||||
|
||||
#define ISC_CHECKED_ADD(a, b) \
|
||||
({ \
|
||||
typeof(a) _c; \
|
||||
bool _overflow = ISC_OVERFLOW_ADD(a, b, &_c); \
|
||||
INSIST(!_overflow); \
|
||||
_c; \
|
||||
#define ISC_CHECKED_SUB(a, b) \
|
||||
({ \
|
||||
typeof(a) _c; \
|
||||
bool _overflow = ckd_sub(&_c, a, b); \
|
||||
INSIST(!_overflow); \
|
||||
_c; \
|
||||
})
|
||||
|
||||
#define ISC_CHECKED_SUB(a, b) \
|
||||
({ \
|
||||
typeof(a) _c; \
|
||||
bool _overflow = ISC_OVERFLOW_SUB(a, b, cp); \
|
||||
INSIST(!_overflow); \
|
||||
_c; \
|
||||
})
|
||||
|
||||
#define ISC_CHECKED_MUL_ADD(a, b, c) \
|
||||
({ \
|
||||
size_t _d; \
|
||||
bool _overflow = ISC_OVERFLOW_MUL(a, b, &_d) || \
|
||||
ISC_OVERFLOW_ADD(_d, c, &_d); \
|
||||
INSIST(!_overflow); \
|
||||
_d; \
|
||||
#define ISC_CHECKED_MUL_ADD(a, b, c) \
|
||||
({ \
|
||||
size_t _d; \
|
||||
bool _overflow = ckd_mul(&_d, a, b) || ckd_add(&_d, _d, c); \
|
||||
INSIST(!_overflow); \
|
||||
_d; \
|
||||
})
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@
|
|||
#define __has_feature(x) 0
|
||||
#endif /* if !defined(__has_feature) */
|
||||
|
||||
#ifndef __has_header
|
||||
#define __has_header(x) 0
|
||||
#endif
|
||||
|
||||
/***
|
||||
*** General Macros.
|
||||
***/
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result) {
|
|||
REQUIRE(t->nanoseconds < NS_PER_SEC && i->nanoseconds < NS_PER_SEC);
|
||||
|
||||
/* Seconds */
|
||||
if (ISC_OVERFLOW_ADD(t->seconds, i->seconds, &result->seconds)) {
|
||||
if (ckd_add(&result->seconds, t->seconds, i->seconds)) {
|
||||
return ISC_R_RANGE;
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +214,7 @@ isc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
|
|||
REQUIRE(t->nanoseconds < NS_PER_SEC && i->nanoseconds < NS_PER_SEC);
|
||||
|
||||
/* Seconds */
|
||||
if (ISC_OVERFLOW_SUB(t->seconds, i->seconds, &result->seconds)) {
|
||||
if (ckd_sub(&result->seconds, t->seconds, i->seconds)) {
|
||||
return ISC_R_RANGE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -316,12 +316,14 @@ endif
|
|||
|
||||
foreach fn : [
|
||||
'__builtin_add_overflow',
|
||||
'__builtin_expect',
|
||||
'__builtin_mul_overflow',
|
||||
'__builtin_prefetch',
|
||||
'__builtin_sub_overflow',
|
||||
'__builtin_unreachable',
|
||||
]
|
||||
if cc.has_function(fn)
|
||||
config.set('HAVE_@0@'.format(fn.substring(2).to_upper()), 1)
|
||||
if not cc.has_function(fn)
|
||||
error('@0@ support required'.format(fn))
|
||||
endif
|
||||
endforeach
|
||||
|
||||
|
|
@ -523,6 +525,7 @@ foreach h : [
|
|||
'net/if6.h',
|
||||
'net/route.h',
|
||||
'regex.h',
|
||||
'stdckdint.h',
|
||||
'sys/mman.h',
|
||||
'sys/select.h',
|
||||
'sys/sockio.h',
|
||||
|
|
|
|||
Loading…
Reference in a new issue