mdbx: устранение всех предупреждений статического анализатора MSVC (все несущественные или ложные).

This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2023-02-11 00:25:14 +03:00
parent 7f5ea6d3b8
commit 25e958f081
13 changed files with 223 additions and 136 deletions

View File

@ -669,6 +669,23 @@ __extern_C key_t ftok(const char *, int);
#endif #endif
#endif /* MDBX_WEAK_IMPORT_ATTRIBUTE */ #endif /* MDBX_WEAK_IMPORT_ATTRIBUTE */
#ifndef MDBX_GOOFY_MSVC_STATIC_ANALYZER
#ifdef _PREFAST_
#define MDBX_GOOFY_MSVC_STATIC_ANALYZER 1
#else
#define MDBX_GOOFY_MSVC_STATIC_ANALYZER 0
#endif
#endif /* MDBX_GOOFY_MSVC_STATIC_ANALYZER */
#if MDBX_GOOFY_MSVC_STATIC_ANALYZER
#define MDBX_ANALYSIS_ASSUME(expr) __analysis_assume(expr)
#define MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(warn_id, note) \
_Pragma(MDBX_STRINGIFY(prefast(suppress : warn_id)))
#else
#define MDBX_ANALYSIS_ASSUME(expr) assert(expr)
#define MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(warn_id, note)
#endif
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
#if defined(MDBX_USE_VALGRIND) #if defined(MDBX_USE_VALGRIND)

View File

@ -1529,7 +1529,7 @@ __cold int rthc_alloc(osal_thread_key_t *pkey, MDBX_reader *begin,
goto bailout; goto bailout;
} }
if (rthc_table == rthc_table_static) if (rthc_table == rthc_table_static)
memcpy(new_table, rthc_table_static, sizeof(rthc_table_static)); memcpy(new_table, rthc_table, sizeof(rthc_entry_t) * rthc_limit);
rthc_table = new_table; rthc_table = new_table;
rthc_limit *= 2; rthc_limit *= 2;
} }
@ -2250,8 +2250,8 @@ static MDBX_PNL pnl_alloc(size_t size) {
#endif /* malloc_usable_size */ #endif /* malloc_usable_size */
pl[0] = pnl_bytes2size(bytes); pl[0] = pnl_bytes2size(bytes);
assert(pl[0] >= size); assert(pl[0] >= size);
pl[1] = 0;
pl += 1; pl += 1;
*pl = 0;
} }
return pl; return pl;
} }
@ -2435,7 +2435,7 @@ pnl_merge_inner(pgno_t *__restrict dst, const pgno_t *__restrict src_a,
// clang<=5: cmov×2, set+add/sub // clang<=5: cmov×2, set+add/sub
// clang>=6: cmov, set+add/sub // clang>=6: cmov, set+add/sub
*dst = flag ? *src_a : *src_b; *dst = flag ? *src_a : *src_b;
src_b += flag - 1; src_b += (ptrdiff_t)flag - 1;
src_a -= flag; src_a -= flag;
#endif #endif
--dst; --dst;
@ -2593,7 +2593,7 @@ static __inline size_t search_spilled(const MDBX_txn *txn, pgno_t pgno) {
if (likely(!pnl)) if (likely(!pnl))
return 0; return 0;
pgno <<= 1; pgno <<= 1;
size_t n = pnl_search(pnl, pgno, (size_t)(MAX_PAGENO + 1) << 1); size_t n = pnl_search(pnl, pgno, (size_t)MAX_PAGENO + MAX_PAGENO + 1);
return (n <= MDBX_PNL_GETSIZE(pnl) && pnl[n] == pgno) ? n : 0; return (n <= MDBX_PNL_GETSIZE(pnl) && pnl[n] == pgno) ? n : 0;
} }
@ -2620,7 +2620,7 @@ static __inline bool intersect_spilled(const MDBX_txn *txn, pgno_t pgno,
const bool rc = n <= MDBX_PNL_GETSIZE(pnl) && pnl[n] <= spilled_range_last; const bool rc = n <= MDBX_PNL_GETSIZE(pnl) && pnl[n] <= spilled_range_last;
#else #else
const size_t n = const size_t n =
pnl_search(pnl, spilled_range_last, (size_t)(MAX_PAGENO + 1) << 1); pnl_search(pnl, spilled_range_last, (size_t)MAX_PAGENO + MAX_PAGENO + 1);
assert(n && (n == MDBX_PNL_GETSIZE(pnl) + 1 || spilled_range_last >= pnl[n])); assert(n && (n == MDBX_PNL_GETSIZE(pnl) + 1 || spilled_range_last >= pnl[n]));
const bool rc = n <= MDBX_PNL_GETSIZE(pnl) && pnl[n] >= spilled_range_begin; const bool rc = n <= MDBX_PNL_GETSIZE(pnl) && pnl[n] >= spilled_range_begin;
#endif #endif
@ -2659,8 +2659,8 @@ static MDBX_TXL txl_alloc(void) {
#endif /* malloc_usable_size */ #endif /* malloc_usable_size */
tl[0] = txl_bytes2size(bytes); tl[0] = txl_bytes2size(bytes);
assert(tl[0] >= MDBX_TXL_INITIAL); assert(tl[0] >= MDBX_TXL_INITIAL);
tl[1] = 0;
tl += 1; tl += 1;
*tl = 0;
} }
return tl; return tl;
} }
@ -2884,7 +2884,7 @@ __hot __noinline static MDBX_dpl *dpl_sort_slowpath(const MDBX_txn *txn) {
#else #else
*w = cmp ? *l : *r; *w = cmp ? *l : *r;
l -= cmp; l -= cmp;
r += cmp - 1; r += (ptrdiff_t)cmp - 1;
#endif #endif
} while (likely(--w > l)); } while (likely(--w > l));
assert(r == tmp - 1); assert(r == tmp - 1);
@ -4886,7 +4886,7 @@ spill_prio(const MDBX_txn *txn, const size_t i, const uint32_t reciprocal) {
factor |= factor >> 4; factor |= factor >> 4;
factor |= factor >> 8; factor |= factor >> 8;
factor |= factor >> 16; factor |= factor >> 16;
factor = prio * log2n_powerof2(factor + 1) + /* golden ratio */ 157; factor = (size_t)prio * log2n_powerof2(factor + 1) + /* golden ratio */ 157;
factor = (factor < 256) ? 255 - factor : 0; factor = (factor < 256) ? 255 - factor : 0;
tASSERT(txn, factor < 256 && factor < (256 - prio)); tASSERT(txn, factor < 256 && factor < (256 - prio));
return prio = (unsigned)factor; return prio = (unsigned)factor;
@ -5007,6 +5007,7 @@ __cold static int txn_spill_slowpath(MDBX_txn *const txn, MDBX_cursor *const m0,
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
goto bailout; goto bailout;
#if MDBX_AVOID_MSYNC #if MDBX_AVOID_MSYNC
MDBX_ANALYSIS_ASSUME(txn->tw.dirtylist != nullptr);
tASSERT(txn, dirtylist_check(txn)); tASSERT(txn, dirtylist_check(txn));
env->me_lck->mti_unsynced_pages.weak += env->me_lck->mti_unsynced_pages.weak +=
txn->tw.dirtylist->pages_including_loose - txn->tw.loose_count; txn->tw.dirtylist->pages_including_loose - txn->tw.loose_count;
@ -5032,6 +5033,7 @@ __cold static int txn_spill_slowpath(MDBX_txn *const txn, MDBX_cursor *const m0,
NOTICE("%s-spilling %zu dirty-entries, %zu dirty-npages", "write", NOTICE("%s-spilling %zu dirty-entries, %zu dirty-npages", "write",
need_spill_entries, need_spill_npages); need_spill_entries, need_spill_npages);
MDBX_ANALYSIS_ASSUME(txn->tw.dirtylist != nullptr);
tASSERT(txn, txn->tw.dirtylist->length - txn->tw.loose_count >= 1); tASSERT(txn, txn->tw.dirtylist->length - txn->tw.loose_count >= 1);
tASSERT(txn, txn->tw.dirtylist->pages_including_loose - txn->tw.loose_count >= tASSERT(txn, txn->tw.dirtylist->pages_including_loose - txn->tw.loose_count >=
need_spill_npages); need_spill_npages);
@ -5549,6 +5551,7 @@ meta_prefer_steady(const MDBX_env *env, const meta_troika_t *troika) {
static __always_inline meta_ptr_t meta_tail(const MDBX_env *env, static __always_inline meta_ptr_t meta_tail(const MDBX_env *env,
const meta_troika_t *troika) { const meta_troika_t *troika) {
const uint8_t tail = troika->tail_and_flags & 3; const uint8_t tail = troika->tail_and_flags & 3;
MDBX_ANALYSIS_ASSUME(tail < NUM_METAS);
meta_ptr_t r; meta_ptr_t r;
r.txnid = troika->txnid[tail]; r.txnid = troika->txnid[tail];
r.ptr_v = METAPAGE(env, tail); r.ptr_v = METAPAGE(env, tail);
@ -5998,7 +6001,7 @@ static void adjust_defaults(MDBX_env *env) {
const size_t basis = env->me_dbgeo.now; const size_t basis = env->me_dbgeo.now;
/* TODO: use options? */ /* TODO: use options? */
const unsigned factor = 9; const unsigned factor = 9;
size_t threshold = (basis < (65536ul << factor)) size_t threshold = (basis < ((size_t)65536 << factor))
? 65536 /* minimal threshold */ ? 65536 /* minimal threshold */
: (basis > (MEGABYTE * 4 << factor)) : (basis > (MEGABYTE * 4 << factor))
? MEGABYTE * 4 /* maximal threshold */ ? MEGABYTE * 4 /* maximal threshold */
@ -8300,22 +8303,24 @@ static int cursor_shadow(MDBX_txn *parent, MDBX_txn *nested) {
static void cursors_eot(MDBX_txn *txn, const bool merge) { static void cursors_eot(MDBX_txn *txn, const bool merge) {
tASSERT(txn, txn->mt_cursors[FREE_DBI] == nullptr); tASSERT(txn, txn->mt_cursors[FREE_DBI] == nullptr);
for (intptr_t i = txn->mt_numdbs; --i > FREE_DBI;) { for (intptr_t i = txn->mt_numdbs; --i > FREE_DBI;) {
MDBX_cursor *next, *mc = txn->mt_cursors[i]; MDBX_cursor *mc = txn->mt_cursors[i];
if (!mc) if (!mc)
continue; continue;
txn->mt_cursors[i] = NULL; txn->mt_cursors[i] = nullptr;
do { do {
const unsigned stage = mc->mc_signature; const unsigned stage = mc->mc_signature;
MDBX_cursor *bk = mc->mc_backup; MDBX_cursor *const next = mc->mc_next;
next = mc->mc_next; MDBX_cursor *const bk = mc->mc_backup;
ENSURE(txn->mt_env, ENSURE(txn->mt_env,
stage == MDBX_MC_LIVE || (stage == MDBX_MC_WAIT4EOT && bk)); stage == MDBX_MC_LIVE || (stage == MDBX_MC_WAIT4EOT && bk));
cASSERT(mc, mc->mc_dbi == (MDBX_dbi)i); cASSERT(mc, mc->mc_dbi == (MDBX_dbi)i);
if (bk) { if (bk) {
MDBX_xcursor *mx = mc->mc_xcursor; MDBX_xcursor *mx = mc->mc_xcursor;
cASSERT(mc, mx == bk->mc_xcursor);
tASSERT(txn, txn->mt_parent != NULL); tASSERT(txn, txn->mt_parent != NULL);
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(
6001, "Using uninitialized memory '*mc->mc_backup'.");
ENSURE(txn->mt_env, bk->mc_signature == MDBX_MC_LIVE); ENSURE(txn->mt_env, bk->mc_signature == MDBX_MC_LIVE);
tASSERT(txn, mx == bk->mc_xcursor);
if (stage == MDBX_MC_WAIT4EOT /* Cursor was closed by user */) if (stage == MDBX_MC_WAIT4EOT /* Cursor was closed by user */)
mc->mc_signature = stage /* Promote closed state to parent txn */; mc->mc_signature = stage /* Promote closed state to parent txn */;
else if (merge) { else if (merge) {
@ -8345,7 +8350,8 @@ static void cursors_eot(MDBX_txn *txn, const bool merge) {
mc->mc_signature = MDBX_MC_READY4CLOSE /* Cursor may be reused */; mc->mc_signature = MDBX_MC_READY4CLOSE /* Cursor may be reused */;
mc->mc_flags = 0 /* reset C_UNTRACK */; mc->mc_flags = 0 /* reset C_UNTRACK */;
} }
} while ((mc = next) != NULL); mc = next;
} while (mc);
} }
} }
@ -9187,9 +9193,6 @@ void *mdbx_txn_get_userctx(const MDBX_txn *txn) {
int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags, int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags,
MDBX_txn **ret, void *context) { MDBX_txn **ret, void *context) {
MDBX_txn *txn;
size_t size, tsize;
if (unlikely(!ret)) if (unlikely(!ret))
return MDBX_EINVAL; return MDBX_EINVAL;
*ret = NULL; *ret = NULL;
@ -9208,6 +9211,7 @@ int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags,
flags |= env->me_flags & MDBX_WRITEMAP; flags |= env->me_flags & MDBX_WRITEMAP;
MDBX_txn *txn = nullptr;
if (parent) { if (parent) {
/* Nested transactions: Max 1 child, write txns only, no writemap */ /* Nested transactions: Max 1 child, write txns only, no writemap */
rc = check_txn_rw(parent, rc = check_txn_rw(parent,
@ -9238,9 +9242,13 @@ int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags,
goto renew; goto renew;
} }
size = env->me_maxdbs * (sizeof(MDBX_db) + sizeof(MDBX_cursor *) + 1); const size_t base = (flags & MDBX_TXN_RDONLY)
size += tsize = sizeof(MDBX_txn); ? sizeof(MDBX_txn) - sizeof(txn->tw) + sizeof(txn->to)
if (unlikely((txn = osal_malloc(size)) == NULL)) { : sizeof(MDBX_txn);
const size_t size =
base + env->me_maxdbs * (sizeof(MDBX_db) + sizeof(MDBX_cursor *) + 1);
txn = osal_malloc(size);
if (unlikely(txn == nullptr)) {
DEBUG("calloc: %s", "failed"); DEBUG("calloc: %s", "failed");
return MDBX_ENOMEM; return MDBX_ENOMEM;
} }
@ -9248,11 +9256,13 @@ int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags,
memset(txn, 0xCD, size); memset(txn, 0xCD, size);
VALGRIND_MAKE_MEM_UNDEFINED(txn, size); VALGRIND_MAKE_MEM_UNDEFINED(txn, size);
#endif /* MDBX_DEBUG */ #endif /* MDBX_DEBUG */
memset(txn, 0, tsize); MDBX_ANALYSIS_ASSUME(size > base);
txn->mt_dbxs = env->me_dbxs; /* static */ memset(txn, 0,
txn->mt_dbs = ptr_disp(txn, tsize); (MDBX_GOOFY_MSVC_STATIC_ANALYZER && base > size) ? size : base);
txn->mt_dbs = ptr_disp(txn, base);
txn->mt_cursors = ptr_disp(txn->mt_dbs, sizeof(MDBX_db) * env->me_maxdbs); txn->mt_cursors = ptr_disp(txn->mt_dbs, sizeof(MDBX_db) * env->me_maxdbs);
txn->mt_dbistate = ptr_disp(txn, size - env->me_maxdbs); txn->mt_dbistate = ptr_disp(txn, size - env->me_maxdbs);
txn->mt_dbxs = env->me_dbxs; /* static */
txn->mt_flags = flags; txn->mt_flags = flags;
txn->mt_env = env; txn->mt_env = env;
@ -9987,8 +9997,9 @@ __cold static int audit_ex(MDBX_txn *txn, size_t retired_stored,
txn->mt_dbistate[i] |= DBI_AUDITED; txn->mt_dbistate[i] |= DBI_AUDITED;
if (txn->mt_dbs[i].md_root == P_INVALID) if (txn->mt_dbs[i].md_root == P_INVALID)
continue; continue;
used += txn->mt_dbs[i].md_branch_pages + txn->mt_dbs[i].md_leaf_pages + used += (size_t)txn->mt_dbs[i].md_branch_pages +
txn->mt_dbs[i].md_overflow_pages; (size_t)txn->mt_dbs[i].md_leaf_pages +
(size_t)txn->mt_dbs[i].md_overflow_pages;
if (i != MAIN_DBI) if (i != MAIN_DBI)
continue; continue;
@ -10016,8 +10027,8 @@ __cold static int audit_ex(MDBX_txn *txn, size_t retired_stored,
} }
} }
} }
used += used += (size_t)db->md_branch_pages + (size_t)db->md_leaf_pages +
db->md_branch_pages + db->md_leaf_pages + db->md_overflow_pages; (size_t)db->md_overflow_pages;
} }
} }
rc = cursor_sibling(&cx.outer, SIBLING_RIGHT); rc = cursor_sibling(&cx.outer, SIBLING_RIGHT);
@ -10031,11 +10042,13 @@ __cold static int audit_ex(MDBX_txn *txn, size_t retired_stored,
continue; continue;
for (MDBX_txn *t = txn; t; t = t->mt_parent) for (MDBX_txn *t = txn; t; t = t->mt_parent)
if (F_ISSET(t->mt_dbistate[i], DBI_DIRTY | DBI_CREAT)) { if (F_ISSET(t->mt_dbistate[i], DBI_DIRTY | DBI_CREAT)) {
used += t->mt_dbs[i].md_branch_pages + t->mt_dbs[i].md_leaf_pages + used += (size_t)t->mt_dbs[i].md_branch_pages +
t->mt_dbs[i].md_overflow_pages; (size_t)t->mt_dbs[i].md_leaf_pages +
(size_t)t->mt_dbs[i].md_overflow_pages;
txn->mt_dbistate[i] |= DBI_AUDITED; txn->mt_dbistate[i] |= DBI_AUDITED;
break; break;
} }
MDBX_ANALYSIS_ASSUME(txn != nullptr);
if (!(txn->mt_dbistate[i] & DBI_AUDITED)) { if (!(txn->mt_dbistate[i] & DBI_AUDITED)) {
WARNING("audit %s@%" PRIaTXN WARNING("audit %s@%" PRIaTXN
": unable account dbi %zd / \"%*s\", state 0x%02x", ": unable account dbi %zd / \"%*s\", state 0x%02x",
@ -10787,8 +10800,9 @@ retry:
: INT16_MAX; : INT16_MAX;
if (avail_gc_slots > 1) { if (avail_gc_slots > 1) {
#if MDBX_ENABLE_BIGFOOT #if MDBX_ENABLE_BIGFOOT
chunk = (chunk < env->me_maxgc_ov1page * 2) ? chunk / 2 chunk = (chunk < env->me_maxgc_ov1page * (size_t)2)
: env->me_maxgc_ov1page; ? chunk / 2
: env->me_maxgc_ov1page;
#else #else
if (chunk < env->me_maxgc_ov1page * 2) if (chunk < env->me_maxgc_ov1page * 2)
chunk /= 2; chunk /= 2;
@ -12641,8 +12655,9 @@ static int sync_locked(MDBX_env *env, unsigned flags, MDBX_meta *const pending,
? /* grow_step */ pv2pages(pending->mm_geo.grow_pv) ? /* grow_step */ pv2pages(pending->mm_geo.grow_pv)
: shrink_step; : shrink_step;
const pgno_t with_backlog_gap = largest_pgno + backlog_gap; const pgno_t with_backlog_gap = largest_pgno + backlog_gap;
const pgno_t aligned = pgno_align2os_pgno( const pgno_t aligned =
env, with_backlog_gap + aligner - with_backlog_gap % aligner); pgno_align2os_pgno(env, (size_t)with_backlog_gap + aligner -
with_backlog_gap % aligner);
const pgno_t bottom = (aligned > pending->mm_geo.lower) const pgno_t bottom = (aligned > pending->mm_geo.lower)
? aligned ? aligned
: pending->mm_geo.lower; : pending->mm_geo.lower;
@ -13566,10 +13581,10 @@ __cold int mdbx_env_get_maxreaders(const MDBX_env *env, unsigned *readers) {
#endif /* LIBMDBX_NO_EXPORTS_LEGACY_API */ #endif /* LIBMDBX_NO_EXPORTS_LEGACY_API */
__cold static int alloc_page_buf(MDBX_env *env) { __cold static int alloc_page_buf(MDBX_env *env) {
return env->me_pbuf return env->me_pbuf ? MDBX_SUCCESS
? MDBX_SUCCESS : osal_memalign_alloc(env->me_os_psize,
: osal_memalign_alloc(env->me_os_psize, env->me_psize * NUM_METAS, env->me_psize * (size_t)NUM_METAS,
&env->me_pbuf); &env->me_pbuf);
} }
/* Further setup required for opening an MDBX environment */ /* Further setup required for opening an MDBX environment */
@ -13599,8 +13614,8 @@ __cold static int setup_dxb(MDBX_env *env, const int lck_rc,
return err; return err;
header = *init_metas(env, env->me_pbuf); header = *init_metas(env, env->me_pbuf);
err = osal_pwrite(env->me_lazy_fd, env->me_pbuf, env->me_psize * NUM_METAS, err = osal_pwrite(env->me_lazy_fd, env->me_pbuf,
0); env->me_psize * (size_t)NUM_METAS, 0);
if (unlikely(err != MDBX_SUCCESS)) if (unlikely(err != MDBX_SUCCESS))
return err; return err;
@ -14640,7 +14655,8 @@ __cold static int handle_env_pathname(MDBX_handle_env_pathname *ctx,
pathchar_t *const buf = ctx->buffer_for_free; pathchar_t *const buf = ctx->buffer_for_free;
rc = MDBX_SUCCESS; rc = MDBX_SUCCESS;
if (ctx->ent_len) { if (ctx->ent_len) {
memcpy(buf, pathname, sizeof(pathchar_t) * pathname_len); memcpy(buf + /* shutting up goofy MSVC static analyzer */ 0, pathname,
sizeof(pathchar_t) * pathname_len);
if (*flags & MDBX_NOSUBDIR) { if (*flags & MDBX_NOSUBDIR) {
const pathchar_t *const lck_ext = const pathchar_t *const lck_ext =
osal_fileext(lck_name, ARRAY_LENGTH(lck_name)); osal_fileext(lck_name, ARRAY_LENGTH(lck_name));
@ -14657,7 +14673,8 @@ __cold static int handle_env_pathname(MDBX_handle_env_pathname *ctx,
rc = check_alternative_lck_absent(buf); rc = check_alternative_lck_absent(buf);
} }
memcpy(ctx->dxb, pathname, sizeof(pathchar_t) * (ctx->ent_len + 1)); memcpy(ctx->dxb + /* shutting up goofy MSVC static analyzer */ 0, pathname,
sizeof(pathchar_t) * (ctx->ent_len + 1));
memcpy(ctx->lck, pathname, sizeof(pathchar_t) * ctx->ent_len); memcpy(ctx->lck, pathname, sizeof(pathchar_t) * ctx->ent_len);
if (*flags & MDBX_NOSUBDIR) { if (*flags & MDBX_NOSUBDIR) {
memcpy(ctx->lck + ctx->ent_len, lock_suffix, sizeof(lock_suffix)); memcpy(ctx->lck + ctx->ent_len, lock_suffix, sizeof(lock_suffix));
@ -14667,11 +14684,13 @@ __cold static int handle_env_pathname(MDBX_handle_env_pathname *ctx,
} }
} else { } else {
assert(!(*flags & MDBX_NOSUBDIR)); assert(!(*flags & MDBX_NOSUBDIR));
memcpy(buf, dxb_name + 1, sizeof(dxb_name) - sizeof(pathchar_t)); memcpy(buf + /* shutting up goofy MSVC static analyzer */ 0, dxb_name + 1,
sizeof(dxb_name) - sizeof(pathchar_t));
memcpy(buf + dxb_name_len - 1, lock_suffix, sizeof(lock_suffix)); memcpy(buf + dxb_name_len - 1, lock_suffix, sizeof(lock_suffix));
rc = check_alternative_lck_absent(buf); rc = check_alternative_lck_absent(buf);
memcpy(ctx->dxb, dxb_name + 1, sizeof(dxb_name) - sizeof(pathchar_t)); memcpy(ctx->dxb + /* shutting up goofy MSVC static analyzer */ 0,
dxb_name + 1, sizeof(dxb_name) - sizeof(pathchar_t));
memcpy(ctx->lck, lck_name + 1, sizeof(lck_name) - sizeof(pathchar_t)); memcpy(ctx->lck, lck_name + 1, sizeof(lck_name) - sizeof(pathchar_t));
} }
return rc; return rc;
@ -15187,8 +15206,9 @@ __cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
sizeof(MDBX_atomic_uint32_t) + 1); sizeof(MDBX_atomic_uint32_t) + 1);
rc = alloc_page_buf(env); rc = alloc_page_buf(env);
if (rc == MDBX_SUCCESS) { if (rc == MDBX_SUCCESS) {
memset(env->me_pbuf, -1, env->me_psize * 2); memset(env->me_pbuf, -1, env->me_psize * (size_t)2);
memset(ptr_disp(env->me_pbuf, env->me_psize * 2), 0, env->me_psize); memset(ptr_disp(env->me_pbuf, env->me_psize * (size_t)2), 0,
env->me_psize);
MDBX_txn *txn = osal_calloc(1, size); MDBX_txn *txn = osal_calloc(1, size);
if (txn) { if (txn) {
txn->mt_dbs = ptr_disp(txn, tsize); txn->mt_dbs = ptr_disp(txn, tsize);
@ -15735,7 +15755,7 @@ __hot __noinline static int page_search_root(MDBX_cursor *mc,
} else { } else {
const struct node_result nsr = node_search(mc, key); const struct node_result nsr = node_search(mc, key);
if (likely(nsr.node)) if (likely(nsr.node))
i = mc->mc_ki[mc->mc_top] + nsr.exact - 1; i = mc->mc_ki[mc->mc_top] + (intptr_t)nsr.exact - 1;
else else
i = page_numkeys(mp) - 1; i = page_numkeys(mp) - 1;
DEBUG("following index %zu for key [%s]", i, DKEY_DEBUG(key)); DEBUG("following index %zu for key [%s]", i, DKEY_DEBUG(key));
@ -16137,9 +16157,9 @@ static int cursor_sibling(MDBX_cursor *mc, int dir) {
DEBUG("parent page is page %" PRIaPGNO ", index %u", DEBUG("parent page is page %" PRIaPGNO ", index %u",
mc->mc_pg[mc->mc_top]->mp_pgno, mc->mc_ki[mc->mc_top]); mc->mc_pg[mc->mc_top]->mp_pgno, mc->mc_ki[mc->mc_top]);
if ((dir == SIBLING_RIGHT) if ((dir == SIBLING_RIGHT) ? (mc->mc_ki[mc->mc_top] + (size_t)1 >=
? (mc->mc_ki[mc->mc_top] + 1u >= page_numkeys(mc->mc_pg[mc->mc_top])) page_numkeys(mc->mc_pg[mc->mc_top]))
: (mc->mc_ki[mc->mc_top] == 0)) { : (mc->mc_ki[mc->mc_top] == 0)) {
DEBUG("no more keys aside, moving to next %s sibling", DEBUG("no more keys aside, moving to next %s sibling",
dir ? "right" : "left"); dir ? "right" : "left");
if (unlikely((rc = cursor_sibling(mc, dir)) != MDBX_SUCCESS)) { if (unlikely((rc = cursor_sibling(mc, dir)) != MDBX_SUCCESS)) {
@ -16188,7 +16208,7 @@ static int cursor_next(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
mp = mc->mc_pg[mc->mc_top]; mp = mc->mc_pg[mc->mc_top];
if (unlikely(mc->mc_flags & C_EOF)) { if (unlikely(mc->mc_flags & C_EOF)) {
if (mc->mc_ki[mc->mc_top] + 1u >= page_numkeys(mp)) if (mc->mc_ki[mc->mc_top] + (size_t)1 >= page_numkeys(mp))
return MDBX_NOTFOUND; return MDBX_NOTFOUND;
mc->mc_flags ^= C_EOF; mc->mc_flags ^= C_EOF;
} }
@ -16503,7 +16523,7 @@ cursor_set(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, MDBX_cursor_op op) {
return ret; return ret;
} }
} else { } else {
mc->mc_pg[0] = 0; mc->mc_pg[0] = nullptr;
} }
ret.err = page_search(mc, &aligned_key, 0); ret.err = page_search(mc, &aligned_key, 0);
@ -16511,6 +16531,7 @@ cursor_set(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, MDBX_cursor_op op) {
return ret; return ret;
mp = mc->mc_pg[mc->mc_top]; mp = mc->mc_pg[mc->mc_top];
MDBX_ANALYSIS_ASSUME(mp != nullptr);
cASSERT(mc, IS_LEAF(mp)); cASSERT(mc, IS_LEAF(mp));
search_node:; search_node:;
@ -16568,10 +16589,12 @@ got_node:
if (unlikely(ret.err != MDBX_SUCCESS)) if (unlikely(ret.err != MDBX_SUCCESS))
return ret; return ret;
if (op == MDBX_SET || op == MDBX_SET_KEY || op == MDBX_SET_RANGE) { if (op == MDBX_SET || op == MDBX_SET_KEY || op == MDBX_SET_RANGE) {
MDBX_ANALYSIS_ASSUME(mc->mc_xcursor != nullptr);
ret.err = cursor_first(&mc->mc_xcursor->mx_cursor, data, NULL); ret.err = cursor_first(&mc->mc_xcursor->mx_cursor, data, NULL);
if (unlikely(ret.err != MDBX_SUCCESS)) if (unlikely(ret.err != MDBX_SUCCESS))
return ret; return ret;
} else { } else {
MDBX_ANALYSIS_ASSUME(mc->mc_xcursor != nullptr);
ret = cursor_set(&mc->mc_xcursor->mx_cursor, data, NULL, MDBX_SET_RANGE); ret = cursor_set(&mc->mc_xcursor->mx_cursor, data, NULL, MDBX_SET_RANGE);
if (unlikely(ret.err != MDBX_SUCCESS)) if (unlikely(ret.err != MDBX_SUCCESS))
return ret; return ret;
@ -16679,6 +16702,7 @@ static int cursor_first(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data) {
rc = cursor_xinit1(mc, node, mp); rc = cursor_xinit1(mc, node, mp);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
MDBX_ANALYSIS_ASSUME(mc->mc_xcursor != nullptr);
rc = cursor_first(&mc->mc_xcursor->mx_cursor, data, NULL); rc = cursor_first(&mc->mc_xcursor->mx_cursor, data, NULL);
if (unlikely(rc)) if (unlikely(rc))
return rc; return rc;
@ -16728,6 +16752,7 @@ static int cursor_last(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data) {
rc = cursor_xinit1(mc, node, mp); rc = cursor_xinit1(mc, node, mp);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
MDBX_ANALYSIS_ASSUME(mc->mc_xcursor != nullptr);
rc = cursor_last(&mc->mc_xcursor->mx_cursor, data, NULL); rc = cursor_last(&mc->mc_xcursor->mx_cursor, data, NULL);
if (unlikely(rc)) if (unlikely(rc))
return rc; return rc;
@ -17141,10 +17166,10 @@ static __hot int cursor_touch(MDBX_cursor *const mc, const MDBX_val *key,
size_t need = CURSOR_STACK + 3; size_t need = CURSOR_STACK + 3;
/* 2) GC/FreeDB for any payload */ /* 2) GC/FreeDB for any payload */
if (mc->mc_dbi > FREE_DBI) { if (mc->mc_dbi > FREE_DBI) {
need += txn->mt_dbs[FREE_DBI].md_depth + 3; need += txn->mt_dbs[FREE_DBI].md_depth + (size_t)3;
/* 3) Named DBs also dirty the main DB */ /* 3) Named DBs also dirty the main DB */
if (mc->mc_dbi > MAIN_DBI) if (mc->mc_dbi > MAIN_DBI)
need += txn->mt_dbs[MAIN_DBI].md_depth + 3; need += txn->mt_dbs[MAIN_DBI].md_depth + (size_t)3;
} }
#if xMDBX_DEBUG_SPILLING != 2 #if xMDBX_DEBUG_SPILLING != 2
/* production mode */ /* production mode */
@ -17152,7 +17177,7 @@ static __hot int cursor_touch(MDBX_cursor *const mc, const MDBX_val *key,
* for extensively splitting, rebalance and merging */ * for extensively splitting, rebalance and merging */
need += need; need += need;
/* 5) Factor the key+data which to be put in */ /* 5) Factor the key+data which to be put in */
need += bytes2pgno(txn->mt_env, node_size(key, data)) + 1; need += bytes2pgno(txn->mt_env, node_size(key, data)) + (size_t)1;
#else #else
/* debug mode */ /* debug mode */
(void)key; (void)key;
@ -18242,6 +18267,7 @@ __hot static int __must_check_result node_add_leaf2(MDBX_cursor *mc,
size_t indx, size_t indx,
const MDBX_val *key) { const MDBX_val *key) {
MDBX_page *mp = mc->mc_pg[mc->mc_top]; MDBX_page *mp = mc->mc_pg[mc->mc_top];
MDBX_ANALYSIS_ASSUME(key != nullptr);
DKBUF_DEBUG; DKBUF_DEBUG;
DEBUG("add to leaf2-%spage %" PRIaPGNO " index %zi, " DEBUG("add to leaf2-%spage %" PRIaPGNO " index %zi, "
" key size %" PRIuPTR " [%s]", " key size %" PRIuPTR " [%s]",
@ -18322,6 +18348,8 @@ __hot static int __must_check_result node_add_leaf(MDBX_cursor *mc, size_t indx,
const MDBX_val *key, const MDBX_val *key,
MDBX_val *data, MDBX_val *data,
unsigned flags) { unsigned flags) {
MDBX_ANALYSIS_ASSUME(key != nullptr);
MDBX_ANALYSIS_ASSUME(data != nullptr);
MDBX_page *mp = mc->mc_pg[mc->mc_top]; MDBX_page *mp = mc->mc_pg[mc->mc_top];
DKBUF_DEBUG; DKBUF_DEBUG;
DEBUG("add to leaf-%spage %" PRIaPGNO " index %zi, data size %" PRIuPTR DEBUG("add to leaf-%spage %" PRIaPGNO " index %zi, data size %" PRIuPTR
@ -19659,7 +19687,7 @@ static int rebalance(MDBX_cursor *mc) {
const int pagetype = PAGETYPE_WHOLE(mc->mc_pg[mc->mc_top]); const int pagetype = PAGETYPE_WHOLE(mc->mc_pg[mc->mc_top]);
STATIC_ASSERT(P_BRANCH == 1); STATIC_ASSERT(P_BRANCH == 1);
const size_t minkeys = (pagetype & P_BRANCH) + 1; const size_t minkeys = (pagetype & P_BRANCH) + (size_t)1;
/* Pages emptier than this are candidates for merging. */ /* Pages emptier than this are candidates for merging. */
size_t room_threshold = likely(mc->mc_dbi != FREE_DBI) size_t room_threshold = likely(mc->mc_dbi != FREE_DBI)
@ -19797,9 +19825,10 @@ static int rebalance(MDBX_cursor *mc) {
return rc; return rc;
cASSERT(mc, PAGETYPE_WHOLE(left) == PAGETYPE_WHOLE(mc->mc_pg[mc->mc_top])); cASSERT(mc, PAGETYPE_WHOLE(left) == PAGETYPE_WHOLE(mc->mc_pg[mc->mc_top]));
} }
if (mn.mc_ki[pre_top] + 1u < page_numkeys(mn.mc_pg[pre_top])) { if (mn.mc_ki[pre_top] + (size_t)1 < page_numkeys(mn.mc_pg[pre_top])) {
rc = page_get( rc = page_get(
&mn, node_pgno(page_node(mn.mc_pg[pre_top], mn.mc_ki[pre_top] + 1)), &mn,
node_pgno(page_node(mn.mc_pg[pre_top], mn.mc_ki[pre_top] + (size_t)1)),
&right, mc->mc_pg[mc->mc_top]->mp_txnid); &right, mc->mc_pg[mc->mc_top]->mp_txnid);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -20454,7 +20483,7 @@ static int page_split(MDBX_cursor *mc, const MDBX_val *const newkey,
return rc; return rc;
} }
STATIC_ASSERT(P_BRANCH == 1); STATIC_ASSERT(P_BRANCH == 1);
const size_t minkeys = (mp->mp_flags & P_BRANCH) + 1; const size_t minkeys = (mp->mp_flags & P_BRANCH) + (size_t)1;
DEBUG(">> splitting %s-page %" PRIaPGNO DEBUG(">> splitting %s-page %" PRIaPGNO
" and adding %zu+%zu [%s] at %i, nkeys %zi", " and adding %zu+%zu [%s] at %i, nkeys %zi",
@ -20758,7 +20787,7 @@ static int page_split(MDBX_cursor *mc, const MDBX_val *const newkey,
} }
/* root split? */ /* root split? */
ptop += mc->mc_snum - snum; ptop += mc->mc_snum - (size_t)snum;
/* Right page might now have changed parent. /* Right page might now have changed parent.
* Check if left page also changed parent. */ * Check if left page also changed parent. */
@ -20811,7 +20840,7 @@ static int page_split(MDBX_cursor *mc, const MDBX_val *const newkey,
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
goto done; goto done;
MDBX_node *node = page_node(mc->mc_pg[ptop], mc->mc_ki[ptop] + 1); MDBX_node *node = page_node(mc->mc_pg[ptop], mc->mc_ki[ptop] + (size_t)1);
cASSERT(mc, node_pgno(node) == mp->mp_pgno && mc->mc_pg[ptop] == ptop_page); cASSERT(mc, node_pgno(node) == mp->mp_pgno && mc->mc_pg[ptop] == ptop_page);
} else { } else {
mn.mc_top--; mn.mc_top--;
@ -21416,7 +21445,7 @@ __cold static void compacting_fixup_meta(MDBX_env *env, MDBX_meta *meta) {
/* Calculate filesize taking in account shrink/growing thresholds */ /* Calculate filesize taking in account shrink/growing thresholds */
if (meta->mm_geo.next != meta->mm_geo.now) { if (meta->mm_geo.next != meta->mm_geo.now) {
meta->mm_geo.now = meta->mm_geo.next; meta->mm_geo.now = meta->mm_geo.next;
const pgno_t aligner = pv2pages( const size_t aligner = pv2pages(
meta->mm_geo.grow_pv ? meta->mm_geo.grow_pv : meta->mm_geo.shrink_pv); meta->mm_geo.grow_pv ? meta->mm_geo.grow_pv : meta->mm_geo.shrink_pv);
if (aligner) { if (aligner) {
const pgno_t aligned = pgno_align2os_pgno( const pgno_t aligned = pgno_align2os_pgno(
@ -22874,9 +22903,10 @@ static int drop_tree(MDBX_cursor *mc, const bool may_have_subDBs) {
if (!(may_have_subDBs | mc->mc_db->md_overflow_pages)) if (!(may_have_subDBs | mc->mc_db->md_overflow_pages))
cursor_pop(mc); cursor_pop(mc);
rc = pnl_need(&txn->tw.retired_pages, mc->mc_db->md_branch_pages + rc = pnl_need(&txn->tw.retired_pages,
mc->mc_db->md_leaf_pages + (size_t)mc->mc_db->md_branch_pages +
mc->mc_db->md_overflow_pages); (size_t)mc->mc_db->md_leaf_pages +
(size_t)mc->mc_db->md_overflow_pages);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
goto bailout; goto bailout;
@ -24647,8 +24677,8 @@ uint64_t mdbx_key_from_jsonInteger(const int64_t json_integer) {
assert(mantissa >= IEEE754_DOUBLE_IMPLICIT_LEAD && assert(mantissa >= IEEE754_DOUBLE_IMPLICIT_LEAD &&
mantissa <= IEEE754_DOUBLE_MANTISSA_AMAX); mantissa <= IEEE754_DOUBLE_MANTISSA_AMAX);
const uint64_t exponent = const uint64_t exponent = (uint64_t)IEEE754_DOUBLE_EXPONENTA_BIAS +
IEEE754_DOUBLE_EXPONENTA_BIAS + IEEE754_DOUBLE_MANTISSA_SIZE - shift; IEEE754_DOUBLE_MANTISSA_SIZE - shift;
assert(exponent > 0 && exponent <= IEEE754_DOUBLE_EXPONENTA_MAX); assert(exponent > 0 && exponent <= IEEE754_DOUBLE_EXPONENTA_MAX);
const uint64_t key = bias + (exponent << IEEE754_DOUBLE_MANTISSA_SIZE) + const uint64_t key = bias + (exponent << IEEE754_DOUBLE_MANTISSA_SIZE) +
(mantissa - IEEE754_DOUBLE_IMPLICIT_LEAD); (mantissa - IEEE754_DOUBLE_IMPLICIT_LEAD);
@ -24673,8 +24703,8 @@ uint64_t mdbx_key_from_jsonInteger(const int64_t json_integer) {
assert(mantissa >= IEEE754_DOUBLE_IMPLICIT_LEAD && assert(mantissa >= IEEE754_DOUBLE_IMPLICIT_LEAD &&
mantissa <= IEEE754_DOUBLE_MANTISSA_AMAX); mantissa <= IEEE754_DOUBLE_MANTISSA_AMAX);
const uint64_t exponent = const uint64_t exponent = (uint64_t)IEEE754_DOUBLE_EXPONENTA_BIAS +
IEEE754_DOUBLE_EXPONENTA_BIAS + IEEE754_DOUBLE_MANTISSA_SIZE - shift; IEEE754_DOUBLE_MANTISSA_SIZE - shift;
assert(exponent > 0 && exponent <= IEEE754_DOUBLE_EXPONENTA_MAX); assert(exponent > 0 && exponent <= IEEE754_DOUBLE_EXPONENTA_MAX);
const uint64_t key = bias - 1 - (exponent << IEEE754_DOUBLE_MANTISSA_SIZE) - const uint64_t key = bias - 1 - (exponent << IEEE754_DOUBLE_MANTISSA_SIZE) -
(mantissa - IEEE754_DOUBLE_IMPLICIT_LEAD); (mantissa - IEEE754_DOUBLE_IMPLICIT_LEAD);

View File

@ -86,14 +86,18 @@
#pragma warning(disable : 4464) /* relative include path contains '..' */ #pragma warning(disable : 4464) /* relative include path contains '..' */
#endif #endif
#if _MSC_VER > 1913 #if _MSC_VER > 1913
#pragma warning(disable : 5045) /* Compiler will insert Spectre mitigation... \ #pragma warning(disable : 5045) /* will insert Spectre mitigation... */
*/
#endif #endif
#if _MSC_VER > 1914 #if _MSC_VER > 1914
#pragma warning( \ #pragma warning( \
disable : 5105) /* winbase.h(9531): warning C5105: macro expansion \ disable : 5105) /* winbase.h(9531): warning C5105: macro expansion \
producing 'defined' has undefined behavior */ producing 'defined' has undefined behavior */
#endif #endif
#if _MSC_VER > 1930
#pragma warning(disable : 6235) /* <expression> is always a constant */
#pragma warning(disable : 6237) /* <expression> is never evaluated and might \
have side effects */
#endif
#pragma warning(disable : 4710) /* 'xyz': function not inlined */ #pragma warning(disable : 4710) /* 'xyz': function not inlined */
#pragma warning(disable : 4711) /* function 'xyz' selected for automatic \ #pragma warning(disable : 4711) /* function 'xyz' selected for automatic \
inline expansion */ inline expansion */
@ -1693,14 +1697,14 @@ int64pgno(int64_t i64) {
MDBX_MAYBE_UNUSED MDBX_NOTHROW_CONST_FUNCTION static __inline pgno_t MDBX_MAYBE_UNUSED MDBX_NOTHROW_CONST_FUNCTION static __inline pgno_t
pgno_add(size_t base, size_t augend) { pgno_add(size_t base, size_t augend) {
assert(base <= MAX_PAGENO + 1 && augend < MAX_PAGENO); assert(base <= MAX_PAGENO + 1 && augend < MAX_PAGENO);
return int64pgno(base + augend); return int64pgno((int64_t)base + (int64_t)augend);
} }
MDBX_MAYBE_UNUSED MDBX_NOTHROW_CONST_FUNCTION static __inline pgno_t MDBX_MAYBE_UNUSED MDBX_NOTHROW_CONST_FUNCTION static __inline pgno_t
pgno_sub(size_t base, size_t subtrahend) { pgno_sub(size_t base, size_t subtrahend) {
assert(base >= MIN_PAGENO && base <= MAX_PAGENO + 1 && assert(base >= MIN_PAGENO && base <= MAX_PAGENO + 1 &&
subtrahend < MAX_PAGENO); subtrahend < MAX_PAGENO);
return int64pgno(base - subtrahend); return int64pgno((int64_t)base - (int64_t)subtrahend);
} }
MDBX_MAYBE_UNUSED MDBX_NOTHROW_CONST_FUNCTION static __always_inline bool MDBX_MAYBE_UNUSED MDBX_NOTHROW_CONST_FUNCTION static __always_inline bool

View File

@ -175,7 +175,7 @@ static int funlock(mdbx_filehandle_t fd, size_t offset, size_t bytes) {
#else #else
#define DXB_MAXLEN UINT32_C(0x7ff00000) #define DXB_MAXLEN UINT32_C(0x7ff00000)
#endif #endif
#define DXB_BODY (env->me_psize * NUM_METAS), DXB_MAXLEN #define DXB_BODY (env->me_psize * (size_t)NUM_METAS), DXB_MAXLEN
#define DXB_WHOLE 0, DXB_MAXLEN #define DXB_WHOLE 0, DXB_MAXLEN
int mdbx_txn_lock(MDBX_env *env, bool dontwait) { int mdbx_txn_lock(MDBX_env *env, bool dontwait) {
@ -194,8 +194,12 @@ int mdbx_txn_lock(MDBX_env *env, bool dontwait) {
} }
} }
if (env->me_flags & MDBX_EXCLUSIVE) if (env->me_flags & MDBX_EXCLUSIVE) {
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(
26115, "Failing to release lock 'env->me_windowsbug_lock' in function "
"'mdbx_txn_lock'");
return MDBX_SUCCESS; return MDBX_SUCCESS;
}
const HANDLE fd4data = const HANDLE fd4data =
env->me_overlapped_fd ? env->me_overlapped_fd : env->me_lazy_fd; env->me_overlapped_fd ? env->me_overlapped_fd : env->me_lazy_fd;
@ -213,8 +217,12 @@ int mdbx_txn_lock(MDBX_env *env, bool dontwait) {
LCK_EXCLUSIVE | LCK_DONTWAIT, DXB_BODY); LCK_EXCLUSIVE | LCK_DONTWAIT, DXB_BODY);
} }
} }
if (rc == MDBX_SUCCESS) if (rc == MDBX_SUCCESS) {
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(
26115, "Failing to release lock 'env->me_windowsbug_lock' in function "
"'mdbx_txn_lock'");
return rc; return rc;
}
LeaveCriticalSection(&env->me_windowsbug_lock); LeaveCriticalSection(&env->me_windowsbug_lock);
return (!dontwait || rc != ERROR_LOCK_VIOLATION) ? rc : MDBX_BUSY; return (!dontwait || rc != ERROR_LOCK_VIOLATION) ? rc : MDBX_BUSY;
@ -281,17 +289,18 @@ static int suspend_and_append(mdbx_handle_array_t **array,
const DWORD ThreadId) { const DWORD ThreadId) {
const unsigned limit = (*array)->limit; const unsigned limit = (*array)->limit;
if ((*array)->count == limit) { if ((*array)->count == limit) {
void *ptr = osal_realloc( mdbx_handle_array_t *const ptr =
(limit > ARRAY_LENGTH((*array)->handles)) osal_realloc((limit > ARRAY_LENGTH((*array)->handles))
? *array ? *array
: /* don't free initial array on the stack */ NULL, : /* don't free initial array on the stack */ NULL,
sizeof(mdbx_handle_array_t) + sizeof(mdbx_handle_array_t) +
sizeof(HANDLE) * (limit * 2 - ARRAY_LENGTH((*array)->handles))); sizeof(HANDLE) * (limit * (size_t)2 -
ARRAY_LENGTH((*array)->handles)));
if (!ptr) if (!ptr)
return MDBX_ENOMEM; return MDBX_ENOMEM;
if (limit == ARRAY_LENGTH((*array)->handles)) if (limit == ARRAY_LENGTH((*array)->handles))
memcpy(ptr, *array, sizeof(mdbx_handle_array_t)); *ptr = **array;
*array = (mdbx_handle_array_t *)ptr; *array = ptr;
(*array)->limit = limit * 2; (*array)->limit = limit * 2;
} }
@ -839,38 +848,40 @@ MDBX_SetFileIoOverlappedRange mdbx_SetFileIoOverlappedRange;
#endif /* GCC/MINGW */ #endif /* GCC/MINGW */
static void mdbx_winnt_import(void) { static void mdbx_winnt_import(void) {
const HINSTANCE hNtdll = GetModuleHandleA("ntdll.dll");
#define GET_PROC_ADDR(dll, ENTRY) \ #define GET_PROC_ADDR(dll, ENTRY) \
mdbx_##ENTRY = (MDBX_##ENTRY)GetProcAddress(dll, #ENTRY) mdbx_##ENTRY = (MDBX_##ENTRY)GetProcAddress(dll, #ENTRY)
if (GetProcAddress(hNtdll, "wine_get_version")) { const HINSTANCE hNtdll = GetModuleHandleA("ntdll.dll");
assert(mdbx_RunningUnderWine()); if (hNtdll) {
} else { if (GetProcAddress(hNtdll, "wine_get_version")) {
GET_PROC_ADDR(hNtdll, NtFsControlFile); assert(mdbx_RunningUnderWine());
GET_PROC_ADDR(hNtdll, NtExtendSection); } else {
assert(!mdbx_RunningUnderWine()); GET_PROC_ADDR(hNtdll, NtFsControlFile);
GET_PROC_ADDR(hNtdll, NtExtendSection);
assert(!mdbx_RunningUnderWine());
}
} }
const HINSTANCE hKernel32dll = GetModuleHandleA("kernel32.dll"); const HINSTANCE hKernel32dll = GetModuleHandleA("kernel32.dll");
GET_PROC_ADDR(hKernel32dll, GetFileInformationByHandleEx); if (hKernel32dll) {
GET_PROC_ADDR(hKernel32dll, GetTickCount64); GET_PROC_ADDR(hKernel32dll, GetFileInformationByHandleEx);
if (!mdbx_GetTickCount64) GET_PROC_ADDR(hKernel32dll, GetTickCount64);
mdbx_GetTickCount64 = stub_GetTickCount64; if (!mdbx_GetTickCount64)
if (!mdbx_RunningUnderWine()) { mdbx_GetTickCount64 = stub_GetTickCount64;
GET_PROC_ADDR(hKernel32dll, SetFileInformationByHandle); if (!mdbx_RunningUnderWine()) {
GET_PROC_ADDR(hKernel32dll, GetVolumeInformationByHandleW); GET_PROC_ADDR(hKernel32dll, SetFileInformationByHandle);
GET_PROC_ADDR(hKernel32dll, GetFinalPathNameByHandleW); GET_PROC_ADDR(hKernel32dll, GetVolumeInformationByHandleW);
GET_PROC_ADDR(hKernel32dll, PrefetchVirtualMemory); GET_PROC_ADDR(hKernel32dll, GetFinalPathNameByHandleW);
GET_PROC_ADDR(hKernel32dll, SetFileIoOverlappedRange); GET_PROC_ADDR(hKernel32dll, PrefetchVirtualMemory);
GET_PROC_ADDR(hKernel32dll, SetFileIoOverlappedRange);
}
} }
const HINSTANCE hAdvapi32dll = GetModuleHandleA("advapi32.dll"); const osal_srwlock_t_function init =
GET_PROC_ADDR(hAdvapi32dll, RegGetValueA); (osal_srwlock_t_function)(hKernel32dll
#undef GET_PROC_ADDR ? GetProcAddress(hKernel32dll,
"InitializeSRWLock")
const osal_srwlock_t_function init = (osal_srwlock_t_function)GetProcAddress( : nullptr);
hKernel32dll, "InitializeSRWLock");
if (init != NULL) { if (init != NULL) {
osal_srwlock_Init = init; osal_srwlock_Init = init;
osal_srwlock_AcquireShared = (osal_srwlock_t_function)GetProcAddress( osal_srwlock_AcquireShared = (osal_srwlock_t_function)GetProcAddress(
@ -888,6 +899,12 @@ static void mdbx_winnt_import(void) {
osal_srwlock_AcquireExclusive = stub_srwlock_AcquireExclusive; osal_srwlock_AcquireExclusive = stub_srwlock_AcquireExclusive;
osal_srwlock_ReleaseExclusive = stub_srwlock_ReleaseExclusive; osal_srwlock_ReleaseExclusive = stub_srwlock_ReleaseExclusive;
} }
const HINSTANCE hAdvapi32dll = GetModuleHandleA("advapi32.dll");
if (hAdvapi32dll) {
GET_PROC_ADDR(hAdvapi32dll, RegGetValueA);
}
#undef GET_PROC_ADDR
} }
#if __GNUC_PREREQ(8, 0) #if __GNUC_PREREQ(8, 0)

View File

@ -571,8 +571,8 @@ static int pgvisitor(const uint64_t pgno, const unsigned pgnumber,
data_tree_problems += !is_gc_tree; data_tree_problems += !is_gc_tree;
gc_tree_problems += is_gc_tree; gc_tree_problems += is_gc_tree;
} else { } else {
dbi->payload_bytes += payload_bytes + header_bytes; dbi->payload_bytes += (uint64_t)payload_bytes + header_bytes;
walk.total_payload_bytes += payload_bytes + header_bytes; walk.total_payload_bytes += (uint64_t)payload_bytes + header_bytes;
} }
} }
} }
@ -632,7 +632,7 @@ static int handle_freedb(const uint64_t record_number, const MDBX_val *key,
pgno_t prev = MDBX_PNL_ASCENDING ? NUM_METAS - 1 : txn->mt_next_pgno; pgno_t prev = MDBX_PNL_ASCENDING ? NUM_METAS - 1 : txn->mt_next_pgno;
pgno_t span = 1; pgno_t span = 1;
for (unsigned i = 0; i < number; ++i) { for (size_t i = 0; i < number; ++i) {
if (check_user_break()) if (check_user_break())
return MDBX_EINTR; return MDBX_EINTR;
const pgno_t pgno = iptr[i]; const pgno_t pgno = iptr[i];
@ -651,7 +651,7 @@ static int handle_freedb(const uint64_t record_number, const MDBX_val *key,
if (MDBX_PNL_DISORDERED(prev, pgno)) { if (MDBX_PNL_DISORDERED(prev, pgno)) {
bad = " [bad sequence]"; bad = " [bad sequence]";
problem_add("entry", txnid, "bad sequence", problem_add("entry", txnid, "bad sequence",
"%" PRIaPGNO " %c [%u].%" PRIaPGNO, prev, "%" PRIaPGNO " %c [%zu].%" PRIaPGNO, prev,
(prev == pgno) ? '=' : (MDBX_PNL_ASCENDING ? '>' : '<'), (prev == pgno) ? '=' : (MDBX_PNL_ASCENDING ? '>' : '<'),
i, pgno); i, pgno);
} }
@ -677,7 +677,7 @@ static int handle_freedb(const uint64_t record_number, const MDBX_val *key,
" pages, maxspan %" PRIaPGNO "%s\n", " pages, maxspan %" PRIaPGNO "%s\n",
txnid, number, span, bad); txnid, number, span, bad);
if (verbose > 4) { if (verbose > 4) {
for (unsigned i = 0; i < number; i += span) { for (size_t i = 0; i < number; i += span) {
const pgno_t pgno = iptr[i]; const pgno_t pgno = iptr[i];
for (span = 1; for (span = 1;
i + span < number && i + span < number &&

View File

@ -673,7 +673,7 @@ int main(int argc, char *argv[]) {
goto env_close; goto env_close;
} }
kbuf.iov_len = mdbx_env_get_maxvalsize_ex(env, 0) + 1; kbuf.iov_len = mdbx_env_get_maxvalsize_ex(env, 0) + (size_t)1;
if (kbuf.iov_len >= INTPTR_MAX / 2) { if (kbuf.iov_len >= INTPTR_MAX / 2) {
if (!quiet) if (!quiet)
fprintf(stderr, "mdbx_env_get_maxkeysize() failed, returns %zu\n", fprintf(stderr, "mdbx_env_get_maxkeysize() failed, returns %zu\n",

View File

@ -48,6 +48,7 @@ static int ntstatus2errcode(NTSTATUS status) {
OVERLAPPED ov; OVERLAPPED ov;
memset(&ov, 0, sizeof(ov)); memset(&ov, 0, sizeof(ov));
ov.Internal = status; ov.Internal = status;
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(6387, "'_Param_(1)' could be '0'");
return GetOverlappedResult(NULL, &ov, &dummy, FALSE) ? MDBX_SUCCESS return GetOverlappedResult(NULL, &ov, &dummy, FALSE) ? MDBX_SUCCESS
: (int)GetLastError(); : (int)GetLastError();
} }
@ -82,6 +83,8 @@ extern NTSTATUS NTAPI NtMapViewOfSection(
extern NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, extern NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle,
IN OPTIONAL PVOID BaseAddress); IN OPTIONAL PVOID BaseAddress);
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(28251,
"Inconsistent annotation for 'NtClose'...")
extern NTSTATUS NTAPI NtClose(HANDLE Handle); extern NTSTATUS NTAPI NtClose(HANDLE Handle);
extern NTSTATUS NTAPI NtAllocateVirtualMemory( extern NTSTATUS NTAPI NtAllocateVirtualMemory(
@ -320,7 +323,7 @@ MDBX_INTERNAL_FUNC int osal_vasprintf(char **strp, const char *fmt,
return needed; return needed;
} }
*strp = osal_malloc(needed + 1); *strp = osal_malloc(needed + (size_t)1);
if (unlikely(*strp == nullptr)) { if (unlikely(*strp == nullptr)) {
va_end(ones); va_end(ones);
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
@ -331,7 +334,7 @@ MDBX_INTERNAL_FUNC int osal_vasprintf(char **strp, const char *fmt,
return -1; return -1;
} }
int actual = vsnprintf(*strp, needed + 1, fmt, ones); int actual = vsnprintf(*strp, needed + (size_t)1, fmt, ones);
va_end(ones); va_end(ones);
assert(actual == needed); assert(actual == needed);
@ -692,7 +695,7 @@ MDBX_INTERNAL_FUNC int osal_ioring_add(osal_ioring_t *ior, const size_t offset,
((bytes | (uintptr_t)data | ior->last_bytes | ((bytes | (uintptr_t)data | ior->last_bytes |
(uintptr_t)(uint64_t)item->sgv[0].Buffer) & (uintptr_t)(uint64_t)item->sgv[0].Buffer) &
ior_alignment_mask) == 0 && ior_alignment_mask) == 0 &&
ior->last_sgvcnt + segments < OSAL_IOV_MAX) { ior->last_sgvcnt + (size_t)segments < OSAL_IOV_MAX) {
assert(ior->overlapped_fd); assert(ior->overlapped_fd);
assert((item->single.iov_len & ior_WriteFile_flag) == 0); assert((item->single.iov_len & ior_WriteFile_flag) == 0);
assert(item->sgv[ior->last_sgvcnt].Buffer == 0); assert(item->sgv[ior->last_sgvcnt].Buffer == 0);
@ -801,6 +804,8 @@ MDBX_INTERNAL_FUNC void osal_ioring_walk(
if (bytes & ior_WriteFile_flag) { if (bytes & ior_WriteFile_flag) {
data = Ptr64ToPtr(item->sgv[0].Buffer); data = Ptr64ToPtr(item->sgv[0].Buffer);
bytes = ior->pagesize; bytes = ior->pagesize;
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(
6385, "Reading invalid data from 'item->sgv'");
while (item->sgv[i].Buffer) { while (item->sgv[i].Buffer) {
if (data + ior->pagesize != item->sgv[i].Buffer) { if (data + ior->pagesize != item->sgv[i].Buffer) {
callback(ctx, offset, data, bytes); callback(ctx, offset, data, bytes);
@ -847,6 +852,8 @@ osal_ioring_write(osal_ioring_t *ior, mdbx_filehandle_t fd) {
if (bytes & ior_WriteFile_flag) { if (bytes & ior_WriteFile_flag) {
assert(ior->overlapped_fd && fd == ior->overlapped_fd); assert(ior->overlapped_fd && fd == ior->overlapped_fd);
bytes = ior->pagesize; bytes = ior->pagesize;
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(
6385, "Reading invalid data from 'item->sgv'");
while (item->sgv[i].Buffer) { while (item->sgv[i].Buffer) {
bytes += ior->pagesize; bytes += ior->pagesize;
++i; ++i;
@ -985,6 +992,8 @@ osal_ioring_write(osal_ioring_t *ior, mdbx_filehandle_t fd) {
size_t i = 1, bytes = item->single.iov_len - ior_WriteFile_flag; size_t i = 1, bytes = item->single.iov_len - ior_WriteFile_flag;
if (bytes & ior_WriteFile_flag) { if (bytes & ior_WriteFile_flag) {
bytes = ior->pagesize; bytes = ior->pagesize;
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(
6385, "Reading invalid data from 'item->sgv'");
while (item->sgv[i].Buffer) { while (item->sgv[i].Buffer) {
bytes += ior->pagesize; bytes += ior->pagesize;
++i; ++i;
@ -1078,9 +1087,12 @@ MDBX_INTERNAL_FUNC void osal_ioring_reset(osal_ioring_t *ior) {
if (item->ov.hEvent && item->ov.hEvent != ior) if (item->ov.hEvent && item->ov.hEvent != ior)
ior_put_event(ior, item->ov.hEvent); ior_put_event(ior, item->ov.hEvent);
size_t i = 1; size_t i = 1;
if ((item->single.iov_len & ior_WriteFile_flag) == 0) if ((item->single.iov_len & ior_WriteFile_flag) == 0) {
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(
6385, "Reading invalid data from 'item->sgv'");
while (item->sgv[i].Buffer) while (item->sgv[i].Buffer)
++i; ++i;
}
item = ior_next(item, i); item = ior_next(item, i);
} }
} }
@ -1095,8 +1107,11 @@ MDBX_INTERNAL_FUNC void osal_ioring_reset(osal_ioring_t *ior) {
static void ior_cleanup(osal_ioring_t *ior, const size_t since) { static void ior_cleanup(osal_ioring_t *ior, const size_t since) {
osal_ioring_reset(ior); osal_ioring_reset(ior);
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
for (size_t i = since; i < ior->event_stack; ++i) for (size_t i = since; i < ior->event_stack; ++i) {
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(
6001, "Using uninitialized memory '**ior.event_pool'");
CloseHandle(ior->event_pool[i]); CloseHandle(ior->event_pool[i]);
}
ior->event_stack = 0; ior->event_stack = 0;
#else #else
(void)since; (void)since;
@ -2734,6 +2749,7 @@ retry_mapview:;
#endif /* POSIX / Windows */ #endif /* POSIX / Windows */
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(6287, "Redundant code");
assert(rc != MDBX_SUCCESS || assert(rc != MDBX_SUCCESS ||
(map->base != nullptr && map->base != MAP_FAILED && (map->base != nullptr && map->base != MAP_FAILED &&
map->current == size && map->limit == limit && map->current == size && map->limit == limit &&

View File

@ -87,10 +87,11 @@ time from_ms(uint64_t ms) {
time now_realtime() { time now_realtime() {
#if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS) #if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS)
static void(WINAPI * query_time)(LPFILETIME); static void(WINAPI * query_time)(LPFILETIME);
if (!query_time) { if (unlikely(!query_time)) {
query_time = (void(WINAPI *)(LPFILETIME))GetProcAddress( HMODULE hModule = GetModuleHandle(TEXT("kernel32.dll"));
GetModuleHandle(TEXT("kernel32.dll")), if (hModule)
"GetSystemTimePreciseAsFileTime"); query_time = (void(WINAPI *)(LPFILETIME))GetProcAddress(
hModule, "GetSystemTimePreciseAsFileTime");
if (!query_time) if (!query_time)
query_time = GetSystemTimeAsFileTime; query_time = GetSystemTimeAsFileTime;
} }

View File

@ -227,7 +227,8 @@ void maker::setup(const config::actor_params_pod &actor, unsigned actor_id,
(void)thread_number; (void)thread_number;
mapping = actor.keygen; mapping = actor.keygen;
salt = (actor.keygen.seed + actor_id) * UINT64_C(14653293970879851569); salt =
(actor.keygen.seed + uint64_t(actor_id)) * UINT64_C(14653293970879851569);
base = actor.serial_base(); base = actor.serial_base();
} }
@ -315,11 +316,12 @@ void __hot maker::mk_begin(const serial_t serial, const essentials &params,
out.value.iov_len = std::max(unsigned(params.minlen), length(serial)); out.value.iov_len = std::max(unsigned(params.minlen), length(serial));
const auto variation = params.maxlen - params.minlen; const auto variation = params.maxlen - params.minlen;
if (variation) { if (variation) {
if (serial % (variation + 1)) { if (serial % (variation + serial_t(1))) {
auto refix = serial * UINT64_C(48835288005252737); auto refix = serial * UINT64_C(48835288005252737);
refix ^= refix >> 32; refix ^= refix >> 32;
out.value.iov_len = std::max( out.value.iov_len =
out.value.iov_len, params.minlen + 1 + size_t(refix) % variation); std::max(out.value.iov_len,
params.minlen + size_t(1) + size_t(refix) % variation);
} }
} }

View File

@ -142,7 +142,7 @@ void output_nocheckloglevel_ap(const logging::loglevel priority,
prefix.c_str(), level2str(priority), suffix.c_str()); prefix.c_str(), level2str(priority), suffix.c_str());
va_list ones; va_list ones;
memset(&ones, 0, sizeof(ones)) /* zap MSVC and other stupid compilers */; memset(&ones, 0, sizeof(ones)) /* zap MSVC and other goofy compilers */;
if (same_or_higher(priority, error)) if (same_or_higher(priority, error))
va_copy(ones, ap); va_copy(ones, ap);
vfprintf(last, format, ap); vfprintf(last, format, ap);
@ -153,11 +153,11 @@ void output_nocheckloglevel_ap(const logging::loglevel priority,
switch (end) { switch (end) {
default: default:
putc('\n', last); putc('\n', last);
// fall through MDBX_CXX17_FALLTHROUGH; // fall through
case '\n': case '\n':
fflush(last); fflush(last);
last = nullptr; last = nullptr;
// fall through MDBX_CXX17_FALLTHROUGH; // fall through
case ' ': case ' ':
case '_': case '_':
case ':': case ':':

View File

@ -248,7 +248,7 @@ Environment:
CommandLine.push_back('"'); CommandLine.push_back('"');
for (auto It = Argument.begin();; ++It) { for (auto It = Argument.begin();; ++It) {
unsigned NumberBackslashes = 0; size_t NumberBackslashes = 0;
while (It != Argument.end() && *It == '\\') { while (It != Argument.end() && *It == '\\') {
++It; ++It;
@ -435,7 +435,7 @@ void osal_udelay(size_t us) {
unsigned timeslice_ms = 1; unsigned timeslice_ms = 1;
while (timeBeginPeriod(timeslice_ms) == TIMERR_NOCANDO) while (timeBeginPeriod(timeslice_ms) == TIMERR_NOCANDO)
++timeslice_ms; ++timeslice_ms;
threshold_us = timeslice_ms * 1500u; threshold_us = timeslice_ms * size_t(1500);
assert(threshold_us > 0); assert(threshold_us > 0);
} }

View File

@ -100,7 +100,7 @@ int testcase::hsr_callback(const MDBX_env *env, const MDBX_txn *txn,
info.mi_geo.current >= info.mi_geo.upper)) { info.mi_geo.current >= info.mi_geo.upper)) {
osal_yield(); osal_yield();
if (retry > 0) if (retry > 0)
osal_udelay(retry * 100); osal_udelay(retry * size_t(100));
return MDBX_RESULT_FALSE /* retry / wait until reader done */; return MDBX_RESULT_FALSE /* retry / wait until reader done */;
} }

View File

@ -101,10 +101,10 @@ class testcase;
class registry { class registry {
struct record { struct record {
actor_testcase id; actor_testcase id = ac_none;
std::string name; std::string name;
bool (*review_params)(actor_params &); bool (*review_params)(actor_params &) = nullptr;
testcase *(*constructor)(const actor_config &, const mdbx_pid_t); testcase *(*constructor)(const actor_config &, const mdbx_pid_t) = nullptr;
}; };
std::unordered_map<std::string, const record *> name2id; std::unordered_map<std::string, const record *> name2id;
std::unordered_map<int, const record *> id2record; std::unordered_map<int, const record *> id2record;