Repository navigation
Fix CI on develop after #5600, #5607, and #5755 - #5764
Merged
Merged
Conversation
- 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>
3 of 4 tasks
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>
- 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>
This comment was marked as outdated.
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>
gregmarr
approved these changes
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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-conversionin the CBOR reader (#5607)ci_test_gccandci_test_standards_gccfail atbinary_reader.hpp:668whennumber_integer_tisshort(the narrow-type tests inunit-msgpack.cpp).static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(number)is promoted toint. Converting it back toshortimplicitly is a-Werror=arith-conversionerror. The fix casts the result back withconditional_static_cast, as the BON8 reader already does.2. Deleted friend operators with old compilers (#5755)
With
JSON_DELETE_DEPRECATED_FUNCTIONS, the deprecated stream operatorsj >> oandj << iwerefriend ... = delete;insidebasic_json. Older compilers reject this:can't initialize friend functionredefinition of 'operator>>'once two specializations existI 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.cppnow compiles with Clang 3.4, 7, 8, 9 and latest, and with GCC 4.9.3. Documentation style check (#5600)
check_structure.pyrejectsjson_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_checkandmkdocs build --strictpass locally.4. libstdc++
<format>under-fsanitize=integer(toolchain)ci_test_clang_sanitizer(silkeh/clang:22, libstdc++ 14.2) fails intest-std-format_cpp20atformat:3906. There,_Scanner(basic_string_view<_CharT>, size_t __nargs = -1)converts-1tosize_t, whichimplicit-integer-sign-changereports for everystd::formatcall. 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, andunit-std-format.cpppasses under the CI's UBSan flags insilkeh/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:
fpclassify(all versions, Handle numbers that do not fit narrow number types in the binary readers #5607):emit_signed/emit_unsignedpassed integers toemit_float, which callsstd::isfinite. MSVC's<cmath>has no integer overloads for it. Integers are now converted tolong doublefirst, asget_cbor_negative_integeralready does.noexceptof the in-class friend scalar comparisons, these versions takebasic_jsonas the class template. On Compiler Explorer, MSVC 2019 16.0 rejects member aliases (basic_json_t) and template parameters in the same position. Only the function parameters are visible there, so the friends now usestd::is_nothrow_constructible<detail::uncvref_t<decltype(lhs)>, ScalarType>. I checked a reproducer with MSVC 2019 16.0, 16.11 and latest; 2015/2017 are not on Compiler Explorer. Theunit-noexcept.cppC2338 failure is a consequence of this error.bool, even an explicitstatic_cast, which/WXturns into an error. The enum conversions for an underlying typebool(Default enum conversion: an enum with underlying type bool can be serialized but not deserialized #5671) now go through the newdetail::bool_aware_static_cast, which compares with zero forbool. The test wraps itsCHECKs in double parentheses, so doctest does not print the enum via its underlying type.test-allocator(2015 Debug, Converting between basic_json specializations (e.g. json to ordered_json) overflows the stack on deep input #5650's test): the debug STL constructs the containers' debug proxies through the allocator innoexceptconstructors, so the test's failingcountdown_allocatorcrashes the program instead of throwingstd::bad_alloc. The test case is skipped there, using the guard Create a value before giving it its type #5585 introduced for the same reason.decltypeas a substitution failure. Its detection traits therefore report the deleted overloads as callable, although calling them still fails to compile. Those checks are skipped for_MSC_VER < 1910. The runtime section ofunit-delete_deprecated_functions.cppnow also usesos << jandis >> j, so MSVC 2015 still compiles the stream operators with the macro set./std:c++17for everything anyway, so they now build only the C++17 variant of each test (JSON_TestStandards=17). They are also split into two jobs each with a new test-only CMake option,JSON_TestShard=<index>/<count>, which keeps everycount-th unit test file starting atindex(48 and 44 of the 92 unit test targets). Locally, the two shards together give exactly the full set of tests.CMAKE_OPTIONSis no longer quoted inappveyor.yml, so that it can hold two options.std::terminatewithstd::optional(2017, Fix CI on develop after merging the ready-to-merge PRs #5754): MSVC 2017 evaluatesstd::is_nothrow_assignable<json&, const T&>as true even ifT'sto_jsonthrows. Soto_json(json&, const std::optional<T>&)wasnoexceptthere, and the exception from to_json(std::optional<T>) is noexcept: an exception from the contained value calls std::terminate #5642's test calledstd::terminateinstead of propagating (C2607 in thestatic_assertshowed the same thing at compile time). On MSVC 2017, that conversion is now nevernoexcept; all other compilers keep the exact condition. Thestatic_asserts on the condition are skipped for MSVC 2017; the runtime check that the exception propagates still runs there. This is a real library fix for MSVC 2017 users, not just a test fix.Validation
ci_test_gccbuild ingcc:latestwith 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.make amalgamate.Public API
No breaking changes. The
noexceptof the scalar comparison operators is unchanged; it is only spelled differently. WithoutJSON_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