https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85222
--- Comment #7 from rguenther at suse dot de <rguenther at suse dot de> --- On Thu, 5 Apr 2018, redi at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85222 > > --- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> --- > (In reply to rguent...@suse.de from comment #5) > > On Thu, 5 Apr 2018, redi at gcc dot gnu.org wrote: > > > > > 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. > > > > Ok, but that would be an even more weird case of an intermediate > > old-ABI object sitting inbetween the c++11 throwing libstdc++ and > > a c++11 object. > > Which can happen with a legacy shared library trying to catch the old > ios::failure, log something, and then re-throw it. If that shared library is > used by a program where the main() function is using the new ABI and main() > tries to catch ios::failure at the top-level, it won't be able to if the > exception was replaced by another type. > > > So the old std::ios::failure doesn't fit in the new one? > > It fits, but overwriting it in place can create data races and invalidate > existing references to the original object that was overwritten. > > > As said > > above I consider the re-throwing and catching as c++11 a situation > > that shouldn't be required for fixing the "legacy" binary case. > > It's not required to fix the simple case of a legacy binary using a new > libstdc++.so but it breaks other cases. None that are not broken right now? Anyway, what would happen if __throw_ios_failure would throw a struct ios_failure : ios_base::failure, ios_base::failure[c++11] class (with both sub-classes properly initialized)? If I do catch (ios_base::failure[c++11] &e) { throw e; } does it re-throw the original exception type? Can I catch that ios_failure class at all this way?