Skip to content

Prepare the 6.5.0 release - #272

Merged
zayenz merged 42 commits into
mainfrom
feature/6.5.0
Oct 31, 2026
Merged

zayenz merged 42 commits into
mainfrom
feature/6.5.0

Conversation

@zayenz

@zayenz zayenz commented Oct 31, 2026 •

Copy link
Copy Markdown
Member

This prepares the 6.5.0 release on top of main. It holds the last fixes and cleanups, sets the build version and ABI, and ends with the release notes, dated 2026-10-31.

What's in it

The commits are ordered so the release commits come last:

  • Release cleanups.
    • Regenerated Makefile.dep, rewrote the 6.5.0 changelog entries, and fixed Doxygen issues.
    • Moved worker-control and build details into the reference docs, and cleaned up the README.
    • Consolidated tests and trimmed duplicate CI checks.
    • Made negated CI checks fail the job.
    • Added AGENTS.md, with a CLAUDE.md that includes it.
  • Kernel, search, and FlatZinc fixes.
    • Brancher callback disposal, invalid downcasts of the list end markers, and the trace recorder check.
    • Stale stop decisions in parallel search.
    • FlatZinc parser leaks and cleanup when parsing fails, and the registry split by constraint family.
  • Link fix. Search::Builder's destructor is now defined in the search library. Before this, clang emitted its vtable in int, set, float, and instance, so those libraries referenced worker-control symbols without linking search. Its memory still comes from Gecode's heap, so allocation and freeing stay in one library on Windows. The gecode-instance tool no longer needs to link search to work around this.
  • Fixes from sanitizer runs. All of these bugs are also in 6.4.0:
    • leaks in tie-break limited variable selection, in PBS and RBS on a failed root, in LDS resets, in LDSB set branchers, and of the array index in FlatZinc annotations;
    • signed integer overflow in unary no-run pruning and in bounds-consistent distinct near the integer limits.
  • Smaller corrections.
    • magic-square-partial is now built by Autoconf.
    • The minimodel dependency note in the build reference is corrected.
    • The PBS::constrain changelog entry is added.
  • Release. The build version is set to 6.5.0, with library ABI 52. The README names 6.5.0, and the last commit writes the release notes.

Testing

  • Full sweep: 47,824 tests passed in a macOS Release build.
  • Sanitizers:
    • Standard tests passed under ASan with GCC 15 on Linux.
    • Standard tests passed under UBSan with Apple Clang, with no reports from the patched code.
  • Release branch:
    • check passed 539/539.
    • All Search tests passed (25,816).
    • Focused LDSB, PBS, RBS, Unary, Distinct, Branch, and Instance selections passed.
    • The changelog tidy check passed.
    • Regenerating Makefile.dep gave no diff.
  • Linking (Linux, clang Debug, -Wl,--no-undefined): the int, set, float, and instance libraries have no undefined Search:: symbols. gecode-instance links only instance, int, kernel, and support. The Autoconf build links and runs it too.
  • Reviews: two independent reviews of the release candidate found no blocking issues. Their findings are fixed here, apart from the items below.

Left for after 6.5.0

None of these is a regression in 6.5.0:

  • the cutoff of an RBS builder in a portfolio whose root space fails leaks, because a builder that never builds an engine does not own its cutoff;
  • integer overflow in the theta-tree arithmetic (gecode/int/task/tree.hpp) near the integer limits;
  • reading past the arguments of a FlatZinc constraint given too few of them, because Registry::post does not check arity;
  • clock-based temporary file names and a 10-second limit in test/instance.cpp, which may explain one Instance test failure that could not be reproduced;
  • FlatZinc-level coverage of cumulatives with variable starts, and worker control combined with stop objects.

zayenz added 30 commits October 31, 2026 11:48
Regenerate the dependencies with make depend for a build with
experimental APIs enabled. This adds the rules for open lists, the
heuristic search engines and their examples, and refreshes the
existing rules.
Add STATISTICS markers to the allocator package test header and the
common-pattern example header, which the documentation statistics
otherwise report as unclassified.
Describe each unreleased change by its effect for users, group the
entries by module, and keep the experimental entries together. Add the
missing entries for the CMake configuration report and the test-run
totals from #252.
Keep the WorkerControl contract in the Doxygen documentation of
gecode/search.hh instead of a separate docs/worker-control.md. Move the
CMake build details from README.md into docs/cmake-build.md, so the
README gives an overview and points to the build reference.
Doxygen reads @ as the start of a command, so credits that contain
GitHub handles were rendered incorrectly. Escape them when generating
the changelog page and when tidy checks the generated text.
Raise the minimum Doxygen version to 1.18 in both build systems.
Predefine the test-harness export macros so their declarations are
documented, and describe how a downstream project builds a propagator
test against an installed harness.
Describe OpenViewList and Test::Int::OpenTest in the changelog and in
the Doxygen overview.
The gcd, divides, product, and product_mod posting functions ignore the
propagation level, so test them once rather than once per level.
Replace the bespoke sparse-table fixtures with the shared table harness,
and make the unmerged-terminal DFA test both accept and reject words at
its final layer. Build the tuple-set size tests from a temporary
instead of leaking a heap-allocated factory.
Give each cumulatives overload a small instance whose machine, resource,
or duration values are forced, so a wrong argument mapping changes the
output. Check forced matching-count outputs, and keep one end-to-end
check of a NUL in a blackbox response.
Parse the printed float values of the restart test and compare them
with a tolerance instead of as exact text.
A worker can decide to stop during one call of next() and only report
it during a later call. In a parallel portfolio this happened when a
worker saw the internal stop of the previous portfolio run: the asset
then stopped without any stop object asking for it, and the portfolio
reported that it had stopped. Number the calls of next() and ignore
stops decided during an earlier call.

Worker control made this likely: paused workers check the stop
condition each time a request wakes them.
Move random worker resizing out of the general search matrix into one
focused test that resizes DFS, BAB, RBS, and portfolio engines from
other threads while they search to completion. Run the sequential pause
test with several workers. Check each incremental open-list constraint
on its own, so a constraint that stops propagating is detected.
DFS clones the root space, so let it use caller-owned spaces directly
instead of leaking extra clones. Remove the IntSet and Boolean
expression failure points and the tests that used them: those
allocations already go through the heap failure point, which the
remaining heap-failure tests exercise.
Keep the check that an unresolved nonzero constraint remains for
assigned adjacent intervals, and document why, without requiring an
exact number of actors.
GECODE_NEVER expands to nothing in release builds, which left the
solution check without a return value on its default path.
Check component aliases without rebuilding duplicate consumers, test the
package version policy directly, and verify generated custom variable
types by content. Write the integer public smoke test in the same style
as the set and float tests.
Bash does not apply set -e to a command negated with !, so these checks
could never fail. Exit explicitly when the unwanted text is found.
View and value branchers registered for disposal when they held filter
or print callbacks but never released them, so the shared callback
objects and their captures leaked.
The disposal list holds branchers as well as propagators. Cast entries
to TraceRecorder before checking whether they are disabled, instead of
reading propagator state from every entry.
The brancher cursors and the iterator end points can refer to the list
end markers, which are not actors. Store them as links and downcast only
after checking for the end of the list.
The FlatZinc search setup created a restart cutoff even when restarts
were disabled. Only create it for restart-based search.
Move the set, float, and cumulatives posters into separate translation
units to reduce peak compiler memory, keeping the registered names,
aliases, order, and feature guards. Registration still calls each family
directly, so static linking includes every enabled family. Check this in
the installed-consumer smoke tests on Unix and Windows.
Dispose of copied set lists, scalar literals, and alias specifications,
and of constraint expressions that are handled without being posted.
Free the original domain when an equality makes one variable an alias
of another, and free the domain of an array declaration with an
initializer once it has been copied to each element.
Close the descriptor right after mapping the file and unmap it when
parsing ends, including on errors. Use fstat on the opened descriptor
and close it when stat or mapping fails.
Let the parser state release its scanner and any remaining variable
specifications, constraints, and output. Own spaces created by parse()
until it succeeds, and leave caller-supplied spaces with the caller,
documenting that such a space should be discarded after a failure.
The mimalloc rename header only exists in mimalloc CMake builds, so
make depend stopped at its guarded include in allocator.cpp. Skip quoted
includes that do not exist, and write dependency lines without trailing
spaces so the output matches the checked-in Makefile.dep.
Add AGENTS.md with an overview of the project and of constraint
programming, the conventions for new code, the obligations of
propagators, branchers, and search engines, how to test a change with
the native test framework, how to maintain the build files and
generated sources, where documentation belongs, and how the changelog
and version are kept. Add a CLAUDE.md that includes it, and link the
guide from the README.
A release description ran until the next [ENTRY], so an empty section
at the top of changelog.in, as opened for the next development release,
absorbed the following release header and its entries. End the
description at the next [RELEASE] as well in all three generators and
in the tidy parser, and add an empty-section regression to the tidy
check. Output for the current changelog is unchanged.
The Autoconf jobs all enabled the experimental preview APIs, so the
default Autoconf configuration had no coverage. Keep the Ubuntu job
experimental and build the macOS and MinGW jobs with the default
configuration.
Builder's virtual destructor was its key function but defined inline, so
Clang emitted its vtable in every file including search.hh. The vtable
pulls in the Options destructor and with it the out-of-line WorkerControl
destructor, which left the int, set, float, and instance libraries with an
undefined reference to the search library they do not link. Defining the
destructor in the search library emits the vtable only there.

The gecode-instance tool no longer needs to link the search library to
work around this.
zayenz added 12 commits October 31, 2026 11:48
Minimodel builds without set variables.
It was only listed in the CMake example list.
ViewSelChooseTbl::dispose destroyed its table but not the merit function of
its base, so the merit function's shared data and any action or CHB handle
leaked.
PBS with explicit builders and RBS returned a dead engine for a failed root
without freeing the builders or the cutoff they own. LDS deleted the spaces
on its stack when it was reset or deleted, but not their choices.
The no-run ranges of unary tasks were computed in int and could overflow
near the integer limits; compute them with long long and clamp them. The
Hall intervals of bounds distinct reach max_x+3, so use long long near the
upper limit too, and compute the value spread without overflow.
LDSBSetBrancher had no dispose, so its IntSet of left-branch values leaked.
The annotation rule for array accesses read the index but never deleted it,
so every indexed variable in a search annotation leaked its index literal.
Delete it as the expression rule already does.
The 6.5.0 changes alter Space, Search::Options, and inline kernel code,
so libraries built from this tree are not binary compatible with 6.4.0.
Keep the README user-facing: point to the tutorial and reference
documentation, the build reference, and the repository guide, and drop
maintainer guidance that belongs in docs/.
Lead with the public test harness, followed by worker control and open
variable lists, then the remaining additions and fixes. Describe the
experimental search engines separately, and end with the mimalloc
recommendation. Set the release date to 2026-10-31.
@zayenz
zayenz merged commit 599f977 into main Oct 31, 2026
16 checks passed
@zayenz
zayenz deleted the feature/6.5.0 branch October 31, 2026 13:52
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