JSON_DIAGNOSTICS trigger assertion
Description
Hi,
I have activated the JSON_DIAGNOSTICS=1 globally in my project and ASSERTION are now fired at runtime. I tested it on with 3.10.5 and then with latest release 3.11.2.
I have done a minimal example to reproduce the assertion (see minimal code example below)
Is there something wrong with my code?
Reproduction steps
Run the minimal code example below
Expected vs. actual results
No ASSERTION should be triggered since without the JSON_DIAGNOSTICS enabled, all seem to work without any memory issues
Minimal code example
json j = json::object();
j["root"] = "root_str";
json jj = json::object();
jj["child"] = json::object();
// If do not push anything in object, then no assert will be produced
jj["child"]["prop1"] = "prop1_value";
// Push all properties of child in parent
j.insert(jj.at("child").begin(), jj.at("child").end());
// Here assert is generated when construct new json
json k(j);
Error messages
nlohmann/json.hpp:19864: void nlohmann::json_abi_diag_v3_11_2::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, adl_serializer, std::vector<unsigned char, std::allocator<unsigned char> > >::assert_invariant(bool) const [ObjectType = std::map, ArrayType = std::vector, StringType = std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, BooleanType = bool, NumberIntegerType = long, NumberUnsignedType = unsigned long, NumberFloatType = double, AllocatorType = std::allocator, JSONSerializer = adl_serializer, BinaryType = std::vector<unsigned char, std::allocator<unsigned char> >]: Assertion `!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j) { return j.m_parent == this; })' failed.
Compiler and operating system
Clang-10 on Ubuntu 20.04
Library version
3.11.2
Validation
- [ ] The bug also occurs if the latest version from the
developbranch is used. - [ ] I can successfully compile and run the unit tests.
I can confirm the issue.
If I understood the code correctly, as of json k(j); the invariant is invalid for instance j due to function insert(it, it) missing a call to set_parents() after this line of code: https://github.com/nlohmann/json/blob/develop/include/nlohmann/json.hpp#L3408
Provided I got the meaning of the statement, during insertion, the properties are basically copied (inserted) to the underlying data structure ObjectType (being std::map for default nlohmann::json) and the copies keep the original parent (as no set_parents() is called during insertion).