https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85222

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #3)
> Do you know of any other exception type affected by the c++11 vs. old ABI
> issue or does the entire I/O hierarchy only ever throw exactly
> ios_base::failure?

That's the only one.

> So a workaround would be to marshal these somehow in the C++ EH personality
> routine?  The c++11 variant seems to be a superset feature-wise (apart from
> the changed inheritance), so constructing (in-place?!) the c++98 variant
> once we hit a filter for c++98 ios_base::failure with an EH object of
> type ios_base::failure[c++11] would "work"?

Until you try to rethrow it and catch it as the new type again.

This approach was considered, and deemed not worth the complexity (and
additional performance hit that would affect every 'catch' in every program
that has to check if the catch handler is for ios::failure).

It would be possible to make __throw_ios_failure() throw:

struct enhanced_failure : std::ios::failure {
  unsigned char buf[sizeof old ios::failure];
};

This can be caught as the new type, and when there's an attempt to catch it as
the old type, construct it in the buffer and catch the object in the buffer.
Constructing it lazily can introduce a race condition, so it might be better to
always pre-propulate the buffer, just in case anybody wants to catch the old
type.

Reply via email to