Skip to content

Fix CI on develop after #5600, #5607, and #5755 - #5764

Merged
nlohmann merged 9 commits into
developfrom
fix/develop-ci-2026-10-05
Oct 6, 2026
Merged

nlohmann merged 9 commits into
developfrom
fix/develop-ci-2026-10-05

Conversation

@nlohmann

@nlohmann nlohmann commented Oct 5, 2026 •

Copy link
Copy Markdown
Owner

On develop (23d3b37), the Ubuntu and Publish documentation workflows and the AppVeyor build fail. There are five separate causes. Most of the other red Ubuntu jobs were only cancelled by fail-fast.

1. -Warith-conversion in the CBOR reader (#5607)

ci_test_gcc and ci_test_standards_gcc fail at binary_reader.hpp:668 when number_integer_t is short (the narrow-type tests in unit-msgpack.cpp). static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(number) is promoted to int. Converting it back to short implicitly is a -Werror=arith-conversion error. The fix casts the result back with conditional_static_cast, as the BON8 reader already does.

2. Deleted friend operators with old compilers (#5755)

With JSON_DELETE_DEPRECATED_FUNCTIONS, the deprecated stream operators j >> o and j << i were friend ... = delete; inside basic_json. Older compilers reject this:

  • GCC 4.8 and 4.9: can't initialize friend function
  • Clang 7, 8 and 9: redefinition of 'operator>>' once two specializations exist

I checked the affected versions with minimal reproducers in the CI Docker images. Clang 3.4/3.5 and Clang ≥ 10 accept it.

The fix keeps the friend definitions only when the functions are not deleted. When they are, deleted function templates at namespace scope (NLOHMANN_BASIC_JSON_TPL_DECLARATION) take their place, and ADL finds them the same way. unit-delete_deprecated_functions.cpp now compiles with Clang 3.4, 7, 8, 9 and latest, and with GCC 4.9.

3. Documentation style check (#5600)

check_structure.py rejects json_use_objects_for_enum_keyed_maps.md: example titles need the "Example: …" form, and the page had no docset entry. Both are fixed. make style_check and mkdocs build --strict pass locally.

4. libstdc++ <format> under -fsanitize=integer (toolchain)

ci_test_clang_sanitizer (silkeh/clang:22, libstdc++ 14.2) fails in test-std-format_cpp20 at format:3906. There, _Scanner(basic_string_view<_CharT>, size_t __nargs = -1) converts -1 to size_t, which implicit-integer-sign-change reports for every std::format call. This is GCC bug 119429, not a library bug; develop fails the same way. Thanks to @fhgffy for pinning it down in #5760.

The new cmake/clang_sanitizer_ignorelist.txt, passed via -fsanitize-ignorelist, excludes only that check and only that header. A deliberate sign change in a test file is still reported, and unit-std-format.cpp passes under the CI's UBSan flags in silkeh/clang:22.

5. AppVeyor: MSVC 2015, 2017 and 2019 (#5607, #5751, #5754)

All AppVeyor jobs fail, and PR builds that merged develop on 10-04 failed the same way:

Validation

  • A full ci_test_gcc build in gcc:latest with the CI flags (-Werror) compiles every target. The only failing tests are FetchContent/git-clone tests, which need network access that my container did not have.
  • Amalgamation was regenerated with make amalgamate.

Public API

No breaking changes. The noexcept of the scalar comparison operators is unchanged; it is only spelled differently. Without JSON_DELETE_DEPRECATED_FUNCTIONS, nothing changes. With it, the two deprecated stream operators are still deleted. They are now namespace-scope function templates instead of hidden friends, so using them is still a compile error.

🤖 Generated with Claude Code

- binary_reader: cast the result of -1 - number back to number_integer_t,
  because a number_integer_t narrower than int is promoted to int, which
  GCC's -Warith-conversion rejects (ci_test_gcc, ci_test_standards_gcc)
- JSON_DELETE_DEPRECATED_FUNCTIONS: declare the deleted stream operators
  as function templates at namespace scope, because GCC < 5 rejects deleted
  friend functions ("can't initialize friend function") and Clang 7-9 report
  a redefinition when a class template has a deleted friend function
- docs: give the examples of JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS "Example:"
  titles and add the page to the docset (style_check)

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
libstdc++ 14's <format> initializes a size_t parameter with -1 (GCC bug
119429), so every std::format call fails ci_test_clang_sanitizer under
-fsanitize=integer (test-std-format_cpp20). Exclude only the
implicit-integer-sign-change check and only that header via
-fsanitize-ignorelist.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
@github-actions github-actions Bot added the CMake label Oct 5, 2026
- binary_reader: emit_signed/emit_unsigned pass integers that do not fit
  the number types to emit_float as long double, because MSVC's <cmath>
  has no integer overloads of std::isfinite (C2668 'fpclassify'), from #5607
- scalar comparisons: the friend operators take the JSON type for their
  noexcept from their parameter, because MSVC 2015/2017 take basic_json as
  the class template there (C3203) and MSVC 2019 16.0 does not see member
  types or template parameters, from #5751
- unit-conversions2: skip the !is_nothrow_constructible static_assert for
  std::optional on MSVC 2017, which evaluates the conditional noexcept as
  true (C2607), from #5754

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
@github-actions github-actions Bot added L tests and removed M labels Oct 5, 2026
@github-actions

This comment was marked as outdated.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
MSVC 2015 warns about any conversion to bool (C4800), even with an
explicit cast, so the enum conversions from #5754 (#5671) failed the
AppVeyor build with /WX. Convert to bool by comparing with zero via the
new detail::bool_aware_static_cast, and keep doctest from printing the
enum in the test.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
MSVC 2015's debug STL constructs the containers' debug proxies through
the allocator in noexcept constructors, so countdown_allocator's failing
construction crashes test-allocator (SIGSEGV) instead of throwing
std::bad_alloc. Use the guard #5585 uses for the same reason.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
MSVC 2015 does not treat selecting a deleted function in decltype as a
substitution failure, so the detection traits in
unit-delete_deprecated_functions (#5755) and the integral-key checks in
unit-element_access2 (#5657) report deleted overloads as callable there.
Calling them still fails to compile. Skip those checks for
_MSC_VER < 1910, and use the stream operators for real in the runtime
section, so MSVC 2015 still compiles them with the macro set.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
The VS 2017 jobs hit AppVeyor's 60-minute limit per job while still
compiling the tests (77 of about 108 test targets after 58 minutes).
They pass /std:c++17 for everything anyway, so build only the C++17
variant of each test (JSON_TestStandards=17), and split the unit test
files across two jobs each with the new JSON_TestShard=<index>/<count>
option, which keeps every <count>-th test file starting at <index>.
The extra variants of single test files are built in shard 0 only.

CMAKE_OPTIONS is no longer quoted in appveyor.yml, so that it can hold
more than one option.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
@github-actions github-actions Bot added the CI label Oct 5, 2026
MSVC 2017 evaluates std::is_nothrow_assignable<json&, const T&> as true
even if T's to_json throws, so to_json(json&, const std::optional<T>&)
was noexcept there and the exception from #5642's test called
std::terminate instead of propagating. Make that conversion never
noexcept on MSVC 2017; all other compilers keep the exact condition.
The static_asserts on the condition are skipped for MSVC 2017; the
runtime check that the exception propagates still runs there.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
@nlohmann nlohmann added this to the Release 3.13.0 milestone Oct 6, 2026
@nlohmann
nlohmann merged commit 8a142bc into develop Oct 6, 2026
256 of 269 checks passed
@nlohmann
nlohmann deleted the fix/develop-ci-2026-10-05 branch October 6, 2026 05:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants