diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 12222cb3..bdffe109 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -4875,9 +4875,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 f7a4c5a1..de146ed6 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -19734,9 +19734,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 3518c4ae..5d48b2ea 100644 --- a/test/src/unit-allocator.cpp +++ b/test/src/unit-allocator.cpp @@ -234,3 +234,45 @@ TEST_CASE("controlled bad_alloc") } } } + +namespace +{ +template +struct allocator_no_forward : std::allocator +{ + allocator_no_forward() {} + template + allocator_no_forward(allocator_no_forward) {} + + template + struct rebind { + using other = allocator_no_forward; + }; + + template + void construct(T* p, const Args&... args) + { + // force copy even if move is available + ::new (static_cast(p)) T(args...); + } +}; +} + +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"); + } +}