diff --git a/include/boost/json/impl/array.ipp b/include/boost/json/impl/array.ipp index 259f422b4..531fc6018 100644 --- a/include/boost/json/impl/array.ipp +++ b/include/boost/json/impl/array.ipp @@ -516,10 +516,17 @@ insert( value_ref> init) -> iterator { + // the initializer_list elements may reference elements of this + // array, whose storage revert_insert can relocate and free, so + // materialise them into a temporary before inserting + array temp(init, sp_); revert_insert r( - pos, init.size(), *this); - value_ref::write_array( - r.p, init, sp_); + pos, temp.size(), *this); + relocate( + r.p, + temp.data(), + temp.size()); + temp.t_->size = 0; return r.commit(); } diff --git a/test/array.cpp b/test/array.cpp index cc4bea6fe..a587c1b68 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -1048,6 +1048,27 @@ class array_test BOOST_TEST(a[4].as_int64() == 4); }); + // init_list elements alias elements and insertion reallocates + fail_loop([&](storage_ptr const& sp) + { + array a(sp); + a.reserve(4); + a.emplace_back(1); + a.emplace_back(2); + a.emplace_back(3); + a.emplace_back(4); + BOOST_TEST(a.capacity() == a.size()); + a.insert(a.begin(), {a[3], a[0]}); + BOOST_TEST(a.size() == 6); + BOOST_TEST(a[0].as_int64() == 4); + BOOST_TEST(a[1].as_int64() == 1); + BOOST_TEST(a[2].as_int64() == 1); + BOOST_TEST(a[3].as_int64() == 2); + BOOST_TEST(a[4].as_int64() == 3); + BOOST_TEST(a[5].as_int64() == 4); + check_storage(a, sp); + }); + // emplace(const_iterator, arg) fail_loop([&](storage_ptr const& sp) {