diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index b72410d71..da3d57b14 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -4878,9 +4878,7 @@ class basic_json // add element to array (move semantics) m_value.array->push_back(std::move(val)); - // invalidate object: mark it null so we do not call the destructor - // cppcheck-suppress accessMoved - val.m_type = value_t::null; + // if val is moved from, basic_json move constructor marks it null so we do not call the destructor } /*! diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 77bd1739c..4d0b84f49 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -19421,9 +19421,7 @@ class basic_json // add element to array (move semantics) m_value.array->push_back(std::move(val)); - // invalidate object: mark it null so we do not call the destructor - // cppcheck-suppress accessMoved - val.m_type = value_t::null; + // if val is moved from, basic_json move constructor marks it null so we do not call the destructor } /*! diff --git a/test/src/unit-allocator.cpp b/test/src/unit-allocator.cpp index 3518c4ae7..c751d3c55 100644 --- a/test/src/unit-allocator.cpp +++ b/test/src/unit-allocator.cpp @@ -234,3 +234,51 @@ TEST_CASE("controlled bad_alloc") } } } + +namespace +{ +template +struct allocator_no_forward +{ + typedef std::remove_const_t value_type; + template + struct rebind + { + typedef allocator_no_forward other; + }; + + T* allocate(size_t sz) + { + return static_cast(malloc(sz * sizeof(T))); + } + + void deallocate(T* p, size_t) + { + free(p); + } + + void construct(T* p, const T& arg) + { + ::new (static_cast(p)) T(arg); + } +}; +} + +TEST_CASE("bad my_allocator::construct") +{ + SECTION("my_allocator::construct doesn't forward") + { + using bad_alloc_json = nlohmann::basic_json; + + bad_alloc_json json; + json["test"] = bad_alloc_json::array_t(); + json["test"].push_back("should not leak"); + } +}