Compare commits

..
Author SHA1 Message Date
Niels Lohmann b640bf728d Re-enable portability-template-virtual-member-function; remove redundant forwards
.clang-tidy disabled three checks "to get the CI going" (#4489,
2024-11-13): portability-template-virtual-member-function,
bugprone-use-after-move and its alias hicpp-invalid-access-moved.

portability-template-virtual-member-function only flagged
output_stream_adapter::write_character/write_characters; annotate
both with NOLINT and re-enable the check.

bugprone-use-after-move flagged several double forwards that have no
effect at runtime:
- from_json.hpp calls std::forward<BasicJsonType>(j).at(Idx) inside
  pack expansions; at() has no ref-qualified overloads and always
  returns an lvalue reference, so the forward is a no-op. Replace with
  plain j.at(Idx) in all four places.
- the move constructor forwards the whole object to its base class
  and then reads other's members. That is item 9 of #5724 (together
  with its cppcheck suppressions) and is left to that change.
- input_adapters.hpp forwards the container twice on purpose, so the
  begin/end iterator types match adapter_type; annotate with NOLINT
  and a comment instead of changing behavior.

The check still flags the move constructor (see above) and two sites
in at(KeyType&&) (both overloads, json.hpp, in the throw's
string_t(std::forward<KeyType>(key)) after
find(std::forward<KeyType>(key))). Open PR #5689 rewrites that hunk,
so bugprone-use-after-move (and hicpp-invalid-access-moved)
stay disabled for now, with a comment explaining why; re-enable them
once #5689 and the #5724 move-constructor change have landed.

Also resolve the portability-avoid-pragma-once TODO: single_include
never has #pragma once (amalgamate.py strips it) and every supported
compiler accepts it in include/, so keep it disabled with an
explanatory comment instead of a TODO. Fix the stale "json.hpp,
around line 1265" comment in unit-class_parser.cpp, which now points
at the move constructor's actual line.

Behavior, the public API and the ABI do not change. Verified with
clang-tidy 22.1.8 that portability-template-virtual-member-function
now reports nothing, that bugprone-use-after-move/
hicpp-invalid-access-moved report only the known at(KeyType&&) and
move-constructor sites, and that unit-custom-base-class, unit-constructor1,
unit-conversions, unit-element_access2, unit-class_parser and
unit-diagnostic-positions (JSON_DIAGNOSTIC_POSITIONS=1) compile
under ASan/UBSan and pass with the same assertion counts as before.
Ran make amalgamate.

Part of #5725

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 10:33:04 +02:00
Niels Lohmann 27db8bd678 Remove the no-op ci_clang_analyze target
ci_clang_analyze configured the build with the real compiler and only
then wrapped ninja with scan-build. scan-build intercepts compiles by
overriding CC/CXX, but build.ninja already had the compiler path baked
in from the configure step, so every run bypassed the analyzer: CI
logs show "No bugs found" after a normal build, never an analysis.
The job also used Debian's frozen clang-tools-14 rather than the
image's own clang, and CLANG_ANALYZER_CHECKS still named three
valist.* checkers that current clang merged into security.VAList.

ci_clang_tidy already runs every clang-analyzer-* check (via
.clang-tidy's "Checks: '*'") with warnings as errors, so nothing is
lost by removing the dead job. Delete ci_clang_analyze,
CLANG_ANALYZER_CHECKS and the SCAN_BUILD_TOOL lookup from
cmake/ci.cmake, drop it from the ubuntu.yml ci_static_analysis_clang
matrix, and drop the now-unused clang-tools apt package (iwyu stays
for ci_single_binaries). Reword quality_assurance.md and
assurance_case.md, which described the dead job as a working control,
to say the Clang Static Analyzer checks run through clang-tidy.

Verified that `cmake -DJSON_CI=ON` still configures cleanly and that
ci_clang_analyze no longer appears in the generated build or in any
CMake/workflow file.

Part of #5725

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 09:55:24 +02:00
Niels Lohmann 819838839d Include doctest as a SYSTEM directory instead of disabling warnings for all tests
test_main added -Wno-deprecated and -Wno-float-equal as PUBLIC compile
options for every non-MSVC compiler, so they were applied to every
translation unit, library headers included, and silenced the CI
warnings meant to check the library's own -Wfloat-equal pragmas. The
only code that actually needed the suppression was the vendored
doctest.h, which was included as a normal (non-SYSTEM) directory.

Include thirdparty/doctest as SYSTEM for test_main, matching what
tests/abi/CMakeLists.txt already does, and drop the two suppressions
from both targets. Verified locally that unit-comparison,
unit-conversions and unit-constructor1 compile clean with
-Werror -Weverything and doctest as -isystem, and that CMake still
configures with JSON_BuildTests=ON.

Part of #5725

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 09:54:07 +02:00
Niels Lohmann 20bbb137ba Name all three C-array check aliases in the enum-macro NOLINTs
NLOHMANN_JSON_SERIALIZE_ENUM(_STRICT) suppressed the c-array warning
under modernize-avoid-c-arrays only, but clang-tidy emits the same
diagnostic under the aliases cppcoreguidelines-avoid-c-arrays and
hicpp-avoid-c-arrays too. Any user running those checks got a false
positive at every macro expansion, and our own tests needed a local
NOLINT at each call site to work around it.

Name all three aliases in the four macro comments instead, and drop
the now-redundant c-array names from the five test call-site NOLINTs.
Comment-only change; behavior, the public API, and the ABI do not
change. Ran make amalgamate.

Part of #5725

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 09:52:09 +02:00
Niels Lohmann 146b9e7615 Drop stale LCOV_EXCL_LINE from the json_pointer out_of_range.410 throw
The comment said the size_type overflow check in array_index() is only
triggered on special platforms like 32-bit, and the throw was excluded
from coverage. On 64-bit platforms the check is true for SIZE_MAX
itself, and unit-json_pointer.cpp has asserted that case four times
since #5395, so the line is executed in the coverage job. Reword the
comment and remove the exclusion marker so the coverage report notices
if the tests stop reaching it.

Part of #5725

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 09:44:28 +02:00
21 changed files with 70 additions and 80 deletions
+9 -3
View File
@@ -1,9 +1,15 @@
# TODO: The first three checks are only removed to get the CI going. They have to be addressed at some point.
# TODO: portability-avoid-pragma-once: should be fixed eventually
# bugprone-use-after-move (hicpp-invalid-access-moved is its alias) still flags
# the basic_json move constructor, which forwards the whole object to its base
# class (#5724), and two forwards in the error-message construction of
# at(KeyType&&) (json.hpp, both overloads: find(std::forward<KeyType>(key))
# followed by string_t(std::forward<KeyType>(key)) in the throw), which #5689
# rewrites. Re-enable both checks once those changes have landed.
# portability-avoid-pragma-once: kept disabled on purpose. #pragma once is accepted
# by every supported compiler, and tools/amalgamate/amalgamate.py strips it from
# single_include, so there is nothing left to fix here.
Checks: '*,
-portability-template-virtual-member-function,
-bugprone-use-after-move,
-hicpp-invalid-access-moved,
+3 -3
View File
@@ -81,10 +81,10 @@ jobs:
container: silkeh/clang:dev
strategy:
matrix:
target: [ci_test_clang, ci_clang_tidy, ci_test_clang_sanitizer, ci_clang_analyze, ci_single_binaries]
target: [ci_test_clang, ci_clang_tidy, ci_test_clang_sanitizer, ci_single_binaries]
steps:
- name: Install git, clang-tools, iwyu (ci_single_binaries), and unzip
run: apt-get update ; apt-get install -y git clang-tools iwyu unzip
- name: Install git, iwyu (ci_single_binaries), and unzip
run: apt-get update ; apt-get install -y git iwyu unzip
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
+1 -1
View File
@@ -10,5 +10,5 @@ title: "JSON for Modern C++"
version: 3.12.0
date-released: 2025-04-07
license: MIT
repository-code: "https://github.com/nlohmann/json"
repository-code: "https://github.com/nlohmann"
url: https://json.nlohmann.me
+1 -4
View File
@@ -42,11 +42,8 @@ endif()
## OPTIONS
##
# Build the tests by default only for the main project and only if the tests
# directory exists (the release archive json.tar.xz does not contain it).
# VERSION_GREATER_EQUAL is not available in older CMake (< 3.7)
if(${MAIN_PROJECT} AND (${CMAKE_VERSION} VERSION_EQUAL 3.13 OR ${CMAKE_VERSION} VERSION_GREATER 3.13)
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/CMakeLists.txt")
if(${MAIN_PROJECT} AND (${CMAKE_VERSION} VERSION_EQUAL 3.13 OR ${CMAKE_VERSION} VERSION_GREATER 3.13))
set(JSON_BuildTests_INIT ON)
else()
set(JSON_BuildTests_INIT OFF)
+2 -5
View File
@@ -7,9 +7,6 @@
# find GNU sed to use `-i` parameter
SED:=$(shell command -v gsed || which sed)
# find GNU tar to use `--sort` and `--pax-option` parameters
TAR:=$(shell command -v gtar || which tar)
##########################################################################
# source files
@@ -218,8 +215,8 @@ ChangeLog.md:
# archive is created according to the advices of <https://reproducible-builds.org/docs/archives/>.
json.tar.xz:
mkdir json
rsync -R $(shell find LICENSE.MIT nlohmann_json.natvis CMakeLists.txt cmake/*.in include single_include src/modules -type f) json
$(TAR) --sort=name --mtime="@$(shell git log -1 --pretty=%ct)" --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime --create --file - json | xz --compress -9e --threads=2 - > json.tar.xz
rsync -R $(shell find LICENSE.MIT nlohmann_json.natvis CMakeLists.txt cmake/*.in include single_include -type f) json
gtar --sort=name --mtime="@$(shell git log -1 --pretty=%ct)" --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime --create --file - json | xz --compress -9e --threads=2 - > json.tar.xz
rm -fr json
# We use `-X` to make the resulting ZIP file reproducible, see
+9 -12
View File
@@ -1204,18 +1204,15 @@ language bindings, format converters, and the like. See the curated [Ecosystem](
Though it's 2026 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
- GCC 4.8 - 16.2 (and possibly later)
- Clang 3.4 - 22.1 (and possibly later)
- Apple Clang 15.0 - 21.0 (and possibly later)
- Intel C++ Compiler Classic (icpc) 2021.10
- Intel oneAPI DPC++/C++ Compiler (icpx) 2025.3 (and possibly later)
- NVIDIA CUDA Compiler (nvcc) 11.8 - 12.6 (and possibly later)
- NVIDIA HPC SDK C++ Compiler (nvc++) 25.5 (and possibly later)
- Microsoft Visual C++ 2015 / MSVC 19.0 (and possibly later)
- Microsoft Visual C++ 2017 / MSVC 19.16 (and possibly later)
- Microsoft Visual C++ 2019 / MSVC 19.29 (and possibly later)
- Microsoft Visual C++ 2022 / MSVC 19.44 (and possibly later)
- Microsoft Visual C++ 2026 / MSVC 19.51 (and possibly later)
- GCC 4.8 - 14.2 (and possibly later)
- Clang 3.4 - 21.0 (and possibly later)
- Apple Clang 9.1 - 16.0 (and possibly later)
- Intel C++ Compiler 17.0.2 (and possibly later)
- Nvidia CUDA Compiler 11.0.221 (and possibly later)
- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later)
- Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later)
- Microsoft Visual C++ 2019 / Build Tools 16.3.1+1def00d3d (and possibly later)
- Microsoft Visual C++ 2022 / Build Tools 19.30.30709.0 (and possibly later)
I would be happy to learn about other compilers/versions.
-16
View File
@@ -69,7 +69,6 @@ message(STATUS "🔖 Valgrind ${VALGRIND_TOOL_VERSION} (${VALGRIND_TOOL})")
find_program(GENHTML_TOOL NAMES genhtml)
find_program(PLOG_CONVERTER_TOOL NAMES plog-converter)
find_program(PVS_STUDIO_ANALYZER_TOOL NAMES pvs-studio-analyzer)
find_program(SCAN_BUILD_TOOL NAMES scan-build-15 scan-build-14 scan-build-13 scan-build-12 scan-build-11 scan-build)
# the individual source files
file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/include/nlohmann/*.hpp)
@@ -423,21 +422,6 @@ add_custom_target(ci_test_valgrind
COMMENT "Compile and test with 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")
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
COMMENT "Check code with Clang Analyzer"
)
###############################################################################
# Check code with Cppcheck.
###############################################################################
+2 -2
View File
@@ -60,11 +60,11 @@ measures that counter them. The measures are described in detail in [Quality ass
|---------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|
| Out-of-bounds read/write ([CWE-125](https://cwe.mitre.org/data/definitions/125.html), [CWE-787](https://cwe.mitre.org/data/definitions/787.html)) | bounds checks on all reads from the input; AddressSanitizer and Valgrind on the test suite; OSS-Fuzz |
| Integer overflow ([CWE-190](https://cwe.mitre.org/data/definitions/190.html)) | UndefinedBehaviorSanitizer with integer overflow detection; Clang-Tidy; Cppcheck |
| Use after free, double free ([CWE-416](https://cwe.mitre.org/data/definitions/416.html), [CWE-415](https://cwe.mitre.org/data/definitions/415.html)) | ownership of all memory by values; AddressSanitizer and Valgrind; Clang Static Analyzer |
| Use after free, double free ([CWE-416](https://cwe.mitre.org/data/definitions/416.html), [CWE-415](https://cwe.mitre.org/data/definitions/415.html)) | ownership of all memory by values; AddressSanitizer and Valgrind; Clang-Tidy (incl. Clang Static Analyzer checks) |
| Memory leaks ([CWE-401](https://cwe.mitre.org/data/definitions/401.html)) | Valgrind (Memcheck) on the test suite |
| Uncontrolled recursion ([CWE-674](https://cwe.mitre.org/data/definitions/674.html)) | iterative parser, binary readers, and destructor; bounded recursion in value operations; tests with deeply nested inputs |
| Uncontrolled resource consumption ([CWE-400](https://cwe.mitre.org/data/definitions/400.html)) | allocations based on announced sizes are capped; OSS-Fuzz with memory limits |
| Undefined behavior in general ([CWE-758](https://cwe.mitre.org/data/definitions/758.html)) | UndefinedBehaviorSanitizer; runtime assertions; Clang-Tidy, Cppcheck, Clang Static Analyzer, Infer |
| Undefined behavior in general ([CWE-758](https://cwe.mitre.org/data/definitions/758.html)) | UndefinedBehaviorSanitizer; runtime assertions; Clang-Tidy (incl. Clang Static Analyzer checks), Cppcheck, Infer |
In addition, every line of the library is covered by the unit tests, and all parsers are fuzz-tested around the clock
by [OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json).
@@ -183,8 +183,8 @@ Note: Some modern features (like C++20 ranges or filesystem support) may be disa
```
- [x] The code is checked with the latest [Cppcheck](https://cppcheck.sourceforge.io) with all warnings enabled.
- [x] The code is checked with the latest [Clang Static Analyzer](https://clang-analyzer.llvm.org) with 89 enabled
rules.
- [x] The code is checked with the latest [Clang Static Analyzer](https://clang-analyzer.llvm.org) checks, run
through Clang-Tidy's `clang-analyzer-*` checks with warnings as errors.
- [x] The code is checked with [Infer](https://fbinfer.com).
- [x] The code is checked with [Codacy](https://app.codacy.com/gh/nlohmann/json/dashboard).
+1 -1
View File
@@ -125,7 +125,7 @@ automatically download a release as a dependency at configure time.
### `JSON_BuildTests`
Build the unit tests when [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/command/enable_testing.html) is enabled. This option is `ON` by default if the library's CMake project is the top project and the `tests` directory exists (the release archive `json.tar.xz` does not contain it). That is, when integrating the library as described above, the test suite is not built unless explicitly switched on with this option.
Build the unit tests when [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/command/enable_testing.html) is enabled. This option is `ON` by default if the library's CMake project is the top project. That is, when integrating the library as described above, the test suite is not built unless explicitly switched on with this option.
### `JSON_CI`
@@ -353,7 +353,7 @@ template < typename BasicJsonType, typename T, std::size_t... Idx >
std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
{
return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
return { { j.at(Idx).template get<T>()... } };
}
template < typename BasicJsonType, typename T, std::size_t N >
@@ -502,7 +502,7 @@ using tuple_type = std::tuple < decltype(from_json_tuple_get_impl(std::declval<B
template<std::size_t PTagValue, typename... Args, typename BasicJsonType, std::size_t... Idx>
tuple_type<PTagValue, BasicJsonType, Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
{
return tuple_type<PTagValue, BasicJsonType, Args...>(from_json_tuple_get_impl(std::forward<BasicJsonType>(j).at(Idx), detail::identity_tag<Args> {}, detail::priority_tag<PTagValue> {})...);
return tuple_type<PTagValue, BasicJsonType, Args...>(from_json_tuple_get_impl(j.at(Idx), detail::identity_tag<Args> {}, detail::priority_tag<PTagValue> {})...);
}
template<std::size_t PTagValue, typename BasicJsonType>
@@ -514,8 +514,8 @@ std::tuple<> from_json_tuple_impl_base(BasicJsonType& /*unused*/, index_sequence
template < typename BasicJsonType, class A1, class A2 >
std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
{
return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
std::forward<BasicJsonType>(j).at(1).template get<A2>()};
return {j.at(0).template get<A1>(),
j.at(1).template get<A2>()};
}
template<typename BasicJsonType, typename A1, typename A2>
@@ -763,6 +763,9 @@ struct container_input_adapter_factory< ContainerType,
static adapter_type create(ContainerType&& container)
{
// container is forwarded twice on purpose: the resulting begin/end
// iterator types must match adapter_type, computed the same way
// NOLINTNEXTLINE(bugprone-use-after-move)
return input_adapter(begin(std::forward<ContainerType>(container)), end(std::forward<ContainerType>(container)));
}
};
+3 -3
View File
@@ -277,11 +277,11 @@ class json_pointer
JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
}
// only triggered on special platforms (like 32bit), see also
// https://github.com/nlohmann/json/pull/2203
// the index does not fit into size_type; on 64-bit platforms this is
// only SIZE_MAX itself (see #2203 and #5395)
if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
{
JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr));
}
return static_cast<size_type>(res);
+4 -4
View File
@@ -260,7 +260,7 @@
{ \
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
/* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \
[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
@@ -274,7 +274,7 @@
{ \
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
/* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
@@ -313,7 +313,7 @@ void templated_json_throw(ExceptionType exception)
{ \
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
/* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \
[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
@@ -328,7 +328,7 @@ void templated_json_throw(ExceptionType exception)
{ \
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
/* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
@@ -117,12 +117,14 @@ class output_stream_adapter : public output_adapter_protocol<CharType>
: stream(s)
{}
// NOLINTNEXTLINE(portability-template-virtual-member-function)
void write_character(CharType c) override
{
stream.put(c);
}
JSON_HEDLEY_NON_NULL(2)
// NOLINTNEXTLINE(portability-template-virtual-member-function)
void write_characters(const CharType* s, std::size_t length) override
{
stream.write(s, static_cast<std::streamsize>(length));
+16 -11
View File
@@ -2671,7 +2671,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP
{ \
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
/* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \
[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
@@ -2685,7 +2685,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP
{ \
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
/* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
@@ -2724,7 +2724,7 @@ void templated_json_throw(ExceptionType exception)
{ \
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
/* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \
[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
@@ -2739,7 +2739,7 @@ void templated_json_throw(ExceptionType exception)
{ \
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
/* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
@@ -5850,7 +5850,7 @@ template < typename BasicJsonType, typename T, std::size_t... Idx >
std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
{
return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
return { { j.at(Idx).template get<T>()... } };
}
template < typename BasicJsonType, typename T, std::size_t N >
@@ -5999,7 +5999,7 @@ using tuple_type = std::tuple < decltype(from_json_tuple_get_impl(std::declval<B
template<std::size_t PTagValue, typename... Args, typename BasicJsonType, std::size_t... Idx>
tuple_type<PTagValue, BasicJsonType, Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
{
return tuple_type<PTagValue, BasicJsonType, Args...>(from_json_tuple_get_impl(std::forward<BasicJsonType>(j).at(Idx), detail::identity_tag<Args> {}, detail::priority_tag<PTagValue> {})...);
return tuple_type<PTagValue, BasicJsonType, Args...>(from_json_tuple_get_impl(j.at(Idx), detail::identity_tag<Args> {}, detail::priority_tag<PTagValue> {})...);
}
template<std::size_t PTagValue, typename BasicJsonType>
@@ -6011,8 +6011,8 @@ std::tuple<> from_json_tuple_impl_base(BasicJsonType& /*unused*/, index_sequence
template < typename BasicJsonType, class A1, class A2 >
std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
{
return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
std::forward<BasicJsonType>(j).at(1).template get<A2>()};
return {j.at(0).template get<A1>(),
j.at(1).template get<A2>()};
}
template<typename BasicJsonType, typename A1, typename A2>
@@ -8307,6 +8307,9 @@ struct container_input_adapter_factory< ContainerType,
static adapter_type create(ContainerType&& container)
{
// container is forwarded twice on purpose: the resulting begin/end
// iterator types must match adapter_type, computed the same way
// NOLINTNEXTLINE(bugprone-use-after-move)
return input_adapter(begin(std::forward<ContainerType>(container)), end(std::forward<ContainerType>(container)));
}
};
@@ -19119,11 +19122,11 @@ class json_pointer
JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
}
// only triggered on special platforms (like 32bit), see also
// https://github.com/nlohmann/json/pull/2203
// the index does not fit into size_type; on 64-bit platforms this is
// only SIZE_MAX itself (see #2203 and #5395)
if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
{
JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr));
}
return static_cast<size_type>(res);
@@ -20256,12 +20259,14 @@ class output_stream_adapter : public output_adapter_protocol<CharType>
: stream(s)
{}
// NOLINTNEXTLINE(portability-template-virtual-member-function)
void write_character(CharType c) override
{
stream.put(c);
}
JSON_HEDLEY_NON_NULL(2)
// NOLINTNEXTLINE(portability-template-virtual-member-function)
void write_characters(const CharType* s, std::size_t length) override
{
stream.write(s, static_cast<std::streamsize>(length));
+2 -2
View File
@@ -90,11 +90,11 @@ target_compile_options(test_main PUBLIC
# https://github.com/nlohmann/json/pull/3229
$<$<CXX_COMPILER_ID:Intel>:-diag-disable=2196>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
$<$<CXX_COMPILER_ID:Intel>:-diag-disable=1786>)
target_include_directories(test_main SYSTEM PUBLIC
thirdparty/doctest)
target_include_directories(test_main PUBLIC
thirdparty/doctest
thirdparty/fifo_map
${PROJECT_BINARY_DIR}/include)
target_link_libraries(test_main PUBLIC ${NLOHMANN_JSON_TARGET_NAME})
-1
View File
@@ -12,7 +12,6 @@ target_compile_options(abi_compat_common INTERFACE
# https://github.com/nlohmann/json/pull/3229
$<$<CXX_COMPILER_ID:Intel>:-diag-disable=2196>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
$<$<CXX_COMPILER_ID:Intel>:-diag-disable=1786>)
target_include_directories(abi_compat_common SYSTEM INTERFACE
+1 -1
View File
@@ -2525,7 +2525,7 @@ TEST_CASE("diagnostic positions: value lifetime, input adapters, and SAX")
SECTION("move constructor resets the moved-from value to npos")
{
// basic_json(basic_json&&) (json.hpp, around line 1265) copies
// basic_json(basic_json&&) (json.hpp, around line 1951) copies
// other's start_position/end_position into *this and then resets
// other's to npos (see the cppcheck-suppress[accessForwarded]
// annotation there, which flags this reset as worth a second
+4 -4
View File
@@ -1622,7 +1622,7 @@ TEST_CASE("value conversion")
enum class cards {kreuz, pik, herz, karo};
// NOLINTNEXTLINE(misc-use-internal-linkage,misc-const-correctness,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
// NOLINTNEXTLINE(misc-use-internal-linkage,misc-const-correctness) - false positive
NLOHMANN_JSON_SERIALIZE_ENUM(cards,
{
{cards::kreuz, "kreuz"},
@@ -1640,7 +1640,7 @@ enum TaskState // NOLINT(cert-int09-c,readability-enum-initial-value,cppcoreguid
TS_INVALID = -1,
};
// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage) - false positive
NLOHMANN_JSON_SERIALIZE_ENUM(TaskState,
{
{TS_INVALID, nullptr},
@@ -1690,7 +1690,7 @@ TEST_CASE("JSON to enum mapping")
enum class strict_cards {kreuz, pik, herz, karo, andere}; // andere not included in mapping
// NOLINTNEXTLINE(misc-use-internal-linkage,misc-const-correctness,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
// NOLINTNEXTLINE(misc-use-internal-linkage,misc-const-correctness) - false positive
NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(strict_cards,
{
{strict_cards::kreuz, "kreuz"},
@@ -1709,7 +1709,7 @@ enum StrictTaskState // NOLINT(cert-int09-c,readability-enum-initial-value,cppco
STRICT_TS_INVALID = -1,
};
// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage) - false positive
NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(StrictTaskState,
{
{STRICT_TS_INVALID, nullptr},
+1 -1
View File
@@ -112,7 +112,7 @@ enum class for_1647
two
};
// NOLINTNEXTLINE(misc-const-correctness,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays): this is a false positive
// NOLINTNEXTLINE(misc-const-correctness): this is a false positive
NLOHMANN_JSON_SERIALIZE_ENUM(for_1647,
{
{for_1647::one, "one"},