public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/56166] New: std::string::clear() can allocate memory despite being marked noexcept
@ 2013-01-31 18:20 zackw at panix dot com
2013-01-31 18:22 ` [Bug libstdc++/56166] std::string::clear() can throw " zackw at panix dot com
` (12 more replies)
0 siblings, 13 replies; 14+ messages in thread
From: zackw at panix dot com @ 2013-01-31 18:20 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56166
Bug #: 56166
Summary: std::string::clear() can allocate memory despite being
marked noexcept
Classification: Unclassified
Product: gcc
Version: 4.7.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: zackw@panix.com
The attached test case (which is regrettably large, but I haven't found a
shorter way to trigger the problem) will call terminate() when compiled with
-std=c++11, despite there being no point at which an exception should escape
main(). The problem is deep inside std::basic_string:
/usr/include/c++/4.7/bits/basic_string.h
796 /**
797 * Erases the string, making it empty.
798 */
799 void
800 clear() _GLIBCXX_NOEXCEPT
801 { _M_mutate(0, this->size(), 0); }
_M_mutate can allocate memory even when it's being asked to erase the string
(presumably due to internal reference-counting -- if you take 's2' out of the
test case the crash goes away), and thus can throw bad_alloc. In C++11 mode,
clear() is marked 'noexcept', so we wind up in terminate().
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/56166] std::string::clear() can throw despite being marked noexcept
2013-01-31 18:20 [Bug libstdc++/56166] New: std::string::clear() can allocate memory despite being marked noexcept zackw at panix dot com
@ 2013-01-31 18:22 ` zackw at panix dot com
2013-01-31 19:25 ` redi at gcc dot gnu.org
` (11 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: zackw at panix dot com @ 2013-01-31 18:22 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56166
--- Comment #1 from Zack Weinberg <zackw at panix dot com> 2013-01-31 18:21:49 UTC ---
Created attachment 29320
--> http://gcc.gnu.org/bugzilla/attachment.cgi?id=29320
test case
In case you're wondering, this was an attempt to do at least *some* testing of
a library's robustness in the face of memory allocation failure.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/56166] std::string::clear() can throw despite being marked noexcept
2013-01-31 18:20 [Bug libstdc++/56166] New: std::string::clear() can allocate memory despite being marked noexcept zackw at panix dot com
2013-01-31 18:22 ` [Bug libstdc++/56166] std::string::clear() can throw " zackw at panix dot com
@ 2013-01-31 19:25 ` redi at gcc dot gnu.org
2013-01-31 22:24 ` paolo.carlini at oracle dot com
` (10 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2013-01-31 19:25 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56166
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Last reconfirmed| |2013-01-31
Ever Confirmed|0 |1
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> 2013-01-31 19:25:27 UTC ---
(In reply to comment #0)
> _M_mutate can allocate memory even when it's being asked to erase the string
> (presumably due to internal reference-counting
If another string shares the same representation then you can't just modify the
representation, you need to create your own clone first, *then* clear it.
For the default configuration we could just point to the shared empty rep, I
wonder why we don't do that. For the _GLIBCXX_FULLY_DYNAMIC_STRING case we
should probably remove noexcept
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/56166] std::string::clear() can throw despite being marked noexcept
2013-01-31 18:20 [Bug libstdc++/56166] New: std::string::clear() can allocate memory despite being marked noexcept zackw at panix dot com
2013-01-31 18:22 ` [Bug libstdc++/56166] std::string::clear() can throw " zackw at panix dot com
2013-01-31 19:25 ` redi at gcc dot gnu.org
@ 2013-01-31 22:24 ` paolo.carlini at oracle dot com
2013-02-01 0:49 ` zackw at panix dot com
` (9 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: paolo.carlini at oracle dot com @ 2013-01-31 22:24 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56166
--- Comment #3 from Paolo Carlini <paolo.carlini at oracle dot com> 2013-01-31 22:24:21 UTC ---
I suppose ext/vstring is already fine. As regards the current
std::basic_string, if Jon has a quick fix, great, but I suggest not spending
much time on it.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/56166] std::string::clear() can throw despite being marked noexcept
2013-01-31 18:20 [Bug libstdc++/56166] New: std::string::clear() can allocate memory despite being marked noexcept zackw at panix dot com
` (2 preceding siblings ...)
2013-01-31 22:24 ` paolo.carlini at oracle dot com
@ 2013-02-01 0:49 ` zackw at panix dot com
2013-02-01 8:42 ` paolo.carlini at oracle dot com
` (8 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: zackw at panix dot com @ 2013-02-01 0:49 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56166
--- Comment #4 from Zack Weinberg <zackw at panix dot com> 2013-02-01 00:48:43 UTC ---
Is vstring going to be promoted to std::string in the *near* future? it doesn't
seem done to me, eg there is no stringstream for it, and it appears to generate
bulkier code. (not scientifically benchmarked)
that said, it doesn't fail this test case, but I haven't checked how its
clear() works, so I'm not sure it has no bug here.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/56166] std::string::clear() can throw despite being marked noexcept
2013-01-31 18:20 [Bug libstdc++/56166] New: std::string::clear() can allocate memory despite being marked noexcept zackw at panix dot com
` (3 preceding siblings ...)
2013-02-01 0:49 ` zackw at panix dot com
@ 2013-02-01 8:42 ` paolo.carlini at oracle dot com
2013-02-01 11:26 ` redi at gcc dot gnu.org
` (7 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: paolo.carlini at oracle dot com @ 2013-02-01 8:42 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56166
--- Comment #5 from Paolo Carlini <paolo.carlini at oracle dot com> 2013-02-01 08:41:59 UTC ---
4.9, yes. Of course wrt the C++11 requirements the current implementation is
non conforming for many other reasons (reference counting is out ruled) + there
are long standing bugs (in partixular alignment related and related to the
shared zero rep for some targets). It goes without saying that when ext/vstring
is promoted it also gets automatically all the iostream overloads, etc, and
further improvements are definitely welcome.
That said, for sure I don't mean to unconditionally oppose fixes to the current
implementation, eh Jon's idea seems fine to me in principle, if only he could
prototype it, would be great, my point was that it doesn't seem to make much
sense doing a *lot* of that *now*.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/56166] std::string::clear() can throw despite being marked noexcept
2013-01-31 18:20 [Bug libstdc++/56166] New: std::string::clear() can allocate memory despite being marked noexcept zackw at panix dot com
` (4 preceding siblings ...)
2013-02-01 8:42 ` paolo.carlini at oracle dot com
@ 2013-02-01 11:26 ` redi at gcc dot gnu.org
2013-07-15 19:38 ` fasdfasdas at gmail dot com
` (6 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2013-02-01 11:26 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56166
--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> 2013-02-01 11:25:33 UTC ---
(In reply to comment #5)
> That said, for sure I don't mean to unconditionally oppose fixes to the current
> implementation, eh Jon's idea seems fine to me in principle, if only he could
> prototype it, would be great, my point was that it doesn't seem to make much
> sense doing a *lot* of that *now*.
Yeah I can take a quick look at that over the weekend
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/56166] std::string::clear() can throw despite being marked noexcept
2013-01-31 18:20 [Bug libstdc++/56166] New: std::string::clear() can allocate memory despite being marked noexcept zackw at panix dot com
` (5 preceding siblings ...)
2013-02-01 11:26 ` redi at gcc dot gnu.org
@ 2013-07-15 19:38 ` fasdfasdas at gmail dot com
2013-07-15 19:47 ` fasdfasdas at gmail dot com
` (5 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: fasdfasdas at gmail dot com @ 2013-07-15 19:38 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56166
Tolga <fasdfasdas at gmail dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |fasdfasdas at gmail dot com
--- Comment #7 from Tolga <fasdfasdas at gmail dot com> ---
I can confirm this on g++ 4.8.1.
I think I can also confirm that it is about reference counting, thanks to this
report, I was able to work around it though.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/56166] std::string::clear() can throw despite being marked noexcept
2013-01-31 18:20 [Bug libstdc++/56166] New: std::string::clear() can allocate memory despite being marked noexcept zackw at panix dot com
` (6 preceding siblings ...)
2013-07-15 19:38 ` fasdfasdas at gmail dot com
@ 2013-07-15 19:47 ` fasdfasdas at gmail dot com
2013-07-15 20:51 ` fasdfasdas at gmail dot com
` (4 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: fasdfasdas at gmail dot com @ 2013-07-15 19:47 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56166
--- Comment #8 from Tolga <fasdfasdas at gmail dot com> ---
Correction, removing the copy, therefore reference counting effect, feels like
has decreased the error but I found out std::string::clear() still throws
std::length_error, although I use no reference.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/56166] std::string::clear() can throw despite being marked noexcept
2013-01-31 18:20 [Bug libstdc++/56166] New: std::string::clear() can allocate memory despite being marked noexcept zackw at panix dot com
` (7 preceding siblings ...)
2013-07-15 19:47 ` fasdfasdas at gmail dot com
@ 2013-07-15 20:51 ` fasdfasdas at gmail dot com
2013-09-20 15:50 ` glisse at gcc dot gnu.org
` (3 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: fasdfasdas at gmail dot com @ 2013-07-15 20:51 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56166
--- Comment #9 from Tolga <fasdfasdas at gmail dot com> ---
It was a bug in my code that called clear from one thread while other inserts
something.
Yet, it throws.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/56166] std::string::clear() can throw despite being marked noexcept
2013-01-31 18:20 [Bug libstdc++/56166] New: std::string::clear() can allocate memory despite being marked noexcept zackw at panix dot com
` (8 preceding siblings ...)
2013-07-15 20:51 ` fasdfasdas at gmail dot com
@ 2013-09-20 15:50 ` glisse at gcc dot gnu.org
2013-09-24 10:07 ` glisse at gcc dot gnu.org
` (2 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: glisse at gcc dot gnu.org @ 2013-09-20 15:50 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56166
--- Comment #10 from Marc Glisse <glisse at gcc dot gnu.org> ---
Author: glisse
Date: Fri Sep 20 15:50:09 2013
New Revision: 202781
URL: http://gcc.gnu.org/viewcvs?rev=202781&root=gcc&view=rev
Log:
2013-09-20 Marc Glisse <marc.glisse@inria.fr>
PR libstdc++/58338
* include/bits/allocator.h (__alloc_swap::_S_do_it,
__shrink_to_fit_aux::_S_do_it): Mark as noexcept.
* include/bits/basic_string.h (basic_string::_Rep) [_S_empty_rep,
_M_is_leaked, _M_is_shared, _M_set_leaked, _M_set_sharable,
_M_set_length_and_sharable, _M_dispose]: Likewise.
(basic_string::_Alloc_hider::_Alloc_hider): Likewise.
(basic_string) [_M_data, _M_rep, _M_ibegin, _M_iend, _M_limit,
_M_disjunct, _M_copy, _M_move, _M_assign, _S_copy_chars, _S_compare,
_S_empty_rep, shrink_to_fit, operator[] const, front const, back const]:
Likewise.
[clear]: Link to PR 56166.
[swap]: Link to PR 58265.
* include/bits/stl_deque.h (_Deque_iterator) [_S_buffer_size,
_Deque_iterator, _M_const_cast, operator*, operator->, operator++,
operator--, operator+=, operator+, operator-=, operator-, operator[],
_M_set_node]: Mark as noexcept.
(operator==(const _Deque_iterator&, const _Deque_iterator&),
operator!=(const _Deque_iterator&, const _Deque_iterator&),
operator<(const _Deque_iterator&, const _Deque_iterator&),
operator>(const _Deque_iterator&, const _Deque_iterator&),
operator<=(const _Deque_iterator&, const _Deque_iterator&),
operator>=(const _Deque_iterator&, const _Deque_iterator&),
operator-(const _Deque_iterator&, const _Deque_iterator&),
operator+(ptrdiff_t, const _Deque_iterator&)): Likewise.
(_Deque_base) [_Deque_base(const allocator_type&)]: Add missing call to
_M_initialize_map.
[~_Deque_base, _M_deallocate_node, _M_deallocate_map, _M_destroy_nodes]:
Mark as noexcept.
(_Deque_base::_Deque_impl) [_Deque_impl(const _Tp_alloc_type&),
_Deque_impl(_Tp_alloc_type&&)]: Likewise.
(deque) [_S_buffer_size, operator=(deque&&), shrink_to_fit, operator[],
front, back, pop_front, pop_back, swap]: Likewise.
[deque(), deque(const allocator_type&)]: Merge.
* include/debug/deque (deque) [operator=(deque&&), shrink_to_fit,
operator[], front, back, pop_front, pop_back, swap]: Mark as noexcept.
* include/profile/deque (deque) [operator=(deque&&), operator[], front,
back, pop_front, pop_back, swap]: Likewise.
* testsuite/23_containers/deque/requirements/dr438/assign_neg.cc:
Adjust line number.
* testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc:
Likewise.
* testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc:
Likewise.
* testsuite/23_containers/deque/requirements/dr438/insert_neg.cc:
Likewise.
Modified:
trunk/libstdc++-v3/ChangeLog
trunk/libstdc++-v3/include/bits/allocator.h
trunk/libstdc++-v3/include/bits/basic_string.h
trunk/libstdc++-v3/include/bits/stl_deque.h
trunk/libstdc++-v3/include/debug/deque
trunk/libstdc++-v3/include/profile/deque
trunk/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
trunk/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
trunk/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
trunk/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/56166] std::string::clear() can throw despite being marked noexcept
2013-01-31 18:20 [Bug libstdc++/56166] New: std::string::clear() can allocate memory despite being marked noexcept zackw at panix dot com
` (9 preceding siblings ...)
2013-09-20 15:50 ` glisse at gcc dot gnu.org
@ 2013-09-24 10:07 ` glisse at gcc dot gnu.org
2014-06-03 22:24 ` redi at gcc dot gnu.org
2015-01-18 17:37 ` redi at gcc dot gnu.org
12 siblings, 0 replies; 14+ messages in thread
From: glisse at gcc dot gnu.org @ 2013-09-24 10:07 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56166
--- Comment #11 from Marc Glisse <glisse at gcc dot gnu.org> ---
Author: glisse
Date: Tue Sep 24 10:07:32 2013
New Revision: 202861
URL: http://gcc.gnu.org/viewcvs?rev=202861&root=gcc&view=rev
Log:
2013-09-24 Marc Glisse <marc.glisse@inria.fr>
PR libstdc++/58338
PR libstdc++/56166
* include/bits/basic_string.h (basic_string)
[basic_string(basic_string&&)]: Make the noexcept conditional.
[operator=(basic_string&&), assign(basic_string&&)]: Link to PR 58265.
[begin(), end(), rbegin(), rend(), clear]: Remove noexcept.
[pop_back]: Comment on the lack of noexcept.
* include/debug/string (basic_string) [basic_string(const _Allocator&),
basic_string(basic_string&&), begin(), end(), rbegin(), rend(), clear,
operator[](size_type), pop_back]: Comment out noexcept, until vstring
replaces basic_string.
Modified:
trunk/libstdc++-v3/ChangeLog
trunk/libstdc++-v3/include/bits/basic_string.h
trunk/libstdc++-v3/include/debug/string
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/56166] std::string::clear() can throw despite being marked noexcept
2013-01-31 18:20 [Bug libstdc++/56166] New: std::string::clear() can allocate memory despite being marked noexcept zackw at panix dot com
` (10 preceding siblings ...)
2013-09-24 10:07 ` glisse at gcc dot gnu.org
@ 2014-06-03 22:24 ` redi at gcc dot gnu.org
2015-01-18 17:37 ` redi at gcc dot gnu.org
12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2014-06-03 22:24 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56166
--- Comment #12 from Jonathan Wakely <redi at gcc dot gnu.org> ---
I think __gnu_cxx::__rc_string has the same problem
There's a patch at https://gcc.gnu.org/ml/gcc-patches/2014-06/msg00278.html
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/56166] std::string::clear() can throw despite being marked noexcept
2013-01-31 18:20 [Bug libstdc++/56166] New: std::string::clear() can allocate memory despite being marked noexcept zackw at panix dot com
` (11 preceding siblings ...)
2014-06-03 22:24 ` redi at gcc dot gnu.org
@ 2015-01-18 17:37 ` redi at gcc dot gnu.org
12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2015-01-18 17:37 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56166
--- Comment #13 from Jonathan Wakely <redi at gcc dot gnu.org> ---
N.B. this is fixed when using the new std::__cxx11::basic_string in GCC 5
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2015-01-18 17:37 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-31 18:20 [Bug libstdc++/56166] New: std::string::clear() can allocate memory despite being marked noexcept zackw at panix dot com
2013-01-31 18:22 ` [Bug libstdc++/56166] std::string::clear() can throw " zackw at panix dot com
2013-01-31 19:25 ` redi at gcc dot gnu.org
2013-01-31 22:24 ` paolo.carlini at oracle dot com
2013-02-01 0:49 ` zackw at panix dot com
2013-02-01 8:42 ` paolo.carlini at oracle dot com
2013-02-01 11:26 ` redi at gcc dot gnu.org
2013-07-15 19:38 ` fasdfasdas at gmail dot com
2013-07-15 19:47 ` fasdfasdas at gmail dot com
2013-07-15 20:51 ` fasdfasdas at gmail dot com
2013-09-20 15:50 ` glisse at gcc dot gnu.org
2013-09-24 10:07 ` glisse at gcc dot gnu.org
2014-06-03 22:24 ` redi at gcc dot gnu.org
2015-01-18 17:37 ` redi at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).