Skip to content
Snippets Groups Projects
Unverified Commit 6e758f37 authored by Jonathan Wakely's avatar Jonathan Wakely Committed by Jonathan Wakely
Browse files

libstdc++: Handle exceptions in std::ostream::sentry destructor

Because basic_ostream::sentry::~sentry is implicitly noexcept, we can't
let any exceptions escape from it, or the program would terminate. If
the streambuf's sync() function throws, or if it returns an error and
setting badbit in the stream state throws, then the program would
terminate.

LWG 835 intended to prevent exceptions from being thrown by the
std::basic_ostream::sentry destructor, but failed to cover the case
where the streambuf's sync() member throws an exception. LWG 4188 is
needed to fix that part. In any case, LWG 835 was never implemented for
libstdc++ so this does that, as well as my proposed fix for 4188 (that
badbit should be set if pubsync() exits via an exception).

In order to avoid a second try-catch block to handle an exception that
might be thrown by setting badbit, this introduces an RAII helper class
that temporarily clears the stream's exceptions mask, then restores it
afterwards.

The try-catch block doesn't handle the forced_unwind exception
explicitly, because catching and rethrowing that would just terminate
when it reached the sentry's implicit noexcept(true) anyway.

libstdc++-v3/ChangeLog:

	* include/bits/ostream.h (basic_ostream::_Disable_exceptions):
	RAII helper type.
	(basic_ostream::sentry::~sentry): Use _Disable_exceptions. Add
	try-catch block around call to pubsync.
	* testsuite/27_io/basic_ostream/exceptions/char/lwg4188.cc: New
	test.
	* testsuite/27_io/basic_ostream/exceptions/wchar_t/lwg4188.cc:
	New test.
parent 89f007c2
No related branches found
No related tags found
No related merge requests found
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment