diff --git a/.cirrus.yml b/.cirrus.yml deleted file mode 100644 index c7f4c15e2..000000000 --- a/.cirrus.yml +++ /dev/null @@ -1,17 +0,0 @@ -arm_container: - image: gcc:latest - -check_task: - check_script: - # the gcc image ships an outdated CMake, so fetch a recent prebuilt binary - # instead of compiling CMake from source - - wget -q https://github.com/Kitware/CMake/releases/download/v4.3.4/cmake-4.3.4-linux-aarch64.tar.gz - - tar xfz cmake-4.3.4-linux-aarch64.tar.gz - - export PATH="$(pwd)/cmake-4.3.4-linux-aarch64/bin:$PATH" - - cmake --version - - mkdir build - - cd build - - cmake .. -DJSON_FastTests=ON - - make -j4 - - cd tests - - ctest -j4 diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ef1432591..4bf8f8782 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -24,6 +24,10 @@ updates: interval: daily cooldown: default-days: 7 + ignore: + # astyle is deliberately pinned (see tools/astyle/requirements.txt): newer versions + # reformat the code, and the pinned version defines the formatting CI enforces + - dependency-name: astyle - package-ecosystem: pip directory: /tools/generate_natvis diff --git a/.github/external_ci/appveyor.yml b/.github/external_ci/appveyor.yml index 5c6b47a34..805195742 100644 --- a/.github/external_ci/appveyor.yml +++ b/.github/external_ci/appveyor.yml @@ -30,14 +30,6 @@ environment: CMAKE_OPTIONS: "" GENERATOR: Visual Studio 14 2015 - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - configuration: Release - platform: x86 - name: with_win_header - CXX_FLAGS: "/W4 /WX" - CMAKE_OPTIONS: "" - GENERATOR: Visual Studio 14 2015 - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 configuration: Release platform: x86 @@ -74,9 +66,6 @@ install: - if "%platform%"=="x86" set GENERATOR_PLATFORM=Win32 before_build: - # for with_win_header build, inject the inclusion of Windows.h to the single-header library - - ps: if ($env:name -Eq "with_win_header") { $header_path = "single_include\nlohmann\json.hpp" } - - ps: if ($env:name -Eq "with_win_header") { "#include `n" + (Get-Content $header_path | Out-String) | Set-Content $header_path } - cmake . -G "%GENERATOR%" -A "%GENERATOR_PLATFORM%" -DCMAKE_CXX_FLAGS="%CXX_FLAGS%" -DCMAKE_IGNORE_PATH="C:/Program Files/Git/usr/bin" -DJSON_BuildTests=On "%CMAKE_OPTIONS%" build_script: diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index fb3cd4148..485fb3b6d 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -52,6 +52,13 @@ jobs: run: cmake -S . -B build -DJSON_CI=On - name: Build run: cmake --build build --target ci_infer + - name: Archive Infer report + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: infer-report + path: ${{ github.workspace }}/build/build_infer/infer-out/report.txt + if-no-files-found: ignore ci_static_analysis_ubuntu: runs-on: ubuntu-latest @@ -97,13 +104,13 @@ jobs: ci_cmake_options: runs-on: ubuntu-latest - container: ubuntu:focal + container: ubuntu:24.04 strategy: matrix: target: [ci_cmake_flags, ci_test_diagnostics, ci_test_diagnostic_positions, ci_test_noexceptions, ci_test_noimplicitconversions, ci_test_legacycomparison, ci_test_noglobaludls, ci_test_disableenumserialization, ci_test_disabletuplereferenceconversion, ci_test_skiplibraryversioncheck, ci_test_simdutf, ci_test_strict_nul_handling, ci_test_no_thread_local] steps: - name: Install build-essential - run: apt-get update ; apt-get install -y build-essential unzip wget git libssl-dev + run: apt-get update ; apt-get install -y build-essential unzip wget git - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false @@ -407,3 +414,21 @@ jobs: run: cmake -S . -B build -DJSON_CI=On - name: Build run: cmake --build build --target ${{ matrix.target }} + + # Native Linux ARM64 runner with the latest GCC. The ubuntu-24.04-arm label is + # only available for public repositories. + ci_test_arm64: + runs-on: ubuntu-24.04-arm + container: gcc:latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Get latest CMake and ninja + uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2 + - name: Check that the job runs natively on arm64 + run: uname -m && test "$(uname -m)" = aarch64 + - name: Run CMake + run: cmake -S . -B build -DJSON_CI=On + - name: Build + run: cmake --build build --target ci_test_compiler_default diff --git a/.inferconfig b/.inferconfig new file mode 100644 index 000000000..9a5a36873 --- /dev/null +++ b/.inferconfig @@ -0,0 +1,12 @@ +{ + "_comment": "Used by the ci_infer CMake target (#5715 item 4b). fail-on-issue makes CI fail on Infer findings; disable-issue-type is a type-level baseline for the ~174 pre-existing findings (all PULSE_UNNECESSARY_COPY*/PULSE_RESOURCE_LEAK/PULSE_CONST_REFABLE, mostly in test code) triaged in run https://github.com/nlohmann/json/actions/runs/35829411620 on commit 1054b2097, so CI fails only on a NEW issue type. Remove an entry here once its findings have been fixed or explicitly accepted.", + "fail-on-issue": true, + "disable-issue-type": [ + "PULSE_UNNECESSARY_COPY_ASSIGNMENT", + "PULSE_UNNECESSARY_COPY", + "PULSE_UNNECESSARY_COPY_INTERMEDIATE", + "PULSE_UNNECESSARY_COPY_OPTIONAL", + "PULSE_RESOURCE_LEAK", + "PULSE_CONST_REFABLE" + ] +} diff --git a/FILES.md b/FILES.md index 263647146..d13be1238 100644 --- a/FILES.md +++ b/FILES.md @@ -33,17 +33,6 @@ Further documentation: > [!IMPORTANT] > The folder `.github/workflows` is predetermined by GitHub. -### `.cirrus.yml` - -Configuration file for the pipeline at [Cirrus CI](https://cirrus-ci.com/github/nlohmann/json). - -Further documentation: - -- [Writing tasks](https://cirrus-ci.org/guide/writing-tasks/) - -> [!IMPORTANT] -> The filename `.cirrus.yml` and position (root of the repository) are predetermined by Cirrus CI. - ### `.github/external_ci/appveyor.yml` Configuration for the pipelines at [AppVeyor](https://ci.appveyor.com/project/nlohmann/json). diff --git a/Makefile b/Makefile index fec936343..3a7fa5c41 100644 --- a/Makefile +++ b/Makefile @@ -87,7 +87,7 @@ install_astyle: # call the Artistic Style pretty printer on all source files pretty: install_astyle - $(ASTYLE) --project=tools/astyle/.astylerc $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) docs/mkdocs/docs/examples/*.cpp + $(ASTYLE) --project=tools/astyle/.astylerc $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) docs/mkdocs/docs/examples/*.cpp docs/mkdocs/docs/examples/*.hpp # create single header files and pretty print amalgamate: $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) diff --git a/README.md b/README.md index 9fd3f71fc..19b238364 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ [![Coverage Status](https://coveralls.io/repos/github/nlohmann/json/badge.svg?branch=develop)](https://coveralls.io/github/nlohmann/json?branch=develop) [![Coverity Scan Build Status](https://scan.coverity.com/projects/5550/badge.svg)](https://scan.coverity.com/projects/nlohmann-json) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/e0d1a9d5d6fd46fcb655c4cb930bb3e8)](https://app.codacy.com/gh/nlohmann/json/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) -[![Cirrus CI](https://api.cirrus-ci.com/github/nlohmann/json.svg)](https://cirrus-ci.com/github/nlohmann/json) [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/json.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:json) [![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/1mp10JbaANo6FUc7) [![Documentation](https://img.shields.io/badge/docs-mkdocs-blue.svg)](https://json.nlohmann.me) diff --git a/cmake/ci.cmake b/cmake/ci.cmake index 27187f235..c0ed77f6c 100644 --- a/cmake/ci.cmake +++ b/cmake/ci.cmake @@ -40,6 +40,14 @@ execute_process(COMMAND ${IWYU_TOOL} --version OUTPUT_VARIABLE IWYU_TOOL_VERSION string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" IWYU_TOOL_VERSION "${IWYU_TOOL_VERSION}") message(STATUS "🔖 include-what-you-use ${IWYU_TOOL_VERSION} (${IWYU_TOOL})") +# CMake's CXX_INCLUDE_WHAT_YOU_USE launcher runs IWYU during the normal compile step (useful to see +# diagnostics inline), but CMake's own __run_co_compile wrapper does not propagate the launched +# tool's exit code to the build, so IWYU's own "-Xiwyu --error" cannot fail that step (verified: a +# deliberately-unused #include in a header still lets `cmake --build` finish with exit code 0). +# iwyu_tool.py, which ships with IWYU, reads compile_commands.json and does return a non-zero exit +# code for any analyzed file with findings; ci_single_binaries uses it to actually fail on findings. +find_program(IWYU_TOOL_PY NAMES iwyu_tool iwyu_tool.py iwyu-tool) + find_program(INFER_TOOL NAMES infer) execute_process(COMMAND ${INFER_TOOL} --version OUTPUT_VARIABLE INFER_TOOL_VERSION ERROR_VARIABLE INFER_TOOL_VERSION) string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" INFER_TOOL_VERSION "${INFER_TOOL_VERSION}") @@ -55,12 +63,6 @@ execute_process(COMMAND ${NINJA_TOOL} --version OUTPUT_VARIABLE NINJA_TOOL_VERSI string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" NINJA_TOOL_VERSION "${NINJA_TOOL_VERSION}") message(STATUS "🔖 Ninja ${NINJA_TOOL_VERSION} (${NINJA_TOOL})") -find_program(OCLINT_TOOL NAMES oclint-json-compilation-database) -find_program(OCLINT_VERSION_TOOL NAMES oclint) -execute_process(COMMAND ${OCLINT_VERSION_TOOL} --version OUTPUT_VARIABLE OCLINT_TOOL_VERSION ERROR_VARIABLE OCLINT_TOOL_VERSION) -string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" OCLINT_TOOL_VERSION "${OCLINT_TOOL_VERSION}") -message(STATUS "🔖 OCLint ${OCLINT_TOOL_VERSION} (${OCLINT_TOOL})") - find_program(VALGRIND_TOOL NAMES valgrind) execute_process(COMMAND ${VALGRIND_TOOL} --version OUTPUT_VARIABLE VALGRIND_TOOL_VERSION ERROR_VARIABLE VALGRIND_TOOL_VERSION) string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" VALGRIND_TOOL_VERSION "${VALGRIND_TOOL_VERSION}") @@ -128,16 +130,16 @@ foreach(CXX_STANDARD 11 14 17 20 23 26) COMMENT "Compile and test with Clang for C++${CXX_STANDARD}" ) + # pass -stdlib=libc++ through CXXFLAGS: an explicit -DCMAKE_CXX_FLAGS would make CMake ignore CXXFLAGS add_custom_target(ci_test_clang_libcxx_cxx${CXX_STANDARD} - COMMAND CXX=${CLANG_TOOL} CXXFLAGS="${CLANG_CXXFLAGS}" ${CMAKE_COMMAND} + COMMAND CXX=${CLANG_TOOL} CXXFLAGS="${CLANG_CXXFLAGS};-stdlib=libc++" ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug -GNinja -DJSON_BuildTests=ON -DJSON_FastTests=ON -DJSON_TestStandards=${CXX_STANDARD} - -DCMAKE_CXX_FLAGS="-stdlib=libc++" -DCMAKE_EXE_LINKER_FLAGS="-lc++abi" - -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD} - COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD} - COMMAND cd ${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_libcxx_cxx${CXX_STANDARD} + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang_libcxx_cxx${CXX_STANDARD} + COMMAND cd ${PROJECT_BINARY_DIR}/build_clang_libcxx_cxx${CXX_STANDARD} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure COMMENT "Compile and test with Clang for C++${CXX_STANDARD} (libc++)" ) endforeach() @@ -376,13 +378,20 @@ add_custom_target(ci_test_clang_sanitizer # Check if header is amalgamated and sources are properly indented. ############################################################################### +# Same file set as .github/workflows/check_amalgamation.yml, so a direct push to develop/master/release/* +# (which only this CMake target checks, not the pull_request-only workflow) is held to the same standard. file(GLOB_RECURSE INDENT_FILES - ${PROJECT_SOURCE_DIR}/include/nlohmann/*.hpp - ${PROJECT_SOURCE_DIR}/tests/src/*.cpp - ${PROJECT_SOURCE_DIR}/tests/src/*.hpp - ${PROJECT_SOURCE_DIR}/tests/benchmarks/src/benchmarks.cpp + ${PROJECT_SOURCE_DIR}/docs/mkdocs/docs/examples/*.hpp ${PROJECT_SOURCE_DIR}/docs/mkdocs/docs/examples/*.cpp + ${PROJECT_SOURCE_DIR}/docs/mkdocs/docs/examples/*.cu + ${PROJECT_SOURCE_DIR}/include/*.hpp + ${PROJECT_SOURCE_DIR}/include/*.cpp + ${PROJECT_SOURCE_DIR}/include/*.cu + ${PROJECT_SOURCE_DIR}/tests/*.hpp + ${PROJECT_SOURCE_DIR}/tests/*.cpp + ${PROJECT_SOURCE_DIR}/tests/*.cu ) +list(FILTER INDENT_FILES EXCLUDE REGEX "/tests/thirdparty/|/tests/abi/include/nlohmann/") set(include_dir ${PROJECT_SOURCE_DIR}/single_include/nlohmann) set(tool_dir ${PROJECT_SOURCE_DIR}/tools/amalgamate) @@ -391,6 +400,7 @@ add_custom_target(ci_test_amalgamation COMMAND cp ${include_dir}/json.hpp ${include_dir}/json.hpp~ COMMAND cp ${include_dir}/json_fwd.hpp ${include_dir}/json_fwd.hpp~ COMMAND cp ${include_dir}/json_literals.hpp ${include_dir}/json_literals.hpp~ + COMMAND cp ${PROJECT_SOURCE_DIR}/BUILD.bazel ${PROJECT_SOURCE_DIR}/BUILD.bazel~ COMMAND ${Python3_EXECUTABLE} -mvenv venv_astyle COMMAND venv_astyle/bin/pip3 --quiet install -r ${CMAKE_SOURCE_DIR}/tools/astyle/requirements.txt @@ -400,16 +410,18 @@ add_custom_target(ci_test_amalgamation COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json_fwd.json -s . COMMAND cp ${PROJECT_SOURCE_DIR}/include/nlohmann/json_literals.hpp ${include_dir}/json_literals.hpp COMMAND venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=none ${include_dir}/json.hpp ${include_dir}/json_fwd.hpp + COMMAND ${CMAKE_COMMAND} -P ${PROJECT_SOURCE_DIR}/cmake/scripts/gen_bazel_build_file.cmake COMMAND diff ${include_dir}/json.hpp~ ${include_dir}/json.hpp COMMAND diff ${include_dir}/json_fwd.hpp~ ${include_dir}/json_fwd.hpp COMMAND diff ${include_dir}/json_literals.hpp~ ${include_dir}/json_literals.hpp + COMMAND diff ${PROJECT_SOURCE_DIR}/BUILD.bazel~ ${PROJECT_SOURCE_DIR}/BUILD.bazel COMMAND venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=orig ${INDENT_FILES} COMMAND for FILE in `find . -name '*.orig'`\; do false \; done WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - COMMENT "Check amalgamation and indentation" + COMMENT "Check amalgamation, formatting, and BUILD.bazel" ) ############################################################################### @@ -444,14 +456,14 @@ add_custom_target(ci_test_valgrind # Check code with Clang Static Analyzer. ############################################################################### -set(CLANG_ANALYZER_CHECKS "fuchsia.HandleChecker,nullability.NullableDereferenced,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,optin.cplusplus.UninitializedObject,optin.cplusplus.VirtualCall,optin.mpi.MPI-Checker,optin.osx.OSObjectCStyleCast,optin.osx.cocoa.localizability.EmptyLocalizationContextChecker,optin.osx.cocoa.localizability.NonLocalizedStringChecker,optin.performance.GCDAntipattern,optin.performance.Padding,optin.portability.UnixAPI,security.FloatLoopCounter,security.insecureAPI.DeprecatedOrUnsafeBufferHandling,security.insecureAPI.bcmp,security.insecureAPI.bcopy,security.insecureAPI.bzero,security.insecureAPI.rand,security.insecureAPI.strcpy,valist.CopyToSelf,valist.Uninitialized,valist.Unterminated,webkit.NoUncountedMemberChecker,webkit.RefCntblBaseVirtualDtor,core.CallAndMessage,core.DivideZero,core.NonNullParamChecker,core.NullDereference,core.StackAddressEscape,core.UndefinedBinaryOperatorResult,core.VLASize,core.uninitialized.ArraySubscript,core.uninitialized.Assign,core.uninitialized.Branch,core.uninitialized.CapturedBlockVariable,core.uninitialized.UndefReturn,cplusplus.InnerPointer,cplusplus.Move,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,cplusplus.PlacementNew,cplusplus.PureVirtualCall,deadcode.DeadStores,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,osx.API,osx.MIG,osx.NumberObjectConversion,osx.OSObjectRetainCount,osx.ObjCProperty,osx.SecKeychainAPI,osx.cocoa.AtSync,osx.cocoa.AutoreleaseWrite,osx.cocoa.ClassRelease,osx.cocoa.Dealloc,osx.cocoa.IncompatibleMethodTypes,osx.cocoa.Loops,osx.cocoa.MissingSuperCall,osx.cocoa.NSAutoreleasePool,osx.cocoa.NSError,osx.cocoa.NilArg,osx.cocoa.NonNilReturnValue,osx.cocoa.ObjCGenerics,osx.cocoa.RetainCount,osx.cocoa.RunLoopAutoreleaseLeak,osx.cocoa.SelfInit,osx.cocoa.SuperDealloc,osx.cocoa.UnusedIvars,osx.cocoa.VariadicMethodTypes,osx.coreFoundation.CFError,osx.coreFoundation.CFNumber,osx.coreFoundation.CFRetainRelease,osx.coreFoundation.containers.OutOfBounds,osx.coreFoundation.containers.PointerSizedValues,security.insecureAPI.UncheckedReturn,security.insecureAPI.decodeValueOfObjCType,security.insecureAPI.getpw,security.insecureAPI.gets,security.insecureAPI.mkstemp,security.insecureAPI.mktemp,security.insecureAPI.vfork,unix.API,unix.Malloc,unix.MallocSizeof,unix.MismatchedDeallocator,unix.Vfork,unix.cstring.BadSizeArg,unix.cstring.NullArg") +set(CLANG_ANALYZER_CHECKS "nullability.NullableDereferenced,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,optin.cplusplus.UninitializedObject,optin.cplusplus.VirtualCall,optin.performance.Padding,optin.portability.UnixAPI,security.FloatLoopCounter,security.insecureAPI.DeprecatedOrUnsafeBufferHandling,security.insecureAPI.bcmp,security.insecureAPI.bcopy,security.insecureAPI.bzero,security.insecureAPI.rand,security.insecureAPI.strcpy,valist.CopyToSelf,valist.Uninitialized,valist.Unterminated,core.CallAndMessage,core.DivideZero,core.NonNullParamChecker,core.NullDereference,core.StackAddressEscape,core.UndefinedBinaryOperatorResult,core.VLASize,core.uninitialized.ArraySubscript,core.uninitialized.Assign,core.uninitialized.Branch,core.uninitialized.CapturedBlockVariable,core.uninitialized.UndefReturn,cplusplus.InnerPointer,cplusplus.Move,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,cplusplus.PlacementNew,cplusplus.PureVirtualCall,deadcode.DeadStores,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,security.insecureAPI.UncheckedReturn,security.insecureAPI.decodeValueOfObjCType,security.insecureAPI.getpw,security.insecureAPI.gets,security.insecureAPI.mkstemp,security.insecureAPI.mktemp,security.insecureAPI.vfork,unix.API,unix.Malloc,unix.MallocSizeof,unix.MismatchedDeallocator,unix.Vfork,unix.cstring.BadSizeArg,unix.cstring.NullArg") add_custom_target(ci_clang_analyze COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug -GNinja -DJSON_BuildTests=ON -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_analyze - COMMAND cd ${PROJECT_BINARY_DIR}/build_clang_analyze && ${SCAN_BUILD_TOOL} -enable-checker ${CLANG_ANALYZER_CHECKS} --use-c++=${CLANG_TOOL} -analyze-headers -o ${PROJECT_BINARY_DIR}/report ninja + COMMAND cd ${PROJECT_BINARY_DIR}/build_clang_analyze && ${SCAN_BUILD_TOOL} -enable-checker ${CLANG_ANALYZER_CHECKS} --use-c++=${CLANG_TOOL} --use-analyzer=${CLANG_TOOL} -analyze-headers --status-bugs -o ${PROJECT_BINARY_DIR}/report ninja COMMENT "Check code with Clang Analyzer" ) @@ -467,7 +479,7 @@ add_custom_target(ci_cppcheck COMMAND venv_cppcheck/bin/cppcheck --enable=warning --check-level=exhaustive --inline-suppr --inconclusive --force --std=c++11 ${PROJECT_SOURCE_DIR}/include/nlohmann/json.hpp -I ${CMAKE_SOURCE_DIR}/include --error-exitcode=1 --relative-paths=${PROJECT_SOURCE_DIR} -j ${N} --include=default_defines.hpp - --cppcheck-build-dir=cppcheck --check-level=exhaustive + --cppcheck-build-dir=cppcheck -UJSON_CATCH_USER -UJSON_TRY_USER -UJSON_ASSERT -UJSON_INTERNAL_CATCH -UJSON_THROW -DJSON_HAS_CPP_11 -UJSON_HAS_CPP_14 -UJSON_HAS_CPP_17 -UJSON_HAS_CPP_20 -UJSON_HAS_THREE_WAY_COMPARISON COMMENT "Check code with Cppcheck" @@ -485,34 +497,6 @@ add_custom_target(ci_cpplint WORKING_DIRECTORY ${PROJECT_BINARY_DIR} ) -############################################################################### -# Check code with OCLint. -############################################################################### - -file(COPY ${PROJECT_SOURCE_DIR}/single_include/nlohmann/json.hpp DESTINATION ${PROJECT_BINARY_DIR}/src_single) -file(RENAME ${PROJECT_BINARY_DIR}/src_single/json.hpp ${PROJECT_BINARY_DIR}/src_single/all.cpp) -file(APPEND "${PROJECT_BINARY_DIR}/src_single/all.cpp" "\n\nint main()\n{}\n") - -add_executable(single_all ${PROJECT_BINARY_DIR}/src_single/all.cpp) -target_compile_features(single_all PRIVATE cxx_std_11) - -add_custom_target(ci_oclint - COMMAND ${CMAKE_COMMAND} - -DCMAKE_BUILD_TYPE=Debug - -DCMAKE_EXPORT_COMPILE_COMMANDS=ON - -DJSON_BuildTests=OFF -DJSON_CI=ON - -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_oclint - COMMAND ${OCLINT_TOOL} -i ${PROJECT_BINARY_DIR}/build_oclint/src_single/all.cpp -p ${PROJECT_BINARY_DIR}/build_oclint -- - -report-type html -enable-global-analysis --max-priority-1=0 --max-priority-2=1000 --max-priority-3=2000 - --disable-rule=MultipleUnaryOperator - --disable-rule=DoubleNegative - --disable-rule=ShortVariableName - --disable-rule=GotoStatement - --disable-rule=LongLine - -o ${PROJECT_BINARY_DIR}/build_oclint/oclint_report.html - COMMENT "Check code with OCLint" -) - ############################################################################### # Check code with Clang-Tidy. ############################################################################### @@ -527,29 +511,16 @@ add_custom_target(ci_clang_tidy COMMENT "Check code with Clang-Tidy" ) -############################################################################### -# Check code with PVS-Studio Analyzer . -############################################################################### - -add_custom_target(ci_pvs_studio - COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND} - -DCMAKE_BUILD_TYPE=Debug - -DCMAKE_EXPORT_COMPILE_COMMANDS=ON - -DJSON_BuildTests=ON - -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_pvs_studio - COMMAND cd ${PROJECT_BINARY_DIR}/build_pvs_studio && ${PVS_STUDIO_ANALYZER_TOOL} analyze -j 10 - COMMAND cd ${PROJECT_BINARY_DIR}/build_pvs_studio && ${PLOG_CONVERTER_TOOL} -a'GA:1,2;64:1;CS' -t fullhtml PVS-Studio.log -o pvs - COMMENT "Check code with PVS Studio" -) - ############################################################################### # Check code with Infer static analyzer. ############################################################################### +# .inferconfig (repository root) pins --fail-on-issue and the currently-triaged issue types that +# are disabled until they are addressed separately; see #5715 item 4b. add_custom_target(ci_infer COMMAND mkdir -p ${PROJECT_BINARY_DIR}/build_infer COMMAND cd ${PROJECT_BINARY_DIR}/build_infer && ${INFER_TOOL} compile -- ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${PROJECT_SOURCE_DIR} -DJSON_BuildTests=ON - COMMAND cd ${PROJECT_BINARY_DIR}/build_infer && ${INFER_TOOL} run -- make + COMMAND cd ${PROJECT_BINARY_DIR}/build_infer && ${INFER_TOOL} run --project-root ${PROJECT_SOURCE_DIR} -- make COMMENT "Check code with Infer" ) @@ -605,7 +576,13 @@ add_custom_target(ci_reproducible_tests # be compiled individually. ############################################################################### -set(iwyu_path_and_options ${IWYU_TOOL} -Xiwyu --max_line_length=300) +set(iwyu_options -Xiwyu --error -Xiwyu --max_line_length=300) +set(iwyu_path_and_options ${IWYU_TOOL} ${iwyu_options}) + +# CMake needs to know the exact flags used to compile each src_single/*.cpp below to hand them to +# iwyu_tool.py; JSON_CI already implies a from-scratch configure, so enabling this project-wide has +# no downside here. +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) foreach(SRC_FILE ${SRC_FILES}) # get relative path of the header file @@ -620,14 +597,34 @@ foreach(SRC_FILE ${SRC_FILES}) target_include_directories(single_${RELATIVE_SRC_FILE} PRIVATE ${PROJECT_SOURCE_DIR}/include) target_compile_features(single_${RELATIVE_SRC_FILE} PRIVATE cxx_std_11) set_property(TARGET single_${RELATIVE_SRC_FILE} PROPERTY CXX_INCLUDE_WHAT_YOU_USE "${iwyu_path_and_options}") - # remember binary for ci_single_binaries target + # remember binary for ci_single_binaries list(APPEND single_binaries single_${RELATIVE_SRC_FILE}) + # json.hpp pulls together the whole library behind heavily templated, SFINAE-based code, and + # IWYU's suggestion for its one truly ambiguous symbol (a container-comparison "swap, + # operator!=") is not deterministic between runs (observed , , and + # for the exact same source across otherwise-identical local and containerized builds). Keep + # reporting its diagnostics (informational, via CXX_INCLUDE_WHAT_YOU_USE above) but exclude it + # from the hard gate below so a fresh IWYU/compiler combination does not fail this target on a + # nondeterministic suggestion for a header that already re-exports everything on purpose. + if(NOT RELATIVE_SRC_FILE STREQUAL "json") + list(APPEND single_binaries_tus src_single/${RELATIVE_SRC_FILE}.cpp) + endif() endforeach() -add_custom_target(ci_single_binaries - DEPENDS ${single_binaries} - COMMENT "Check if headers are self-contained" -) +if(IWYU_TOOL_PY) + add_custom_target(ci_single_binaries + DEPENDS ${single_binaries} + COMMAND ${IWYU_TOOL_PY} -p ${PROJECT_BINARY_DIR} ${single_binaries_tus} -- ${iwyu_options} + COMMENT "Check if headers are self-contained" + ) +else() + # iwyu_tool.py (ships with IWYU, e.g. as /usr/bin/iwyu_tool on Debian/Ubuntu) was not found; + # fall back to building the self-containment check without enforcing the IWYU findings. + add_custom_target(ci_single_binaries + DEPENDS ${single_binaries} + COMMENT "Check if headers are self-contained" + ) +endif() ############################################################################### # Benchmarks @@ -649,21 +646,41 @@ add_custom_target(ci_benchmarks # we test the project with different CMake versions: # - CMake 3.5 (the earliest supported) # - CMake 3.31.6 (the latest 3.x release) -# - CMake 4.0.0 (the latest release) +# - CMake 4.0.0 (the first 4.x release) +# - the CMake version running this build (usually the latest release) function(ci_get_cmake version var) set(${var} ${PROJECT_BINARY_DIR}/cmake-${version}/bin/cmake) - add_custom_command( - OUTPUT ${${var}} - COMMAND wget -nc https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}.tar.gz - COMMAND tar xfz cmake-${version}.tar.gz - COMMAND rm cmake-${version}.tar.gz - # -DCMAKE_POLICY_VERSION_MINIMUM=3.5 required to compile older CMake versions with CMake 4.0.0 - COMMAND cmake -S cmake-${version} -B cmake-${version} -DCMAKE_POLICY_VERSION_MINIMUM=3.5 - COMMAND cmake --build cmake-${version} --parallel 10 - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - COMMENT "Download CMake ${version}" - ) + if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "^(x86_64|amd64)$") + # Kitware publishes a prebuilt Linux x86_64 archive for every release; unpacking it is far + # cheaper than compiling all of CMake (including its own test helpers) from source. + add_custom_command( + OUTPUT ${${var}} + COMMAND wget -nc https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}-linux-x86_64.tar.gz + COMMAND wget -nc https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}-SHA-256.txt + # verify the archive against Kitware's published SHA-256 sums before unpacking it + COMMAND sh -c "grep ' cmake-${version}-linux-x86_64[.]tar[.]gz$' cmake-${version}-SHA-256.txt | sha256sum -c -" + COMMAND tar xfz cmake-${version}-linux-x86_64.tar.gz + COMMAND rm cmake-${version}-linux-x86_64.tar.gz cmake-${version}-SHA-256.txt + COMMAND ${CMAKE_COMMAND} -E rm -rf cmake-${version} + COMMAND ${CMAKE_COMMAND} -E rename cmake-${version}-linux-x86_64 cmake-${version} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMENT "Download prebuilt CMake ${version}" + ) + else() + # no prebuilt archive for this platform (e.g. macOS or Linux aarch64): build from source + add_custom_command( + OUTPUT ${${var}} + COMMAND wget -nc https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}.tar.gz + COMMAND tar xfz cmake-${version}.tar.gz + COMMAND rm cmake-${version}.tar.gz + # -DCMAKE_POLICY_VERSION_MINIMUM=3.5 required to compile older CMake versions with CMake 4.0.0 + COMMAND cmake -S cmake-${version} -B cmake-${version} -DCMAKE_POLICY_VERSION_MINIMUM=3.5 + COMMAND cmake --build cmake-${version} --parallel 10 + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMENT "Download and build CMake ${version} from source" + ) + endif() set(${var} ${${var}} PARENT_SCOPE) endfunction() @@ -673,30 +690,24 @@ ci_get_cmake(4.0.0 CMAKE_4_0_0_BINARY) # the tests require CMake 3.13 or later, so they are excluded for CMake 3.5.0 set(JSON_CMAKE_FLAGS_3_5_0 JSON_Diagnostics JSON_Diagnostic_Positions JSON_GlobalUDLs JSON_ImplicitConversions JSON_DisableEnumSerialization - JSON_LegacyDiscardedValueComparison JSON_Install JSON_MultipleHeaders JSON_SystemInclude JSON_Valgrind) -set(JSON_CMAKE_FLAGS_3_31_6 JSON_BuildTests ${JSON_CMAKE_FLAGS_3_31_6}) + JSON_LegacyDiscardedValueComparison JSON_Install JSON_MultipleHeaders JSON_SystemInclude JSON_Valgrind + JSON_StrictNulHandling) +set(JSON_CMAKE_FLAGS_3_31_6 JSON_BuildTests ${JSON_CMAKE_FLAGS_3_5_0}) set(JSON_CMAKE_FLAGS_4_0_0 JSON_BuildTests ${JSON_CMAKE_FLAGS_3_5_0}) function(ci_add_cmake_flags_targets flag min_version) string(TOLOWER "ci_cmake_flag_${flag}" flag_target) string(REPLACE . _ min_version_var ${min_version}) set(cmake_binary ${CMAKE_${min_version_var}_BINARY}) - add_custom_target(${flag_target}_${min_version}_2 - COMMENT "Check CMake flag ${flag} (CMake ${CMAKE_VERSION})" - COMMAND ${CMAKE_COMMAND} - -Werror=dev - -D${flag}=ON - -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_${flag_target} - ) add_custom_target(${flag_target}_${min_version_var} - COMMENT "Check CMake flag ${JSON_CMAKE_FLAG} (CMake ${min_version})" + COMMENT "Check CMake flag ${flag} (CMake ${min_version})" COMMAND mkdir -pv ${PROJECT_BINARY_DIR}/build_${flag_target}_${min_version_var} COMMAND cd ${PROJECT_BINARY_DIR}/build_${flag_target}_${min_version_var} && ${cmake_binary} -Werror=dev ${PROJECT_SOURCE_DIR} -D${flag}=ON DEPENDS ${cmake_binary} ) - list(APPEND JSON_CMAKE_FLAG_TARGETS ${JSON_CMAKE_FLAG_TARGET} ${flag_target}_${min_version_var}) - list(APPEND JSON_CMAKE_FLAG_BUILD_DIRS ${PROJECT_BINARY_DIR}/build_${flag_target} ${PROJECT_BINARY_DIR}/build_${flag_target}_${min_version_var}) + list(APPEND JSON_CMAKE_FLAG_TARGETS ${flag_target}_${min_version_var}) + list(APPEND JSON_CMAKE_FLAG_BUILD_DIRS ${PROJECT_BINARY_DIR}/build_${flag_target}_${min_version_var}) set(JSON_CMAKE_FLAG_TARGETS ${JSON_CMAKE_FLAG_TARGETS} PARENT_SCOPE) set(JSON_CMAKE_FLAG_BUILD_DIRS ${JSON_CMAKE_FLAG_BUILD_DIRS} PARENT_SCOPE) endfunction() @@ -713,6 +724,20 @@ foreach(JSON_CMAKE_FLAG ${JSON_CMAKE_FLAGS_4_0_0}) ci_add_cmake_flags_targets(${JSON_CMAKE_FLAG} 4.0.0) endforeach() +# check the same flags with the CMake version running this build +foreach(JSON_CMAKE_FLAG ${JSON_CMAKE_FLAGS_4_0_0}) + string(TOLOWER "ci_cmake_flag_${JSON_CMAKE_FLAG}" flag_target) + add_custom_target(${flag_target} + COMMENT "Check CMake flag ${JSON_CMAKE_FLAG} (CMake ${CMAKE_VERSION})" + COMMAND ${CMAKE_COMMAND} + -Werror=dev + -D${JSON_CMAKE_FLAG}=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_${flag_target} + ) + list(APPEND JSON_CMAKE_FLAG_TARGETS ${flag_target}) + list(APPEND JSON_CMAKE_FLAG_BUILD_DIRS ${PROJECT_BINARY_DIR}/build_${flag_target}) +endforeach() + add_custom_target(ci_cmake_flags DEPENDS ${JSON_CMAKE_FLAG_TARGETS} COMMENT "Check CMake flags" @@ -871,6 +896,6 @@ add_custom_target(ci_test_build_documentation ############################################################################### add_custom_target(ci_clean - COMMAND rm -fr ${PROJECT_BINARY_DIR}/build_* cmake-3.5.0-Darwin64 ${JSON_CMAKE_FLAG_BUILD_DIRS} ${single_binaries} + COMMAND rm -fr ${PROJECT_BINARY_DIR}/build_* ${PROJECT_BINARY_DIR}/cmake-3.5.0 ${PROJECT_BINARY_DIR}/cmake-3.31.6 ${PROJECT_BINARY_DIR}/cmake-4.0.0 ${JSON_CMAKE_FLAG_BUILD_DIRS} ${single_binaries} COMMENT "Clean generated directories" ) diff --git a/docs/mkdocs/docs/community/quality_assurance.md b/docs/mkdocs/docs/community/quality_assurance.md index f2404c77b..d44135bf2 100644 --- a/docs/mkdocs/docs/community/quality_assurance.md +++ b/docs/mkdocs/docs/community/quality_assurance.md @@ -90,7 +90,7 @@ Note: Some modern features (like C++20 ranges or filesystem support) may be disa | GNU 14.2.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | | GNU 15.1.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | | GNU 16.1.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | - | GNU 16.1.0 | arm64 | Linux 6.1.100 | Cirrus CI | + | GNU 16.1.0 | arm64 | Ubuntu 24.04 | GitHub | | icpc (ICC) 2021.10.0 20230609 | x86_64 | Ubuntu 22.04 LTS | GitHub | | icpx (Intel oneAPI DPC++/C++) 2025.3.2 | x86_64 | Ubuntu 24.04 LTS | GitHub | | nvc++ (NVIDIA HPC SDK) 25.5-0 | x86_64 | Ubuntu 22.04 LTS | GitHub | @@ -132,7 +132,8 @@ Note: Some modern features (like C++20 ranges or filesystem support) may be disa [libstdc++](https://gcc.gnu.org/onlinedocs/libstdc++/) to detect subtle differences or incompatibilities. - [x] The code checked with [Include What You Use (IWYU)](https://include-what-you-use.org) that all required standard headers are included. -- [x] On Windows, the library is compiled with `` being included to detect and avoid common bugs. +- [x] On Windows, the library is compiled with `` being included to detect and avoid common bugs (see + [`unit-windows_h.cpp`](https://github.com/nlohmann/json/blob/develop/tests/src/unit-windows_h.cpp)). - [x] The library is compiled with exceptions disabled to support alternative means of error handling. ## Stable public API diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 09a1ec9b5..de82cad37 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -29,7 +29,9 @@ #endif #include // all_of, find, for_each, none_of +#include // isnan #include // nullptr_t, ptrdiff_t, size_t +#include // uint8_t #include // hash, less #include // initializer_list #ifndef JSON_NO_IO @@ -38,19 +40,28 @@ #include // make_move_iterator, random_access_iterator_tag #include // numeric_limits #include // unique_ptr +#include // swap, operator!= #include // length_error #include // string, stoi, to_string +#include // enable_if_t, is_same, is_scalar, ... +#include // swap (for the from_json(..., std::unordered_map&) overload) #include // declval, forward, move, pair, swap #include // vector -#include +// keep: json.hpp's own basic_json<> default template arguments need the complete definition of +// each of these, not only the forward declarations from json_fwd.hpp, so IWYU's suggestion to +// drop them (nothing in this file otherwise names the type) would break every downstream +// translation unit that relies on basic_json<>'s defaults actually being usable. +#include // IWYU pragma: keep #include -#include -#include +#include +#include // IWYU pragma: keep +#include // IWYU pragma: keep #include #include #include #include +#include #include #include #include @@ -62,6 +73,7 @@ #include #include #include +#include #include #include #include @@ -73,7 +85,8 @@ #include #include #include -#include +#include // IWYU pragma: keep +#include #if defined(JSON_HAS_CPP_17) #if JSON_HAS_STATIC_RTTI @@ -6802,7 +6815,10 @@ struct formatter // NOLINT(cert-dcl58-c } // namespace std -#include +// keep: undoes the macros defined via detail/macro_scope.hpp at the top of this file; removing it +// (nothing in this file *uses* a symbol from it) would leak JSON_* macros into every translation +// unit that includes this header. +#include // IWYU pragma: keep // End of GCC diagnostic pragmas for C++ modules support #if defined(__GNUC__) && !defined(__clang__) && __cplusplus >= 202002L diff --git a/include/nlohmann/json_fwd.hpp b/include/nlohmann/json_fwd.hpp index be05ebeef..3ca4d082d 100644 --- a/include/nlohmann/json_fwd.hpp +++ b/include/nlohmann/json_fwd.hpp @@ -11,8 +11,7 @@ #include // int64_t, uint64_t #include // map -#include // allocator -#include // string +#include // allocator, string #include // vector #include @@ -32,7 +31,7 @@ This serializer ignores the template arguments and uses ADL for serialization. */ template -struct adl_serializer; +struct adl_serializer; // IWYU pragma: keep /// a class to store JSON values /// @sa https://json.nlohmann.me/api/basic_json/ @@ -48,12 +47,12 @@ template class ObjectType = adl_serializer, class BinaryType = std::vector, // cppcheck-suppress syntaxError class CustomBaseClass = void> -class basic_json; +class basic_json; // IWYU pragma: keep /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document /// @sa https://json.nlohmann.me/api/json_pointer/ template -class json_pointer; +class json_pointer; // IWYU pragma: keep /*! @brief default specialization @@ -64,7 +63,7 @@ using json = basic_json<>; /// @brief a minimal map-like container that preserves insertion order /// @sa https://json.nlohmann.me/api/ordered_map/ template -struct ordered_map; +struct ordered_map; // IWYU pragma: keep /// @brief specialization that maintains the insertion order of object keys /// @sa https://json.nlohmann.me/api/ordered_json/ diff --git a/include/nlohmann/ordered_map.hpp b/include/nlohmann/ordered_map.hpp index 15e52ebb1..7b6f63781 100644 --- a/include/nlohmann/ordered_map.hpp +++ b/include/nlohmann/ordered_map.hpp @@ -12,13 +12,14 @@ #include // equal_to, less #include // initializer_list #include // input_iterator_tag, iterator_traits -#include // allocator +#include // for operator new (placement new) #include // for out_of_range #include // forward_as_tuple #include // enable_if, integral_constant, is_convertible, is_nothrow_move_constructible #include // forward, move, pair, piecewise_construct -#include // vector +#include // vector, allocator +#include #include #include diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index c6c4d81b5..f39e593b9 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -29,7 +29,9 @@ #endif #include // all_of, find, for_each, none_of +#include // isnan #include // nullptr_t, ptrdiff_t, size_t +#include // uint8_t #include // hash, less #include // initializer_list #ifndef JSON_NO_IO @@ -38,11 +40,18 @@ #include // make_move_iterator, random_access_iterator_tag #include // numeric_limits #include // unique_ptr +#include // swap, operator!= #include // length_error #include // string, stoi, to_string +#include // enable_if_t, is_same, is_scalar, ... +#include // swap (for the from_json(..., std::unordered_map&) overload) #include // declval, forward, move, pair, swap #include // vector +// keep: json.hpp's own basic_json<> default template arguments need the complete definition of +// each of these, not only the forward declarations from json_fwd.hpp, so IWYU's suggestion to +// drop them (nothing in this file otherwise names the type) would break every downstream +// translation unit that relies on basic_json<>'s defaults actually being usable. // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ @@ -3973,8 +3982,7 @@ NLOHMANN_JSON_NAMESPACE_END #include // int64_t, uint64_t #include // map - #include // allocator - #include // string + #include // allocator, string #include // vector // #include @@ -3995,7 +4003,7 @@ NLOHMANN_JSON_NAMESPACE_END for serialization. */ template - struct adl_serializer; + struct adl_serializer; // IWYU pragma: keep /// a class to store JSON values /// @sa https://json.nlohmann.me/api/basic_json/ @@ -4011,12 +4019,12 @@ NLOHMANN_JSON_NAMESPACE_END adl_serializer, class BinaryType = std::vector, // cppcheck-suppress syntaxError class CustomBaseClass = void> - class basic_json; + class basic_json; // IWYU pragma: keep /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document /// @sa https://json.nlohmann.me/api/json_pointer/ template - class json_pointer; + class json_pointer; // IWYU pragma: keep /*! @brief default specialization @@ -4027,7 +4035,7 @@ NLOHMANN_JSON_NAMESPACE_END /// @brief a minimal map-like container that preserves insertion order /// @sa https://json.nlohmann.me/api/ordered_map/ template - struct ordered_map; + struct ordered_map; // IWYU pragma: keep /// @brief specialization that maintains the insertion order of object keys /// @sa https://json.nlohmann.me/api/ordered_json/ @@ -7144,7 +7152,7 @@ struct adl_serializer }; NLOHMANN_JSON_NAMESPACE_END - +// IWYU pragma: keep // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ @@ -7251,10 +7259,12 @@ class byte_container_with_subtype : public BinaryType NLOHMANN_JSON_NAMESPACE_END +// #include + // #include - +// IWYU pragma: keep // #include - +// IWYU pragma: keep // #include // #include @@ -17855,6 +17865,8 @@ NLOHMANN_JSON_NAMESPACE_END // #include +// #include + // #include // #include @@ -20836,6 +20848,8 @@ NLOHMANN_JSON_NAMESPACE_END // #include +// #include + // #include // #include @@ -26375,12 +26389,14 @@ NLOHMANN_JSON_NAMESPACE_END #include // equal_to, less #include // initializer_list #include // input_iterator_tag, iterator_traits -#include // allocator +#include // for operator new (placement new) #include // for out_of_range #include // forward_as_tuple #include // enable_if, integral_constant, is_convertible, is_nothrow_move_constructible #include // forward, move, pair, piecewise_construct -#include // vector +#include // vector, allocator + +// #include // #include @@ -26815,6 +26831,8 @@ private: }; NLOHMANN_JSON_NAMESPACE_END +// IWYU pragma: keep +// #include #if defined(JSON_HAS_CPP_17) @@ -33544,6 +33562,9 @@ struct formatter // NOLINT(cert-dcl58-c } // namespace std +// keep: undoes the macros defined via detail/macro_scope.hpp at the top of this file; removing it +// (nothing in this file *uses* a symbol from it) would leak JSON_* macros into every translation +// unit that includes this header. // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ @@ -33758,7 +33779,7 @@ struct formatter // NOLINT(cert-dcl58-c #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG #undef JSON_HEDLEY_FALL_THROUGH - +// IWYU pragma: keep // End of GCC diagnostic pragmas for C++ modules support #if defined(__GNUC__) && !defined(__clang__) && __cplusplus >= 202002L diff --git a/single_include/nlohmann/json_fwd.hpp b/single_include/nlohmann/json_fwd.hpp index f23ea4820..3ee7afa73 100644 --- a/single_include/nlohmann/json_fwd.hpp +++ b/single_include/nlohmann/json_fwd.hpp @@ -11,8 +11,7 @@ #include // int64_t, uint64_t #include // map -#include // allocator -#include // string +#include // allocator, string #include // vector // #include @@ -177,7 +176,7 @@ This serializer ignores the template arguments and uses ADL for serialization. */ template -struct adl_serializer; +struct adl_serializer; // IWYU pragma: keep /// a class to store JSON values /// @sa https://json.nlohmann.me/api/basic_json/ @@ -193,12 +192,12 @@ template class ObjectType = adl_serializer, class BinaryType = std::vector, // cppcheck-suppress syntaxError class CustomBaseClass = void> -class basic_json; +class basic_json; // IWYU pragma: keep /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document /// @sa https://json.nlohmann.me/api/json_pointer/ template -class json_pointer; +class json_pointer; // IWYU pragma: keep /*! @brief default specialization @@ -209,7 +208,7 @@ using json = basic_json<>; /// @brief a minimal map-like container that preserves insertion order /// @sa https://json.nlohmann.me/api/ordered_map/ template -struct ordered_map; +struct ordered_map; // IWYU pragma: keep /// @brief specialization that maintains the insertion order of object keys /// @sa https://json.nlohmann.me/api/ordered_json/ diff --git a/tests/src/unit.cpp b/tests/src/unit.cpp index 93a934005..c05cde9c8 100644 --- a/tests/src/unit.cpp +++ b/tests/src/unit.cpp @@ -7,4 +7,22 @@ // SPDX-License-Identifier: MIT #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN + +// libc++ annotates std::mutex for Clang's thread safety analysis, so -Weverything +// reports -Wthread-safety-negative for the locks in doctest's reporters, which are +// only compiled in this file. __has_warning keeps older Clang versions from +// reporting an unknown warning group. +#if defined(__clang__) && defined(__has_warning) + #if __has_warning("-Wthread-safety-negative") + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wthread-safety-negative" + #endif +#endif + #include "doctest_compatibility.h" + +#if defined(__clang__) && defined(__has_warning) + #if __has_warning("-Wthread-safety-negative") + #pragma clang diagnostic pop + #endif +#endif diff --git a/tools/astyle/requirements.txt b/tools/astyle/requirements.txt index 99458a860..cfa98d67e 100644 --- a/tools/astyle/requirements.txt +++ b/tools/astyle/requirements.txt @@ -1 +1,4 @@ +# astyle is deliberately pinned: newer versions reformat the code, and this version +# defines the formatting that `make amalgamate` produces and check_amalgamation.yml enforces. +# Dependabot is told to ignore it in .github/dependabot.yml. astyle==3.4.13