Bug 117541 - vector::insert_range should not use ranges::copy
Summary: vector::insert_range should not use ranges::copy
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 15.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks: 111055 std::vector
  Show dependency treegraph
 
Reported: 2024-11-12 02:10 UTC by 康桓瑋
Modified: 2024-12-21 07:13 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-11-13 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description 康桓瑋 2024-11-12 02:10:56 UTC
Unlike vector::assign_range which requires assignable_from<T&, ranges​::​range_reference_t<R>> is true, this means that ranges::copy is not necessarily well-formed for vector::insert_range:

#include <vector>

struct Int {
  void operator=(int) = delete;
  Int(int);
};

int main() {
  std::vector<Int> v;
  v.insert_range(v.begin(), std::vector{42});
}

https://godbolt.org/z/jo3vjjo5b
Comment 1 Jonathan Wakely 2024-11-12 10:35:08 UTC
ranges::copy performs exactly the same operations as vector::insert(p, i, j) does, which fails the same way for libstdc++ and libc++:

  std::vector<Int> v;
  std::vector<int> vi{42};
  v.insert(v.begin(), vi.begin(), vi.end());

So this seems like a pre-existing issue. Arguably, it's a standard defect. Why should be construct new elements when we already have some in the right locations?
Comment 2 Jonathan Wakely 2024-11-12 10:53:02 UTC
MSVC creates a hole in the middle of the vector, destroying the elements that were there previously, then fills the hole using uninitialized_copy.