From dbf9f45455e4f759322ca4f24b72fb41fcfde84c Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 14 Oct 2026 17:58:07 +0200 Subject: [PATCH] Update cppcheck to 1.5.2 (Cppcheck 2.20) and fix its new findings Cppcheck 2.20 rejects invocations of unknown function-like macros in #if conditions instead of evaluating them as 0. default_defines.hpp expands the Hedley macros to the compiler's feature-test operators (__has_attribute etc.), so define them as 0 in a generated include file. It also reports a false bufferAccessOutOfBounds in the float overload of float_from_bits, sizing the parameter as the double overload's; use the size of the source instead (equal by the static_assert). Signed-off-by: Niels Lohmann --- cmake/ci.cmake | 9 ++++++++- cmake/requirements/requirements-cppcheck.txt | 2 +- include/nlohmann/detail/input/number_parse.hpp | 2 +- single_include/nlohmann/json.hpp | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/cmake/ci.cmake b/cmake/ci.cmake index cc8aaf620..d85214922 100644 --- a/cmake/ci.cmake +++ b/cmake/ci.cmake @@ -485,6 +485,13 @@ add_custom_target(ci_clang_analyze # Check code with Cppcheck. ############################################################################### +# default_defines.hpp expands the Hedley macros to the compiler's feature-test operators, which Cppcheck does not know. +# Since Cppcheck 2.20, it rejects their invocations in #if conditions instead of evaluating them as 0. +file(WRITE ${CMAKE_BINARY_DIR}/cppcheck_feature_tests.hpp "") +foreach(OPERATOR __has_attribute __has_builtin __has_cpp_attribute __has_declspec_attribute __has_extension __has_feature __has_include __has_warning) + file(APPEND ${CMAKE_BINARY_DIR}/cppcheck_feature_tests.hpp "#define ${OPERATOR}(x) 0\n") +endforeach() + add_custom_target(ci_cppcheck COMMAND mkdir -p cppcheck COMMAND clang -dM -E -x c++ -std=c++11 ${CMAKE_SOURCE_DIR}/include/nlohmann/thirdparty/hedley/hedley.hpp > default_defines.hpp 2> /dev/null @@ -493,7 +500,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 + --include=${CMAKE_BINARY_DIR}/cppcheck_feature_tests.hpp --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" diff --git a/cmake/requirements/requirements-cppcheck.txt b/cmake/requirements/requirements-cppcheck.txt index aa1591128..ecfb21ac7 100644 --- a/cmake/requirements/requirements-cppcheck.txt +++ b/cmake/requirements/requirements-cppcheck.txt @@ -1 +1 @@ -cppcheck==1.5.1 +cppcheck==1.5.2 diff --git a/include/nlohmann/detail/input/number_parse.hpp b/include/nlohmann/detail/input/number_parse.hpp index e6e5bd58b..ccd8ac11f 100644 --- a/include/nlohmann/detail/input/number_parse.hpp +++ b/include/nlohmann/detail/input/number_parse.hpp @@ -704,7 +704,7 @@ inline void float_from_bits(std::uint64_t bits, float& value) noexcept { static_assert(sizeof(float) == sizeof(std::uint32_t), "float must have 32 bits"); const auto bits32 = static_cast(bits); - std::memcpy(&value, &bits32, sizeof(value)); + std::memcpy(&value, &bits32, sizeof(bits32)); } /// the powers of ten that are exact in binary64 (up to 10^22) diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index a35f9e32c..9f1d4370e 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -10151,7 +10151,7 @@ inline void float_from_bits(std::uint64_t bits, float& value) noexcept { static_assert(sizeof(float) == sizeof(std::uint32_t), "float must have 32 bits"); const auto bits32 = static_cast(bits); - std::memcpy(&value, &bits32, sizeof(value)); + std::memcpy(&value, &bits32, sizeof(bits32)); } /// the powers of ten that are exact in binary64 (up to 10^22)