[Bug libstdc++/31370] New: resizing bugs in std::vector
Pre-4.0, vector had a bunch of nasty error cases when resizing overflowed a size_t. Change 89377 fixed some of them. But 1) vector's copy (yuck) of the relevant functions weren't updated 2) vector's max_size is incorrect. currently it is set to the maximum size_t. but because vector's iterators aren't directly pointers, and the iterator arithmetic takes ssize_t as arguments, it can't tolerate sizes that don't fit in an ssize_t. because of the round up to the nearest word, the correct max_size is SIZE_MAX rounded down to the nearest word. 3) if doubling a vector size exceeds max_size, the code will go ahead and ask the allocator for it. It seems nicer to clamp the size to max_size, although a bad_alloc is to be expected either way. I'd mostly argue that the vector code should clamp at max_size to avoid relying on the allocator to range check properly. -- Summary: resizing bugs in std::vector Product: gcc Version: 4.1.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: gcc at severeweblint dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31370
[Bug libstdc++/31370] resizing bugs in std::vector
--- Comment #1 from gcc at severeweblint dot org 2007-03-27 04:08 --- Created an attachment (id=13292) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=13292&action=view) testcase This little program pushes some of the boundary cases. It ought to print nothing and exit cleanly. Currently it complains and crashes. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31370
[Bug libstdc++/31370] resizing bugs in std::vector
--- Comment #2 from gcc at severeweblint dot org 2007-03-27 04:20 --- Created an attachment (id=13293) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=13293&action=view) patch This patch fixes all the problems in the cheapest possible way. With it the attached testcase succeedds. It does not incorporate the testcase attachment into the gcc testsuite, although that surely ought to be done. (I got confused by the makefile for the testsuite. sorry) Note there are other approaches to fixing these bugs that might be better in the long term: 1) It is plainly bad that vector has a copy of code from vector. It is likewise poor that each has 3 places that deal in resizing, each of which needs similar defensive logic. 2) vector::iterator ought to use a 64-bit int for sizes, even in a 32-bit environment, since it could have sizes larger than the pointer limitation. But I'm not positive that that is doable. It may not be possible to match function signatures to vector as needed. The limited size may be best considered a cost of the mistake of making a bit vector a specialization of vector, instead of its own class. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31370
[Bug libstdc++/31370] resizing bugs in std::vector
--- Comment #6 from gcc at severeweblint dot org 2007-03-27 20:27 --- 4.2 doesn't fix any of the problems, but it does make the max_size issue a bit more confusing. There is a subtle relationship between vector size and pointers. Pointers can address only SIZE_MAX memory. But iterators takes ssize_t as arguments to addition and subtraction operators, so vector size should be limited to SSIZE_MAX. For sizeof(_Tp) of at least 2 bytes, there is no problem. The pointer limitation implies a size limit of SIZE_MAX / sizeof(_Tp) which is less than SSIZE_MAX. For sizeof(_Tp) of one byte, things deserve to be broken, but manage not to be. The fact that for two size_t x1 and x2, it is always true that size_t(x1+x2) == size_t(x1+ssize_t(y)) manages to rescue the situation. But for vector, things break down completely and the max_size becomes limited by SSIZE_MAX, not the pointer limitation. Worse, because of the round up to the nearest word, the max_size actually has to be SSIZE_MAX rounded DOWN to the nearest word. So allowing for the allocator to have its own size limit, the implementation of max_size has to become size_type max_size() const { const size_type __isize = SSIZE_MAX - int(_S_word_bit) + 1; const size_type __asize = _M_get_Bit_allocator().max_size(); return (__asize < __isize / size_type(_S_word_bit) ? __asize * size_type(_S_word_bit) : __isize); } Note that it probably isn't correct to assume that difference_type is a ssize_t, and therefore has maximum SSIZE_MAX, but I don't see what the correct way to ask what the maximum value representable by difference_type is. I'm fine with filling out copyright assignment paperwork, but I didn't see the form at the link you gave me. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31370
[Bug libstdc++/31777] New: GLIBCXX_FORCE_NEW doesn't always work in pool_allocator
in revision 83355 of libstdc++-v3/include/ext/pool_allocator.h the efficient thread support code for GLIBCXX_FORCE_NEW was broken by changing the test (_S_force_new>0) to (_S_force_new==1). now there is a race condition. -- Summary: GLIBCXX_FORCE_NEW doesn't always work in pool_allocator Product: gcc Version: 3.4.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: gcc at severeweblint dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31777