Committed (r208519 on trunk and r208520 on 4.8) after approval posted in http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59392. Only the dates are changed from what I posted originally.
Thanks, Roland On Fri, Dec 6, 2013 at 3:24 PM, Roland McGrath <mcgra...@google.com> wrote: > [This patch is on the git-only branch roland/pr59392.] > > As described in http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59392, this > bug looks to have been present since 4.2 originally introduced support > for ARM EABI-based C++ exception handling. I'd like to put this fix on > trunk and 4.8, and don't personally care about older versions but the > same fix should apply to all versions still being maintained. > > The nature of the bug is quite straightforward: it's an unconditional > null pointer dereference in the code path for an unexpected throw done > inside a user-supplied handler for unexpected exceptions. I'm not > really sure if there are other ways to make it manifest. > > Mark Seaborn is responsible for identifying the fix, which mimics the > similar code for the non-EABI implementation (and copies its comment). > I filled it out with a regression test. (We're both covered by Google's > blanket copyright assignment.) > > No regressions in 'make check-c++' on arm-linux-gnueabihf. > > Ok for trunk and 4.8? > > > Thanks, > Roland > > > libstdc++-v3/ > 2013-12-06 Roland McGrath <mcgra...@google.com> > Mark Seaborn <mseab...@google.com> > > PR libstdc++/59392 > * libsupc++/eh_call.cc (__cxa_call_unexpected): Call __do_catch with > the address of a null pointer, not with a null pointer to pointer. > Copy comment for this case from > eh_personality.cc:__cxa_call_unexpected. > * testsuite/18_support/bad_exception/59392.cc: New file. > > --- a/libstdc++-v3/libsupc++/eh_call.cc > +++ b/libstdc++-v3/libsupc++/eh_call.cc > @@ -140,7 +140,11 @@ __cxa_call_unexpected(void* exc_obj_in) > &new_ptr) != ctm_failed) > __throw_exception_again; > > - if (catch_type->__do_catch(&bad_exc, 0, 1)) > + // If the exception spec allows std::bad_exception, throw that. > + // We don't have a thrown object to compare against, but since > + // bad_exception doesn't have virtual bases, that's OK; just pass > NULL. > + void* obj = NULL; > + if (catch_type->__do_catch(&bad_exc, &obj, 1)) > bad_exception_allowed = true; > } > > --- /dev/null > +++ b/libstdc++-v3/testsuite/18_support/bad_exception/59392.cc > @@ -0,0 +1,51 @@ > +// Copyright (C) 2013 Free Software Foundation, Inc. > +// > +// This file is part of the GNU ISO C++ Library. This library is free > +// software; you can redistribute it and/or modify it under the > +// terms of the GNU General Public License as published by the > +// Free Software Foundation; either version 3, or (at your option) > +// any later version. > + > +// This library is distributed in the hope that it will be useful, > +// but WITHOUT ANY WARRANTY; without even the implied warranty of > +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +// GNU General Public License for more details. > + > +// You should have received a copy of the GNU General Public License along > +// with this library; see the file COPYING3. If not see > +// <http://www.gnu.org/licenses/>. > + > +#include <exception> > +#include <cstdlib> > + > +class expected {}; > +class unexpected {}; > +class from_handler {}; > + > +static void func_with_exception_spec() throw(expected) > +{ > + throw unexpected(); > +} > + > +static void unexpected_handler() > +{ > + throw from_handler(); > +} > + > +static void terminate_handler() > +{ > + exit(0); > +} > + > +// libstdc++/59392 > +int main() > +{ > + std::set_unexpected(unexpected_handler); > + std::set_terminate(terminate_handler); > + try { > + func_with_exception_spec(); > + } catch (expected&) { > + abort(); > + } > + abort(); > +}