diff --git a/src/base.h b/src/base.h index 753ad005..09aa7ff3 100644 --- a/src/base.h +++ b/src/base.h @@ -669,6 +669,23 @@ __extern_C key_t ftok(const char *, int); #endif #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) diff --git a/src/core.c b/src/core.c index 97eebbdd..b32ae17a 100644 --- a/src/core.c +++ b/src/core.c @@ -1529,7 +1529,7 @@ __cold int rthc_alloc(osal_thread_key_t *pkey, MDBX_reader *begin, goto bailout; } 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_limit *= 2; } @@ -2250,8 +2250,8 @@ static MDBX_PNL pnl_alloc(size_t size) { #endif /* malloc_usable_size */ pl[0] = pnl_bytes2size(bytes); assert(pl[0] >= size); - pl[1] = 0; pl += 1; + *pl = 0; } 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>=6: cmov, set+add/sub *dst = flag ? *src_a : *src_b; - src_b += flag - 1; + src_b += (ptrdiff_t)flag - 1; src_a -= flag; #endif --dst; @@ -2593,7 +2593,7 @@ static __inline size_t search_spilled(const MDBX_txn *txn, pgno_t pgno) { if (likely(!pnl)) return 0; 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; } @@ -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; #else 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])); const bool rc = n <= MDBX_PNL_GETSIZE(pnl) && pnl[n] >= spilled_range_begin; #endif @@ -2659,8 +2659,8 @@ static MDBX_TXL txl_alloc(void) { #endif /* malloc_usable_size */ tl[0] = txl_bytes2size(bytes); assert(tl[0] >= MDBX_TXL_INITIAL); - tl[1] = 0; tl += 1; + *tl = 0; } return tl; } @@ -2884,7 +2884,7 @@ __hot __noinline static MDBX_dpl *dpl_sort_slowpath(const MDBX_txn *txn) { #else *w = cmp ? *l : *r; l -= cmp; - r += cmp - 1; + r += (ptrdiff_t)cmp - 1; #endif } while (likely(--w > l)); 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 >> 8; 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; tASSERT(txn, factor < 256 && factor < (256 - prio)); 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)) goto bailout; #if MDBX_AVOID_MSYNC + MDBX_ANALYSIS_ASSUME(txn->tw.dirtylist != nullptr); tASSERT(txn, dirtylist_check(txn)); env->me_lck->mti_unsynced_pages.weak += 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", 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->pages_including_loose - txn->tw.loose_count >= 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, const meta_troika_t *troika) { const uint8_t tail = troika->tail_and_flags & 3; + MDBX_ANALYSIS_ASSUME(tail < NUM_METAS); meta_ptr_t r; r.txnid = troika->txnid[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; /* TODO: use options? */ const unsigned factor = 9; - size_t threshold = (basis < (65536ul << factor)) + size_t threshold = (basis < ((size_t)65536 << factor)) ? 65536 /* minimal threshold */ : (basis > (MEGABYTE * 4 << factor)) ? 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) { tASSERT(txn, txn->mt_cursors[FREE_DBI] == nullptr); 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) continue; - txn->mt_cursors[i] = NULL; + txn->mt_cursors[i] = nullptr; do { const unsigned stage = mc->mc_signature; - MDBX_cursor *bk = mc->mc_backup; - next = mc->mc_next; + MDBX_cursor *const next = mc->mc_next; + MDBX_cursor *const bk = mc->mc_backup; ENSURE(txn->mt_env, stage == MDBX_MC_LIVE || (stage == MDBX_MC_WAIT4EOT && bk)); cASSERT(mc, mc->mc_dbi == (MDBX_dbi)i); if (bk) { MDBX_xcursor *mx = mc->mc_xcursor; - cASSERT(mc, mx == bk->mc_xcursor); 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); + tASSERT(txn, mx == bk->mc_xcursor); if (stage == MDBX_MC_WAIT4EOT /* Cursor was closed by user */) mc->mc_signature = stage /* Promote closed state to parent txn */; 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_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, MDBX_txn **ret, void *context) { - MDBX_txn *txn; - size_t size, tsize; - if (unlikely(!ret)) return MDBX_EINVAL; *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; + MDBX_txn *txn = nullptr; if (parent) { /* Nested transactions: Max 1 child, write txns only, no writemap */ 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; } - size = env->me_maxdbs * (sizeof(MDBX_db) + sizeof(MDBX_cursor *) + 1); - size += tsize = sizeof(MDBX_txn); - if (unlikely((txn = osal_malloc(size)) == NULL)) { + const size_t base = (flags & MDBX_TXN_RDONLY) + ? sizeof(MDBX_txn) - sizeof(txn->tw) + sizeof(txn->to) + : 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"); 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); VALGRIND_MAKE_MEM_UNDEFINED(txn, size); #endif /* MDBX_DEBUG */ - memset(txn, 0, tsize); - txn->mt_dbxs = env->me_dbxs; /* static */ - txn->mt_dbs = ptr_disp(txn, tsize); + MDBX_ANALYSIS_ASSUME(size > base); + memset(txn, 0, + (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_dbistate = ptr_disp(txn, size - env->me_maxdbs); + txn->mt_dbxs = env->me_dbxs; /* static */ txn->mt_flags = flags; 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; if (txn->mt_dbs[i].md_root == P_INVALID) continue; - used += txn->mt_dbs[i].md_branch_pages + txn->mt_dbs[i].md_leaf_pages + - txn->mt_dbs[i].md_overflow_pages; + used += (size_t)txn->mt_dbs[i].md_branch_pages + + (size_t)txn->mt_dbs[i].md_leaf_pages + + (size_t)txn->mt_dbs[i].md_overflow_pages; if (i != MAIN_DBI) continue; @@ -10016,8 +10027,8 @@ __cold static int audit_ex(MDBX_txn *txn, size_t retired_stored, } } } - used += - db->md_branch_pages + db->md_leaf_pages + db->md_overflow_pages; + used += (size_t)db->md_branch_pages + (size_t)db->md_leaf_pages + + (size_t)db->md_overflow_pages; } } rc = cursor_sibling(&cx.outer, SIBLING_RIGHT); @@ -10031,11 +10042,13 @@ __cold static int audit_ex(MDBX_txn *txn, size_t retired_stored, continue; for (MDBX_txn *t = txn; t; t = t->mt_parent) 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 + - t->mt_dbs[i].md_overflow_pages; + used += (size_t)t->mt_dbs[i].md_branch_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; break; } + MDBX_ANALYSIS_ASSUME(txn != nullptr); if (!(txn->mt_dbistate[i] & DBI_AUDITED)) { WARNING("audit %s@%" PRIaTXN ": unable account dbi %zd / \"%*s\", state 0x%02x", @@ -10787,8 +10800,9 @@ retry: : INT16_MAX; if (avail_gc_slots > 1) { #if MDBX_ENABLE_BIGFOOT - chunk = (chunk < env->me_maxgc_ov1page * 2) ? chunk / 2 - : env->me_maxgc_ov1page; + chunk = (chunk < env->me_maxgc_ov1page * (size_t)2) + ? chunk / 2 + : env->me_maxgc_ov1page; #else if (chunk < env->me_maxgc_ov1page * 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) : shrink_step; const pgno_t with_backlog_gap = largest_pgno + backlog_gap; - const pgno_t aligned = pgno_align2os_pgno( - env, with_backlog_gap + aligner - with_backlog_gap % aligner); + const pgno_t aligned = + pgno_align2os_pgno(env, (size_t)with_backlog_gap + aligner - + with_backlog_gap % aligner); const pgno_t bottom = (aligned > pending->mm_geo.lower) ? aligned : 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 */ __cold static int alloc_page_buf(MDBX_env *env) { - return env->me_pbuf - ? MDBX_SUCCESS - : osal_memalign_alloc(env->me_os_psize, env->me_psize * NUM_METAS, - &env->me_pbuf); + return env->me_pbuf ? MDBX_SUCCESS + : osal_memalign_alloc(env->me_os_psize, + env->me_psize * (size_t)NUM_METAS, + &env->me_pbuf); } /* 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; header = *init_metas(env, env->me_pbuf); - err = osal_pwrite(env->me_lazy_fd, env->me_pbuf, env->me_psize * NUM_METAS, - 0); + err = osal_pwrite(env->me_lazy_fd, env->me_pbuf, + env->me_psize * (size_t)NUM_METAS, 0); if (unlikely(err != MDBX_SUCCESS)) 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; rc = MDBX_SUCCESS; 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) { const pathchar_t *const lck_ext = 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); } - 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); if (*flags & MDBX_NOSUBDIR) { 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 { 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)); 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)); } return rc; @@ -15187,8 +15206,9 @@ __cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname, sizeof(MDBX_atomic_uint32_t) + 1); rc = alloc_page_buf(env); if (rc == MDBX_SUCCESS) { - memset(env->me_pbuf, -1, env->me_psize * 2); - memset(ptr_disp(env->me_pbuf, env->me_psize * 2), 0, env->me_psize); + memset(env->me_pbuf, -1, env->me_psize * (size_t)2); + memset(ptr_disp(env->me_pbuf, env->me_psize * (size_t)2), 0, + env->me_psize); MDBX_txn *txn = osal_calloc(1, size); if (txn) { txn->mt_dbs = ptr_disp(txn, tsize); @@ -15735,7 +15755,7 @@ __hot __noinline static int page_search_root(MDBX_cursor *mc, } else { const struct node_result nsr = node_search(mc, key); 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 i = page_numkeys(mp) - 1; 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", mc->mc_pg[mc->mc_top]->mp_pgno, mc->mc_ki[mc->mc_top]); - if ((dir == SIBLING_RIGHT) - ? (mc->mc_ki[mc->mc_top] + 1u >= page_numkeys(mc->mc_pg[mc->mc_top])) - : (mc->mc_ki[mc->mc_top] == 0)) { + if ((dir == SIBLING_RIGHT) ? (mc->mc_ki[mc->mc_top] + (size_t)1 >= + page_numkeys(mc->mc_pg[mc->mc_top])) + : (mc->mc_ki[mc->mc_top] == 0)) { DEBUG("no more keys aside, moving to next %s sibling", dir ? "right" : "left"); 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]; 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; 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; } } else { - mc->mc_pg[0] = 0; + mc->mc_pg[0] = nullptr; } 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; mp = mc->mc_pg[mc->mc_top]; + MDBX_ANALYSIS_ASSUME(mp != nullptr); cASSERT(mc, IS_LEAF(mp)); search_node:; @@ -16568,10 +16589,12 @@ got_node: if (unlikely(ret.err != MDBX_SUCCESS)) return ret; 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); if (unlikely(ret.err != MDBX_SUCCESS)) return ret; } else { + MDBX_ANALYSIS_ASSUME(mc->mc_xcursor != nullptr); ret = cursor_set(&mc->mc_xcursor->mx_cursor, data, NULL, MDBX_SET_RANGE); if (unlikely(ret.err != MDBX_SUCCESS)) 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); if (unlikely(rc != MDBX_SUCCESS)) return rc; + MDBX_ANALYSIS_ASSUME(mc->mc_xcursor != nullptr); rc = cursor_first(&mc->mc_xcursor->mx_cursor, data, NULL); if (unlikely(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); if (unlikely(rc != MDBX_SUCCESS)) return rc; + MDBX_ANALYSIS_ASSUME(mc->mc_xcursor != nullptr); rc = cursor_last(&mc->mc_xcursor->mx_cursor, data, NULL); if (unlikely(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; /* 2) GC/FreeDB for any payload */ 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 */ 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 /* 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 */ need += need; /* 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 /* debug mode */ (void)key; @@ -18242,6 +18267,7 @@ __hot static int __must_check_result node_add_leaf2(MDBX_cursor *mc, size_t indx, const MDBX_val *key) { MDBX_page *mp = mc->mc_pg[mc->mc_top]; + MDBX_ANALYSIS_ASSUME(key != nullptr); DKBUF_DEBUG; DEBUG("add to leaf2-%spage %" PRIaPGNO " index %zi, " " 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, MDBX_val *data, unsigned flags) { + MDBX_ANALYSIS_ASSUME(key != nullptr); + MDBX_ANALYSIS_ASSUME(data != nullptr); MDBX_page *mp = mc->mc_pg[mc->mc_top]; DKBUF_DEBUG; 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]); 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. */ size_t room_threshold = likely(mc->mc_dbi != FREE_DBI) @@ -19797,9 +19825,10 @@ static int rebalance(MDBX_cursor *mc) { return rc; 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( - &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); if (unlikely(rc != MDBX_SUCCESS)) return rc; @@ -20454,7 +20483,7 @@ static int page_split(MDBX_cursor *mc, const MDBX_val *const newkey, return rc; } 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 " 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? */ - ptop += mc->mc_snum - snum; + ptop += mc->mc_snum - (size_t)snum; /* Right page might now have 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)) 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); } else { 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 */ if (meta->mm_geo.next != meta->mm_geo.now) { 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); if (aligner) { 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)) cursor_pop(mc); - rc = pnl_need(&txn->tw.retired_pages, mc->mc_db->md_branch_pages + - mc->mc_db->md_leaf_pages + - mc->mc_db->md_overflow_pages); + rc = pnl_need(&txn->tw.retired_pages, + (size_t)mc->mc_db->md_branch_pages + + (size_t)mc->mc_db->md_leaf_pages + + (size_t)mc->mc_db->md_overflow_pages); if (unlikely(rc != MDBX_SUCCESS)) goto bailout; @@ -24647,8 +24677,8 @@ uint64_t mdbx_key_from_jsonInteger(const int64_t json_integer) { assert(mantissa >= IEEE754_DOUBLE_IMPLICIT_LEAD && mantissa <= IEEE754_DOUBLE_MANTISSA_AMAX); - const uint64_t exponent = - IEEE754_DOUBLE_EXPONENTA_BIAS + IEEE754_DOUBLE_MANTISSA_SIZE - shift; + const uint64_t exponent = (uint64_t)IEEE754_DOUBLE_EXPONENTA_BIAS + + IEEE754_DOUBLE_MANTISSA_SIZE - shift; assert(exponent > 0 && exponent <= IEEE754_DOUBLE_EXPONENTA_MAX); const uint64_t key = bias + (exponent << IEEE754_DOUBLE_MANTISSA_SIZE) + (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 && mantissa <= IEEE754_DOUBLE_MANTISSA_AMAX); - const uint64_t exponent = - IEEE754_DOUBLE_EXPONENTA_BIAS + IEEE754_DOUBLE_MANTISSA_SIZE - shift; + const uint64_t exponent = (uint64_t)IEEE754_DOUBLE_EXPONENTA_BIAS + + IEEE754_DOUBLE_MANTISSA_SIZE - shift; assert(exponent > 0 && exponent <= IEEE754_DOUBLE_EXPONENTA_MAX); const uint64_t key = bias - 1 - (exponent << IEEE754_DOUBLE_MANTISSA_SIZE) - (mantissa - IEEE754_DOUBLE_IMPLICIT_LEAD); diff --git a/src/internals.h b/src/internals.h index 06cfbfd3..7bd0f96d 100644 --- a/src/internals.h +++ b/src/internals.h @@ -86,14 +86,18 @@ #pragma warning(disable : 4464) /* relative include path contains '..' */ #endif #if _MSC_VER > 1913 -#pragma warning(disable : 5045) /* Compiler will insert Spectre mitigation... \ - */ +#pragma warning(disable : 5045) /* will insert Spectre mitigation... */ #endif #if _MSC_VER > 1914 #pragma warning( \ disable : 5105) /* winbase.h(9531): warning C5105: macro expansion \ producing 'defined' has undefined behavior */ #endif +#if _MSC_VER > 1930 +#pragma warning(disable : 6235) /* is always a constant */ +#pragma warning(disable : 6237) /* is never evaluated and might \ + have side effects */ +#endif #pragma warning(disable : 4710) /* 'xyz': function not inlined */ #pragma warning(disable : 4711) /* function 'xyz' selected for automatic \ inline expansion */ @@ -1693,14 +1697,14 @@ int64pgno(int64_t i64) { MDBX_MAYBE_UNUSED MDBX_NOTHROW_CONST_FUNCTION static __inline pgno_t pgno_add(size_t base, size_t augend) { 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 pgno_sub(size_t base, size_t subtrahend) { assert(base >= MIN_PAGENO && base <= MAX_PAGENO + 1 && 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 diff --git a/src/lck-windows.c b/src/lck-windows.c index 500510d9..10c24503 100644 --- a/src/lck-windows.c +++ b/src/lck-windows.c @@ -175,7 +175,7 @@ static int funlock(mdbx_filehandle_t fd, size_t offset, size_t bytes) { #else #define DXB_MAXLEN UINT32_C(0x7ff00000) #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 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; + } const HANDLE fd4data = 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); } } - 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; + } LeaveCriticalSection(&env->me_windowsbug_lock); 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 unsigned limit = (*array)->limit; if ((*array)->count == limit) { - void *ptr = osal_realloc( - (limit > ARRAY_LENGTH((*array)->handles)) - ? *array - : /* don't free initial array on the stack */ NULL, - sizeof(mdbx_handle_array_t) + - sizeof(HANDLE) * (limit * 2 - ARRAY_LENGTH((*array)->handles))); + mdbx_handle_array_t *const ptr = + osal_realloc((limit > ARRAY_LENGTH((*array)->handles)) + ? *array + : /* don't free initial array on the stack */ NULL, + sizeof(mdbx_handle_array_t) + + sizeof(HANDLE) * (limit * (size_t)2 - + ARRAY_LENGTH((*array)->handles))); if (!ptr) return MDBX_ENOMEM; if (limit == ARRAY_LENGTH((*array)->handles)) - memcpy(ptr, *array, sizeof(mdbx_handle_array_t)); - *array = (mdbx_handle_array_t *)ptr; + *ptr = **array; + *array = ptr; (*array)->limit = limit * 2; } @@ -839,38 +848,40 @@ MDBX_SetFileIoOverlappedRange mdbx_SetFileIoOverlappedRange; #endif /* GCC/MINGW */ static void mdbx_winnt_import(void) { - const HINSTANCE hNtdll = GetModuleHandleA("ntdll.dll"); - #define GET_PROC_ADDR(dll, ENTRY) \ mdbx_##ENTRY = (MDBX_##ENTRY)GetProcAddress(dll, #ENTRY) - if (GetProcAddress(hNtdll, "wine_get_version")) { - assert(mdbx_RunningUnderWine()); - } else { - GET_PROC_ADDR(hNtdll, NtFsControlFile); - GET_PROC_ADDR(hNtdll, NtExtendSection); - assert(!mdbx_RunningUnderWine()); + const HINSTANCE hNtdll = GetModuleHandleA("ntdll.dll"); + if (hNtdll) { + if (GetProcAddress(hNtdll, "wine_get_version")) { + assert(mdbx_RunningUnderWine()); + } else { + GET_PROC_ADDR(hNtdll, NtFsControlFile); + GET_PROC_ADDR(hNtdll, NtExtendSection); + assert(!mdbx_RunningUnderWine()); + } } const HINSTANCE hKernel32dll = GetModuleHandleA("kernel32.dll"); - GET_PROC_ADDR(hKernel32dll, GetFileInformationByHandleEx); - GET_PROC_ADDR(hKernel32dll, GetTickCount64); - if (!mdbx_GetTickCount64) - mdbx_GetTickCount64 = stub_GetTickCount64; - if (!mdbx_RunningUnderWine()) { - GET_PROC_ADDR(hKernel32dll, SetFileInformationByHandle); - GET_PROC_ADDR(hKernel32dll, GetVolumeInformationByHandleW); - GET_PROC_ADDR(hKernel32dll, GetFinalPathNameByHandleW); - GET_PROC_ADDR(hKernel32dll, PrefetchVirtualMemory); - GET_PROC_ADDR(hKernel32dll, SetFileIoOverlappedRange); + if (hKernel32dll) { + GET_PROC_ADDR(hKernel32dll, GetFileInformationByHandleEx); + GET_PROC_ADDR(hKernel32dll, GetTickCount64); + if (!mdbx_GetTickCount64) + mdbx_GetTickCount64 = stub_GetTickCount64; + if (!mdbx_RunningUnderWine()) { + GET_PROC_ADDR(hKernel32dll, SetFileInformationByHandle); + GET_PROC_ADDR(hKernel32dll, GetVolumeInformationByHandleW); + GET_PROC_ADDR(hKernel32dll, GetFinalPathNameByHandleW); + GET_PROC_ADDR(hKernel32dll, PrefetchVirtualMemory); + GET_PROC_ADDR(hKernel32dll, SetFileIoOverlappedRange); + } } - const HINSTANCE hAdvapi32dll = GetModuleHandleA("advapi32.dll"); - GET_PROC_ADDR(hAdvapi32dll, RegGetValueA); -#undef GET_PROC_ADDR - - const osal_srwlock_t_function init = (osal_srwlock_t_function)GetProcAddress( - hKernel32dll, "InitializeSRWLock"); + const osal_srwlock_t_function init = + (osal_srwlock_t_function)(hKernel32dll + ? GetProcAddress(hKernel32dll, + "InitializeSRWLock") + : nullptr); if (init != NULL) { osal_srwlock_Init = init; 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_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) diff --git a/src/mdbx_chk.c b/src/mdbx_chk.c index 7a13e733..a8c97372 100644 --- a/src/mdbx_chk.c +++ b/src/mdbx_chk.c @@ -571,8 +571,8 @@ static int pgvisitor(const uint64_t pgno, const unsigned pgnumber, data_tree_problems += !is_gc_tree; gc_tree_problems += is_gc_tree; } else { - dbi->payload_bytes += payload_bytes + header_bytes; - walk.total_payload_bytes += payload_bytes + header_bytes; + dbi->payload_bytes += (uint64_t)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 span = 1; - for (unsigned i = 0; i < number; ++i) { + for (size_t i = 0; i < number; ++i) { if (check_user_break()) return MDBX_EINTR; 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)) { bad = " [bad sequence]"; problem_add("entry", txnid, "bad sequence", - "%" PRIaPGNO " %c [%u].%" PRIaPGNO, prev, + "%" PRIaPGNO " %c [%zu].%" PRIaPGNO, prev, (prev == pgno) ? '=' : (MDBX_PNL_ASCENDING ? '>' : '<'), i, pgno); } @@ -677,7 +677,7 @@ static int handle_freedb(const uint64_t record_number, const MDBX_val *key, " pages, maxspan %" PRIaPGNO "%s\n", txnid, number, span, bad); 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]; for (span = 1; i + span < number && diff --git a/src/mdbx_load.c b/src/mdbx_load.c index 8a7a191a..552fedc8 100644 --- a/src/mdbx_load.c +++ b/src/mdbx_load.c @@ -673,7 +673,7 @@ int main(int argc, char *argv[]) { 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 (!quiet) fprintf(stderr, "mdbx_env_get_maxkeysize() failed, returns %zu\n", diff --git a/src/osal.c b/src/osal.c index f5630324..748767ba 100644 --- a/src/osal.c +++ b/src/osal.c @@ -48,6 +48,7 @@ static int ntstatus2errcode(NTSTATUS status) { OVERLAPPED ov; memset(&ov, 0, sizeof(ov)); ov.Internal = status; + MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(6387, "'_Param_(1)' could be '0'"); return GetOverlappedResult(NULL, &ov, &dummy, FALSE) ? MDBX_SUCCESS : (int)GetLastError(); } @@ -82,6 +83,8 @@ extern NTSTATUS NTAPI NtMapViewOfSection( extern NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN OPTIONAL PVOID BaseAddress); +MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(28251, + "Inconsistent annotation for 'NtClose'...") extern NTSTATUS NTAPI NtClose(HANDLE Handle); extern NTSTATUS NTAPI NtAllocateVirtualMemory( @@ -320,7 +323,7 @@ MDBX_INTERNAL_FUNC int osal_vasprintf(char **strp, const char *fmt, return needed; } - *strp = osal_malloc(needed + 1); + *strp = osal_malloc(needed + (size_t)1); if (unlikely(*strp == nullptr)) { va_end(ones); #if defined(_WIN32) || defined(_WIN64) @@ -331,7 +334,7 @@ MDBX_INTERNAL_FUNC int osal_vasprintf(char **strp, const char *fmt, return -1; } - int actual = vsnprintf(*strp, needed + 1, fmt, ones); + int actual = vsnprintf(*strp, needed + (size_t)1, fmt, ones); va_end(ones); 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 | (uintptr_t)(uint64_t)item->sgv[0].Buffer) & 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((item->single.iov_len & ior_WriteFile_flag) == 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) { data = Ptr64ToPtr(item->sgv[0].Buffer); bytes = ior->pagesize; + MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER( + 6385, "Reading invalid data from 'item->sgv'"); while (item->sgv[i].Buffer) { if (data + ior->pagesize != item->sgv[i].Buffer) { 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) { assert(ior->overlapped_fd && fd == ior->overlapped_fd); bytes = ior->pagesize; + MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER( + 6385, "Reading invalid data from 'item->sgv'"); while (item->sgv[i].Buffer) { bytes += ior->pagesize; ++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; if (bytes & ior_WriteFile_flag) { bytes = ior->pagesize; + MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER( + 6385, "Reading invalid data from 'item->sgv'"); while (item->sgv[i].Buffer) { bytes += ior->pagesize; ++i; @@ -1078,9 +1087,12 @@ MDBX_INTERNAL_FUNC void osal_ioring_reset(osal_ioring_t *ior) { if (item->ov.hEvent && item->ov.hEvent != ior) ior_put_event(ior, item->ov.hEvent); 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) ++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) { osal_ioring_reset(ior); #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]); + } ior->event_stack = 0; #else (void)since; @@ -2734,6 +2749,7 @@ retry_mapview:; #endif /* POSIX / Windows */ + MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(6287, "Redundant code"); assert(rc != MDBX_SUCCESS || (map->base != nullptr && map->base != MAP_FAILED && map->current == size && map->limit == limit && diff --git a/test/chrono.c++ b/test/chrono.c++ index 71273e92..4d53b60d 100644 --- a/test/chrono.c++ +++ b/test/chrono.c++ @@ -87,10 +87,11 @@ time from_ms(uint64_t ms) { time now_realtime() { #if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS) static void(WINAPI * query_time)(LPFILETIME); - if (!query_time) { - query_time = (void(WINAPI *)(LPFILETIME))GetProcAddress( - GetModuleHandle(TEXT("kernel32.dll")), - "GetSystemTimePreciseAsFileTime"); + if (unlikely(!query_time)) { + HMODULE hModule = GetModuleHandle(TEXT("kernel32.dll")); + if (hModule) + query_time = (void(WINAPI *)(LPFILETIME))GetProcAddress( + hModule, "GetSystemTimePreciseAsFileTime"); if (!query_time) query_time = GetSystemTimeAsFileTime; } diff --git a/test/keygen.c++ b/test/keygen.c++ index e8e53262..a6d20f33 100644 --- a/test/keygen.c++ +++ b/test/keygen.c++ @@ -227,7 +227,8 @@ void maker::setup(const config::actor_params_pod &actor, unsigned actor_id, (void)thread_number; 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(); } @@ -315,11 +316,12 @@ void __hot maker::mk_begin(const serial_t serial, const essentials ¶ms, out.value.iov_len = std::max(unsigned(params.minlen), length(serial)); const auto variation = params.maxlen - params.minlen; if (variation) { - if (serial % (variation + 1)) { + if (serial % (variation + serial_t(1))) { auto refix = serial * UINT64_C(48835288005252737); refix ^= refix >> 32; - out.value.iov_len = std::max( - out.value.iov_len, params.minlen + 1 + size_t(refix) % variation); + out.value.iov_len = + std::max(out.value.iov_len, + params.minlen + size_t(1) + size_t(refix) % variation); } } diff --git a/test/log.c++ b/test/log.c++ index bc52432e..04dad84d 100644 --- a/test/log.c++ +++ b/test/log.c++ @@ -142,7 +142,7 @@ void output_nocheckloglevel_ap(const logging::loglevel priority, prefix.c_str(), level2str(priority), suffix.c_str()); 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)) va_copy(ones, ap); vfprintf(last, format, ap); @@ -153,11 +153,11 @@ void output_nocheckloglevel_ap(const logging::loglevel priority, switch (end) { default: putc('\n', last); - // fall through + MDBX_CXX17_FALLTHROUGH; // fall through case '\n': fflush(last); last = nullptr; - // fall through + MDBX_CXX17_FALLTHROUGH; // fall through case ' ': case '_': case ':': diff --git a/test/osal-windows.c++ b/test/osal-windows.c++ index 57746532..24cde253 100644 --- a/test/osal-windows.c++ +++ b/test/osal-windows.c++ @@ -248,7 +248,7 @@ Environment: CommandLine.push_back('"'); for (auto It = Argument.begin();; ++It) { - unsigned NumberBackslashes = 0; + size_t NumberBackslashes = 0; while (It != Argument.end() && *It == '\\') { ++It; @@ -435,7 +435,7 @@ void osal_udelay(size_t us) { unsigned timeslice_ms = 1; while (timeBeginPeriod(timeslice_ms) == TIMERR_NOCANDO) ++timeslice_ms; - threshold_us = timeslice_ms * 1500u; + threshold_us = timeslice_ms * size_t(1500); assert(threshold_us > 0); } diff --git a/test/test.c++ b/test/test.c++ index 1e8429c5..77c90c0a 100644 --- a/test/test.c++ +++ b/test/test.c++ @@ -100,7 +100,7 @@ int testcase::hsr_callback(const MDBX_env *env, const MDBX_txn *txn, info.mi_geo.current >= info.mi_geo.upper)) { osal_yield(); if (retry > 0) - osal_udelay(retry * 100); + osal_udelay(retry * size_t(100)); return MDBX_RESULT_FALSE /* retry / wait until reader done */; } diff --git a/test/test.h++ b/test/test.h++ index 52a2add3..6158ba66 100644 --- a/test/test.h++ +++ b/test/test.h++ @@ -101,10 +101,10 @@ class testcase; class registry { struct record { - actor_testcase id; + actor_testcase id = ac_none; std::string name; - bool (*review_params)(actor_params &); - testcase *(*constructor)(const actor_config &, const mdbx_pid_t); + bool (*review_params)(actor_params &) = nullptr; + testcase *(*constructor)(const actor_config &, const mdbx_pid_t) = nullptr; }; std::unordered_map name2id; std::unordered_map id2record;