document aliasing precondition for array::insert(pos, init) - #1174
document aliasing precondition for array::insert(pos, init)#1174Ramya-9353 wants to merge 1 commit into
Conversation
|
An automated preview of the documentation is available at https://1174.json.prtest2.cppalliance.org/libs/json/doc/html/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-08-14 11:49:06 UTC |
|
GCOVR code coverage report https://1174.json.prtest2.cppalliance.org/gcovr/index.html Build time: 2026-08-14 12:01:11 UTC |
|
|
4be67a7 to
e8492c7
Compare
|
Rebased onto current develop to re-run CI. The only red stage on the previous drone build (Linux GCC 12 arm64) hung for ~44h and was killed by the runner; all other 65 stages passed, including the ASan/UBSan/TSan/Valgrind jobs. No code changes. |
|
I thought, I commented on this PR, but it appears that I have forgotten to do that. While I understand the problem, in this case the solution might be to just declare such use UB and hence motivate the caller to create the temporary themselves. Did you catch the bug in an organic usage scenario, or have you encountered it simply by analysing corner cases? |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1174 +/- ##
===========================================
- Coverage 93.91% 93.71% -0.21%
===========================================
Files 91 85 -6
Lines 9288 8971 -317
===========================================
- Hits 8723 8407 -316
+ Misses 565 564 -1
... and 8 files with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
|
|
|
Corner-case analysis, not an organic report. After the fill-value aliasing fix in #1167 I went through the remaining array mutators looking for reads of user-supplied sources after reallocation, and this overload was the last one left. On declaring it UB: that's defensible, but it would make this overload the odd one out. The count-fill and input-iterator overloads already tolerate aliasing, and the equivalent braced-list insert on std::vector is well defined because the list materialises copies before the call, so the pointer semantics of value_ref are what make it surprising here; nothing at the call site hints that a temporary is needed. The cost is one temporary array on this overload only, the same as the range insert already pays. That said, if you'd rather document it as a precondition instead, I can rework the PR that way. |
|
Almost the entire point of this overload is to avoid an allocation of a temporary. Otherwise you could just do |
e8492c7 to
58ee1d0
Compare
|
Fair enough, the temporary does undercut the reason the overload exists. Reworked as you suggested: the code change and test are gone, and the doc block now declares the aliasing UB with a precondition next to the existing |
|
|



Repro:
a.insert(a.begin(), {a[0], a[1]})on an array withsize() == capacity()reports an ASAN heap-use-after-free; theinitializer_list<value_ref>overload buildsrevert_insertfirst, which on the growth path frees the old table beforewrite_arraydereferences thevalue_refs that point into it.Resolution: per review, buffering the list into a temporary would defeat the point of the overload, so such use is declared UB instead. This adds the aliasing precondition to the docs, alongside the existing
first/lastprecondition on the range overload. Callers needing the self-referential form can materialise a temporary themselves.