Skip to content

unified and cleaned up CI scripts - #6

Merged
mikucionisaau merged 45 commits into
mainfrom
ci-scripts
May 28, 2026
Merged

unified and cleaned up CI scripts#6
mikucionisaau merged 45 commits into
mainfrom
ci-scripts

Conversation

@mikucionisaau

@mikucionisaau mikucionisaau commented May 13, 2026

Copy link
Copy Markdown
Member
  • unified CI scripts
  • added formatting and clang-tidy
  • moved and renamed __ variables into ptrie::internal namespace
  • fixed many other clang-tidy complaints
  • Added heaptrack analysis of heap and potential leaks

mikucionisaau and others added 30 commits May 13, 2026 10:35
…g (it seems to expect unsigned, whereas we are passing size_t)
…idy-18 does not understand source-filter option
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Inserts 20-byte keys (> default HEAPBOUND of 17) so the key suffix is
heap-allocated via new_uchar and its raw pointer embedded in the node
bucket.  Running under ASAN confirms the destructor frees every such
allocation without leaking.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New Node At Depth One: exercises ptrie_internal.hpp:1252 (node = new
node_t{}) with byte==1 and base==fwd.  Six 128-byte keys fill a leaf
whose split_fwd sets fwd_n->_children[0..127] to self-loops; the 7th
insert (5 bytes, nitemsize=4 < HEAPBOUND) finds such a self-loop at
depth 1, triggering the base==fwd path and allocating the new node.

Split Node Both Partitions: exercises ptrie_internal.hpp:1154 (h_node =
new node_t{}) when both low and high partitions of a split_node are
non-empty.  Five 64-byte keys plus one 4-byte key fill a leaf; after
split_fwd the recursive split_node at p_byte=1 finds f[1]=0x40 for the
long keys (HIGH) and f[1]=0x04 for the short key (LOW), creating h_node.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
write_data admits a symbolic path where size=0 after (stored_uint16 >> 8),
making both pos<size guards false and leaving the returned key uninitialized.
Remove the suppressing key_t{} zero-init in operator* and add an iterator
value-correctness test that drives 200 ints through write_data (forcing fwd
splits so ps≥1 nodes are exercised) and verifies each dereferenced value via
set.exists() under UBSAN.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reverts the uninitialized key_t key; back to auto key = key_t{};
so the clang-analyzer-core.uninitialized.UndefReturn false positive is
suppressed by construction: even if write_data somehow exits without
writing all bytes the return value is still defined.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
clang-tidy flags node->_count + 1 as a garbage-value operation because its
symbolic model does not track the in-class initializer `uint16_t _count = 0`
on node_t, treating new node_t{} as leaving _count uninitialised.  The new
test drives the base==fwd insertion path (first insert into an empty set),
verifies correct insert/exists/duplicate semantics, and lets ASAN/UBSAN
confirm that _count is properly zero-initialised on every fresh-node alloc.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
_count garbage value (line 1293):
  The analyzer does not track the in-class initializer
  `uint16_t _count = 0` on node_t, so it models new node_t{} as leaving
  _count uninitialized.  Add an explicit `node->_count = 0` assignment
  immediately after the allocation so the initialisation is visible to
  the symbolic model.

dest potential leak (line 1401):
  The heap key suffix allocated by new_uchar is embedded into nbucket via
  mem_store (a byte-level copy).  The analyzer cannot follow the pointer
  through this type-punning operation and reports it as potentially leaked
  when nbucket is moved into node->_data.  Suppress with NOLINTNEXTLINE at
  the diagnostic site; the pointer is freed by delete_uchar during cleanup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
as clang-tidy seems to require files which are generated during the actual build
@mikucionisaau
mikucionisaau marked this pull request as draft May 22, 2026 15:15
mikucionisaau and others added 15 commits May 22, 2026 17:16
Brought the build/test/lint/CI docs in line with the ci-scripts branch:
the merged tidy workflow, GCC-14/Clang-20 toolchains, release-deb presets,
heaptrack test variants, and example/ consumption checks.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Instruments the ptrie test targets and adds a `coverage` target that
produces an HTML + textual report: gcov/lcov for GCC, llvm-cov for Clang.
lcov >= 2.0 is handled via --ignore-errors unused so the never-matched
benchmark exclude pattern does not abort the report.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Added a "Code Coverage" section to README.md (build steps, tooling per
compiler, required packages) and moved the llvm-cov "mismatched data"
explanation there from cmake/coverage.cmake. Also pass
geninfo_unexecuted_blocks=1 to lcov capture so inlined/templated code
no longer triggers "unexecuted block ... with non-zero hit count".

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
"Erase Missing Keys" exercises erase() on absent keys (empty trie, never
inserted, double erase, prefix-sharing longer key), closing the only real
coverage gap among the deletion functions. Two further cases ("Erase Keeps
Dense Node", "Erase Deep Subtree Collapse") add partial- and deep-deletion
regression coverage.

The remaining uncovered lines in merge_regular/merge_empty are unreachable
defensive guards: merge_down already returns on the same count>SPLITBOUND/3
check before calling merge_regular, the differing-sibling-type branch is
preceded by a block that always returns, and merge_empty's upward-collapse
loop only runs at the final root-level collapse.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adding tests that copy tries with heap-stored (long) and multi-entry inline
keys uncovered three bugs in node_t::clone, all in branches no prior test
exercised:
  - inline copy used an end iterator of data()+(lencsize-bdepth) without the
    per-entry offset, dropping every entry after the first;
  - the deep heap branch copied `encsize` bytes into an `encsize-bdepth`
    buffer (heap overflow);
  - the shallow heap branch accessed the stored pointer via as_array at an
    unaligned offset (UBSan misalignment).
The heap branches now use mem_load/mem_store like the rest of the code.

New cases (Copy Heap Keys Shallow/Deep, Copy Inline Keys) cover these paths
and assert deep-copy independence; the full suite passes under ASAN+UBSAN+SSP.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Forces a shared first byte to split fully and advance to the next byte while
suffixes are heap-stored, so split_fwd's move_data must migrate heap pointers.
Acts as a deterministic regression guard for that path, which existing random
split tests only exercise incidentally (and which lcov under-reports because
move_data is a generic lambda). Passes under ASAN+UBSAN+SSP.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…s on modmap files that clang-tidy cannot find
@mikucionisaau
mikucionisaau marked this pull request as ready for review May 28, 2026 07:20
@mikucionisaau
mikucionisaau merged commit ae61251 into main May 28, 2026
6 of 12 checks passed
@mikucionisaau
mikucionisaau deleted the ci-scripts branch May 28, 2026 07:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant