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

--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #8)
> (In reply to rguent...@suse.de from comment #7)
> > > 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?
> 
> Well with the case of a legacy shared lib and a new main(), currently the
> shared lib won't catch the exception but main will. It's arguably more
> broken if main doesn't catch it and terminates with an unhandled exception.
>  
> > 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)?
> 
> Bug 66145 comment 23.

Bah.  Stupid C++ for not providing a way to disambiguate ;)

Looks like it also fails silently - just not catch anything.

> > 
> > If I do
> > 
> >   catch (ios_base::failure[c++11] &e)
> 
> You can't use the ABI tag in the name like this.

Of course, it was just pseudo-code.  Apart from the above issue which
makes it a non-starter it works though.

Downstream comments in the bug already argue you're breaking the ABI :/

Now it might be (no idea!) simpler to "fix" this in the unwinder when
an object with the above multi-inheritance is thrown (just to fix the
std::exception case).  Either by being able to modify the actual
implementation of the inheritance meta-data (if such exists) to avoid
the ambiguity and just re-direct to either base or by detecting the
situation and doing that manually.

Thus, provide an "extension" that makes the following valid:

struct base {};
struct err1 : base { };
struct err2 : base { };
struct err : err1, err2 /*<somehow-specify-'base'-is-from-err1>*/ { };

void f()
{
  err e;
  base &b = e;
}

Reply via email to