Re: std::rethrow_exception is broken

2014-03-31 Thread Rainer Orth
Jonathan Wakely jwak...@redhat.com writes:

 On 25/03/14 17:25 +, Jonathan Wakely wrote:
Tested x86_64-linux, I plan to commit this to trunk soon.


commit 06a845f80204947afd6866109db58cc85dc87117
Author: Jonathan Wakely jwak...@redhat.com
Date:   Tue Mar 25 14:42:45 2014 +

  PR libstdc++/60612
  * libsupc++/eh_ptr.cc: Assert __cxa_dependent_exception layout is
  compatible with __cxa_exception.
  * libsupc++/unwind-cxx.h (__cxa_dependent_exception): Add padding.
  Fix typos in comments.
  * testsuite/18_support/exception_ptr/60612-terminate.cc: New.
  * testsuite/18_support/exception_ptr/60612-unexpected.cc: New.

 Committed to trunk.

Unfortunately, the new tests FAIL on non-C99 targets (i386-pc-solaris2.9
in my case):

FAIL: 18_support/exception_ptr/60612-terminate.cc (test for excess errors)
Excess errors:
/vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/18_support/exception_ptr/6061
2-terminate.cc:26:27: error: '_Exit' was not declared in this scope

WARNING: 18_support/exception_ptr/60612-terminate.cc compilation failed to produ
ce executable

The following patch fixes this, following the idiom often used in the
libstdc++ testsuite.

Tested with the appropriate runtest invocation on
i386-pc-solaris2.{9,11}.  Ok for mainline?

When looking into this, I noticed that this idiom is very widespread in
the v3 testsuite, but IMNSHO a *very bad* idea since it hides the fact
that many tests are acutually UNSUPPORTED, but appear to PASS, while the
only thing that passes is an empty main.  I had something similar
recently when all C99 functionality in libstdc++ got disabled, but
testsuite results barely changed.

Unless someone strongly objects, I expect to change those tests to use
corresponding dg-require-* keywords to make mark them appropriately once
4.9 branches.

Rainer


2014-03-31  Rainer Orth  r...@cebitec.uni-bielefeld.de

* testsuite/18_support/exception_ptr/60612-terminate.cc
(terminate, f): Wrap in _GLIBCXX_USE_C99.
* testsuite/18_support/exception_ptr/60612-unexpected.cc: Likewise.

# HG changeset patch
# Parent 23f930c5334d34dff20abb2647f50b4a095481e4
Fix 18_support/exception_ptr/60612-*.cc on non-C99 targets

diff --git a/libstdc++-v3/testsuite/18_support/exception_ptr/60612-terminate.cc b/libstdc++-v3/testsuite/18_support/exception_ptr/60612-terminate.cc
--- a/libstdc++-v3/testsuite/18_support/exception_ptr/60612-terminate.cc
+++ b/libstdc++-v3/testsuite/18_support/exception_ptr/60612-terminate.cc
@@ -23,6 +23,7 @@
 #include exception
 #include stdlib.h
 
+#ifdef _GLIBCXX_USE_C99
 void terminate() { _Exit(0); }
 
 void f() noexcept
@@ -34,8 +35,12 @@ void f() noexcept
 std::rethrow_exception(std::current_exception());
   }
 }
+#endif
 
 int main()
 {
+#ifdef _GLIBCXX_USE_C99
   f();
+#endif
+  return 0;
 }
diff --git a/libstdc++-v3/testsuite/18_support/exception_ptr/60612-unexpected.cc b/libstdc++-v3/testsuite/18_support/exception_ptr/60612-unexpected.cc
--- a/libstdc++-v3/testsuite/18_support/exception_ptr/60612-unexpected.cc
+++ b/libstdc++-v3/testsuite/18_support/exception_ptr/60612-unexpected.cc
@@ -23,6 +23,7 @@
 #include exception
 #include stdlib.h
 
+#ifdef _GLIBCXX_USE_C99
 void unexpected() { _Exit(0); }
 
 void f() throw()
@@ -34,8 +35,11 @@ void f() throw()
 std::rethrow_exception(std::current_exception());
   }
 }
+#endif
 
 int main()
 {
+#ifdef _GLIBCXX_USE_C99
   f();
+#endif
 }

-- 
-
Rainer Orth, Center for Biotechnology, Bielefeld University


Re: std::rethrow_exception is broken

2014-03-31 Thread Jonathan Wakely

On 31/03/14 14:13 +0200, Rainer Orth wrote:


Unfortunately, the new tests FAIL on non-C99 targets (i386-pc-solaris2.9
in my case):

FAIL: 18_support/exception_ptr/60612-terminate.cc (test for excess errors)
Excess errors:
/vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/18_support/exception_ptr/6061
2-terminate.cc:26:27: error: '_Exit' was not declared in this scope

WARNING: 18_support/exception_ptr/60612-terminate.cc compilation failed to produ
ce executable


Sorry about that.
Does Solaris 9 not support C99 at all, or does it only define _Exit
when __STDC_VERSION__ has the right value?


The following patch fixes this, following the idiom often used in the
libstdc++ testsuite.

Tested with the appropriate runtest invocation on
i386-pc-solaris2.{9,11}.  Ok for mainline?


The patch is OK, thanks.


When looking into this, I noticed that this idiom is very widespread in
the v3 testsuite, but IMNSHO a *very bad* idea since it hides the fact
that many tests are acutually UNSUPPORTED, but appear to PASS, while the
only thing that passes is an empty main.  I had something similar
recently when all C99 functionality in libstdc++ got disabled, but
testsuite results barely changed.


I completely agree it's a bad idea.


Unless someone strongly objects, I expect to change those tests to use
corresponding dg-require-* keywords to make mark them appropriately once
4.9 branches.


I certainly don't object, but you should be aware that once we're in
stage 1 I want to review all our uses of _GLIBCXX_USE_C99 and replace
it with more fine-grained checks. We should at least have separate
macros for:

* we can use the C99 library in C++11 mode
(true for a modern libc that checks for __cplusplus = 201103L)

* we can use the C99 library in C++98 mode
(true for glibc, because we define _GNU_SOURCE)


Re: std::rethrow_exception is broken

2014-03-31 Thread Rainer Orth
Hi Jonathan,

 On 31/03/14 14:13 +0200, Rainer Orth wrote:

Unfortunately, the new tests FAIL on non-C99 targets (i386-pc-solaris2.9
in my case):

FAIL: 18_support/exception_ptr/60612-terminate.cc (test for excess errors)
Excess errors:
/vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/18_support/exception_ptr/6061
2-terminate.cc:26:27: error: '_Exit' was not declared in this scope

WARNING: 18_support/exception_ptr/60612-terminate.cc compilation failed to
 produ
ce executable

 Sorry about that.
 Does Solaris 9 not support C99 at all, or does it only define _Exit
 when __STDC_VERSION__ has the right value?

no C99 support at all.  That only appeared in Solaris 10.

When looking into this, I noticed that this idiom is very widespread in
the v3 testsuite, but IMNSHO a *very bad* idea since it hides the fact
that many tests are acutually UNSUPPORTED, but appear to PASS, while the
only thing that passes is an empty main.  I had something similar
recently when all C99 functionality in libstdc++ got disabled, but
testsuite results barely changed.

 I completely agree it's a bad idea.

Unless someone strongly objects, I expect to change those tests to use
corresponding dg-require-* keywords to make mark them appropriately once
4.9 branches.

 I certainly don't object, but you should be aware that once we're in
 stage 1 I want to review all our uses of _GLIBCXX_USE_C99 and replace
 it with more fine-grained checks. We should at least have separate
 macros for:

 * we can use the C99 library in C++11 mode
 (true for a modern libc that checks for __cplusplus = 201103L)

 * we can use the C99 library in C++98 mode
 (true for glibc, because we define _GNU_SOURCE)

Good to know, thanks for the heads-up.

Rainer

-- 
-
Rainer Orth, Center for Biotechnology, Bielefeld University


Re: std::rethrow_exception is broken

2014-03-31 Thread Jonathan Wakely

On 29/03/14 19:55 +0100, Daniel Krügler wrote:

2014-03-28 13:37 GMT+01:00 Jonathan Wakely jwak...@redhat.com:

On 27/03/14 23:00 +0100, Daniel Krügler wrote:

I'm in favour for changing it, what about something like

layout mismatch

?

How about this?

__cxa_dependent_exception::termHandler layout must be consistent with

__cxa_exception::termHandler

Yes, this seems even better to me.


This improves the static assertion messages, as suggested by François
and Daniel.

Tested x86_64-linux, committed to trunk.

commit f92ce7260937614a7897d9890c022812794f793b
Author: Jonathan Wakely jwak...@redhat.com
Date:   Wed Mar 12 21:36:53 2014 +

2014-03-12  Lars Gullik Bj??nnes  lar...@gullik.org
Jonathan Wakely  jwak...@redhat.com

PR libstdc++/60270
* include/std/iomanip (_Quoted_string operator): Do not clear
string if input is not quoted.
* testsuite/27_io/manipulators/standard/char/60270.cc: New.

diff --git a/libstdc++-v3/include/std/iomanip b/libstdc++-v3/include/std/iomanip
index b2c7b95..73822db 100644
--- a/libstdc++-v3/include/std/iomanip
+++ b/libstdc++-v3/include/std/iomanip
@@ -415,8 +415,6 @@ _GLIBCXX_END_NAMESPACE_VERSION
 const _Quoted_stringbasic_string_CharT, _Traits, _Alloc,
  _CharT __str)
   {
-   __str._M_string.clear();
-
_CharT __c;
__is  __c;
if (!__is.good())
@@ -427,6 +425,7 @@ _GLIBCXX_END_NAMESPACE_VERSION
__is  __str._M_string;
return __is;
  }
+   __str._M_string.clear();
std::ios_base::fmtflags __flags
  = __is.flags(__is.flags()  ~std::ios_base::skipws);
do
diff --git a/libstdc++-v3/testsuite/27_io/manipulators/standard/char/60270.cc 
b/libstdc++-v3/testsuite/27_io/manipulators/standard/char/60270.cc
new file mode 100644
index 000..b2b213b
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/manipulators/standard/char/60270.cc
@@ -0,0 +1,38 @@
+// { dg-do run }
+// { dg-options -std=gnu++14 }
+
+// Copyright (C) 2014 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/.
+
+// 27.7.6 - Quoted manipulators[quoted.manip]
+
+// libstdc++/60270
+
+#include string
+#include sstream
+#include iomanip
+#include testsuite_hooks.h
+
+int main()
+{
+  std::istringstream in;
+  std::string s = xxx;
+  in  s;
+  VERIFY( !s.empty() );
+  in  std::quoted(s);
+  VERIFY( !s.empty() );
+}

commit aeebd7a5d8e91d309070757e9732127e28527512
Author: redi redi@138bc75d-0d04-0410-961f-82ee72b054a4
Date:   Mon Mar 31 18:16:14 2014 +

* libsupc++/eh_ptr.cc: Improve static_assert messages.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@208965 
138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/libstdc++-v3/libsupc++/eh_ptr.cc b/libstdc++-v3/libsupc++/eh_ptr.cc
index 8c25a81..f974309 100644
--- a/libstdc++-v3/libsupc++/eh_ptr.cc
+++ b/libstdc++-v3/libsupc++/eh_ptr.cc
@@ -48,7 +48,8 @@ templatetypename Ex
 
 static_assert( termHandler__cxa_exception()
   == termHandler__cxa_dependent_exception(),
-  __cxa_dependent_exception::termHandler layout is correct );
+  __cxa_dependent_exception::termHandler layout must be
+   consistent with __cxa_exception::termHandler );
 
 #ifndef __ARM_EABI_UNWINDER__
 templatetypename Ex
@@ -57,7 +58,8 @@ templatetypename Ex
 
 static_assert( adjptr__cxa_exception()
   == adjptr__cxa_dependent_exception(),
-  __cxa_dependent_exception::adjustedPtr layout is correct );
+  __cxa_dependent_exception::adjustedPtr layout must be
+   consistent with __cxa_exception::adjustedPtr );
 #endif
 }
 


Re: std::rethrow_exception is broken

2014-03-31 Thread Jonathan Wakely

On 31/03/14 19:17 +0100, Jonathan Wakely wrote:

This improves the static assertion messages, as suggested by François
and Daniel.

Tested x86_64-linux, committed to trunk.


Oops, apparently mutt doesn't attach attachments until you actually
send the mail, by which time the file I was attaching had changed!

*This* improves the static assertion messages, not the last patch.

commit 0aedd873a6ccc367bac38e1edc347f1774310ebe
Author: Jonathan Wakely jwak...@redhat.com
Date:   Mon Mar 31 17:51:43 2014 +0100

* libsupc++/eh_ptr.cc: Improve static_assert messages.

diff --git a/libstdc++-v3/libsupc++/eh_ptr.cc b/libstdc++-v3/libsupc++/eh_ptr.cc
index 8c25a81..f974309 100644
--- a/libstdc++-v3/libsupc++/eh_ptr.cc
+++ b/libstdc++-v3/libsupc++/eh_ptr.cc
@@ -48,7 +48,8 @@ templatetypename Ex
 
 static_assert( termHandler__cxa_exception()
   == termHandler__cxa_dependent_exception(),
-  __cxa_dependent_exception::termHandler layout is correct );
+  __cxa_dependent_exception::termHandler layout must be
+   consistent with __cxa_exception::termHandler );
 
 #ifndef __ARM_EABI_UNWINDER__
 templatetypename Ex
@@ -57,7 +58,8 @@ templatetypename Ex
 
 static_assert( adjptr__cxa_exception()
   == adjptr__cxa_dependent_exception(),
-  __cxa_dependent_exception::adjustedPtr layout is correct );
+  __cxa_dependent_exception::adjustedPtr layout must be
+   consistent with __cxa_exception::adjustedPtr );
 #endif
 }
 


Re: std::rethrow_exception is broken

2014-03-27 Thread Jonathan Wakely

On 25/03/14 17:25 +, Jonathan Wakely wrote:

Tested x86_64-linux, I plan to commit this to trunk soon.




commit 06a845f80204947afd6866109db58cc85dc87117
Author: Jonathan Wakely jwak...@redhat.com
Date:   Tue Mar 25 14:42:45 2014 +

PR libstdc++/60612
* libsupc++/eh_ptr.cc: Assert __cxa_dependent_exception layout is
compatible with __cxa_exception.
* libsupc++/unwind-cxx.h (__cxa_dependent_exception): Add padding.
Fix typos in comments.
* testsuite/18_support/exception_ptr/60612-terminate.cc: New.
* testsuite/18_support/exception_ptr/60612-unexpected.cc: New.


Committed to trunk.



Re: std::rethrow_exception is broken

2014-03-25 Thread Jonathan Wakely

On 24/03/14 19:19 +, Jonathan Wakely wrote:

There is a lot of code in libsupc++/eh_* that relies on
__cxa_exception and __cxa_dependent_exception having similar layouts,
so tricks like this work:

static inline void*
__gxx_caught_object(_Unwind_Exception* eo)
{
 // Bad as it looks, this actually works for dependent exceptions too.
 __cxa_exception* header = __get_exception_header_from_ue (eo);
 return header-adjustedPtr;
}

The idea is that although the eo might be a pointer to the
unwindHeader member  of either __cxa_exception or
__cxa_dependent_exception, the adjustedPtr member will be always be at
the same location relative to the unwindHeader member, so it Just
Works.

Except it doesn't.

offsetof(__cxa_exception, unwindHeader) == 80
offsetof(__cxa_dependent_exception, unwindHeader) == 80
offsetof(__cxa_exception, adjustedPtr) == 72
offsetof(__cxa_dependent_exception, adjustedPtr) == 64


Here's the output of GDB's pahole on __cxa_exception

(gdb) pahole struct __cxxabiv1::__cxa_exception
   struct __cxxabiv1::__cxa_exception {
 /*   0   8 */std::type_info * exceptionType
 /*   8   8 */void (*)(void *) exceptionDestructor
 /*  16   8 */void (*)(void) unexpectedHandler
 /*  24   8 */void (*)(void) terminateHandler
 /*  32   8 */__cxxabiv1::__cxa_exception * nextException
 /*  40   4 */int handlerCount
 /*  44   4 */int handlerSwitchValue
 /*  48   8 */const unsigned char * actionRecord
 /*  56   8 */const unsigned char * languageSpecificData
 /*  64   8 */unsigned long catchTemp
 /*  72   8 */void * adjustedPtr
 /*  80  32 */   struct _Unwind_Exception {
 /*   0   8 */  unsigned long exception_class
 /*   8   8 */  void (*)(_Unwind_Reason_Code, _Unwind_Exception *) 
exception_cleanup
 /*  16   8 */  unsigned long private_1
 /*  24   8 */  unsigned long private_2
 } unwindHeader
   } 
 
And here's the current definition of __cxa_dependent_exception:


(gdb) pahole struct __cxxabiv1::__cxa_dependent_exception 
   struct __cxxabiv1::__cxa_dependent_exception {

 /*   0   8 */void * primaryException
 /*   8   8 */void (*)(void) unexpectedHandler
 /*  16   8 */void (*)(void) terminateHandler
 /*  24   8 */__cxxabiv1::__cxa_exception * nextException
 /*  32   4 */int handlerCount
 /*  36   4 */int handlerSwitchValue
 /*  40   8 */const unsigned char * actionRecord
 /*  48   8 */const unsigned char * languageSpecificData
 /*  56   8 */unsigned long catchTemp
 /*  64   8 */void * adjustedPtr
  /* XXX 64 bit hole, try to pack */
 /*  80  32 */   struct _Unwind_Exception {
 /*   0   8 */  unsigned long exception_class
 /*   8   8 */  void (*)(_Unwind_Reason_Code, _Unwind_Exception *) 
exception_cleanup
 /*  16   8 */  unsigned long private_1
 /*  24   8 */  unsigned long private_2
 } unwindHeader
   } 


Notice the hole right before the unwindHeader member which is not
there in __cxa_exception. All the member which are supposed to be at
the same offsets as in __cxa_exception are 8 bytes earlier.

The attached patch adds a __padding member near the start so changes
that to:

(gdb) pahole struct __cxxabiv1::__cxa_dependent_exception 
   struct __cxxabiv1::__cxa_dependent_exception {

 /*   0   8 */void * primaryException
 /*   8   8 */void (*)(void *) __padding
 /*  16   8 */void (*)(void) unexpectedHandler
 /*  24   8 */void (*)(void) terminateHandler
 /*  32   8 */__cxxabiv1::__cxa_exception * nextException
 /*  40   4 */int handlerCount
 /*  44   4 */int handlerSwitchValue
 /*  48   8 */const unsigned char * actionRecord
 /*  56   8 */const unsigned char * languageSpecificData
 /*  64   8 */unsigned long catchTemp
 /*  72   8 */void * adjustedPtr
 /*  80  32 */   struct _Unwind_Exception {
 /*   0   8 */  unsigned long exception_class
 /*   8   8 */  void (*)(_Unwind_Reason_Code, _Unwind_Exception *) 
exception_cleanup
 /*  16   8 */  unsigned long private_1
 /*  24   8 */  unsigned long private_2
 } unwindHeader
   } 


That change allows all the pointer tricks in libsupc++/eh_*.cc to
continue working.  It's a change to the layout of a low-level type,
which is not visible to users linking to libsupc++.so, but anyone
linking statically will not be able to mix code using GCC 4.9's
libsupc++.a with the libsupc++.a from previous versions if they use
std::rethrow_exception() anywhere.

Tested x86_64-linux, I plan to commit this to trunk soon.

commit 06a845f80204947afd6866109db58cc85dc87117
Author: Jonathan Wakely jwak...@redhat.com
Date:   Tue Mar 25 14:42:45 2014 +

PR libstdc++/60612
* libsupc++/eh_ptr.cc: Assert __cxa_dependent_exception layout is
compatible with __cxa_exception.
* libsupc++/unwind-cxx.h (__cxa_dependent_exception): Add padding.
Fix typos in comments.

std::rethrow_exception is broken

2014-03-24 Thread Jonathan Wakely
There is a lot of code in libsupc++/eh_* that relies on
__cxa_exception and __cxa_dependent_exception having similar layouts,
so tricks like this work:

static inline void*
__gxx_caught_object(_Unwind_Exception* eo)
{
  // Bad as it looks, this actually works for dependent exceptions too.
  __cxa_exception* header = __get_exception_header_from_ue (eo);
  return header-adjustedPtr;
}

The idea is that although the eo might be a pointer to the
unwindHeader member  of either __cxa_exception or
__cxa_dependent_exception, the adjustedPtr member will be always be at
the same location relative to the unwindHeader member, so it Just
Works.

Except it doesn't.

offsetof(__cxa_exception, unwindHeader) == 80
offsetof(__cxa_dependent_exception, unwindHeader) == 80
offsetof(__cxa_exception, adjustedPtr) == 72
offsetof(__cxa_dependent_exception, adjustedPtr) == 64

This is the cause of PR 60612, and means we need to fix a lot of code
by explicitly checking the exception class (see attached patch for a
partial fix doing that in two places) or we need to change the layout
of __cxa_dependent_exception (and then add some tests to verify the
assumptions implicit in the code!)

I don't think this is all fixable in time for 4.9.0, but the attached
patch fixes one part of the problem, so I'm probably going to commit
it and then work on a more complete fix later.
commit 0e783c3897f1d1905bd64129e6eb9902a523626a
Author: Jonathan Wakely jwak...@redhat.com
Date:   Mon Mar 24 12:30:20 2014 +

PR libstdc++/60612
* libsupc++/eh_call.cc (__cxa_call_terminate): Handle dependent
exceptions.
* libsupc++/eh_personality.cc (__cxa_call_unexpected): Likewise.
* libsupc++/unwind-cxx.h: Fix typos in comments.
* testsuite/18_support/exception_ptr/60612-terminate.cc: New.
* testsuite/18_support/exception_ptr/60612-unexpected.cc: New.

diff --git a/libstdc++-v3/libsupc++/eh_call.cc 
b/libstdc++-v3/libsupc++/eh_call.cc
index 7677692..ac75813 100644
--- a/libstdc++-v3/libsupc++/eh_call.cc
+++ b/libstdc++-v3/libsupc++/eh_call.cc
@@ -48,10 +48,12 @@ __cxa_call_terminate(_Unwind_Exception* ue_header) throw ()
   // exception.  */
   if (__is_gxx_exception_class(ue_header-exception_class))
{
- __cxa_exception* xh;
-
- xh = __get_exception_header_from_ue(ue_header);
- __terminate(xh-terminateHandler);
+ std::terminate_handler th;
+ if (__is_dependent_exception(ue_header-exception_class))
+   th = __get_dependent_exception_from_ue(ue_header)-terminateHandler;
+ else
+   th = __get_exception_header_from_ue(ue_header)-terminateHandler;
+ __terminate(th);
}
 }
   /* Call the global routine if we don't have anything better.  */
diff --git a/libstdc++-v3/libsupc++/eh_personality.cc 
b/libstdc++-v3/libsupc++/eh_personality.cc
index f315a83..698dc7d 100644
--- a/libstdc++-v3/libsupc++/eh_personality.cc
+++ b/libstdc++-v3/libsupc++/eh_personality.cc
@@ -737,20 +737,35 @@ __cxa_call_unexpected (void *exc_obj_in)
   } end_catch_protect_obj;
 
   lsda_header_info info;
-  __cxa_exception *xh = __get_exception_header_from_ue (exc_obj);
   const unsigned char *xh_lsda;
   _Unwind_Sword xh_switch_value;
   std::terminate_handler xh_terminate_handler;
-
+  std::unexpected_handler xh_unexpected_handler;
   // If the unexpectedHandler rethrows the exception (e.g. to categorize it),
   // it will clobber data about the current handler.  So copy the data out now.
-  xh_lsda = xh-languageSpecificData;
-  xh_switch_value = xh-handlerSwitchValue;
-  xh_terminate_handler = xh-terminateHandler;
-  info.ttype_base = (_Unwind_Ptr) xh-catchTemp;
+  if (__is_dependent_exception(exc_obj-exception_class))
+{
+  __cxa_dependent_exception *xh = __get_dependent_exception_from_ue 
(exc_obj);
+
+  xh_lsda = xh-languageSpecificData;
+  xh_switch_value = xh-handlerSwitchValue;
+  xh_terminate_handler = xh-terminateHandler;
+  xh_unexpected_handler = xh-unexpectedHandler;
+  info.ttype_base = (_Unwind_Ptr) xh-catchTemp;
+}
+  else
+{
+  __cxa_exception *xh = __get_exception_header_from_ue (exc_obj);
+
+  xh_lsda = xh-languageSpecificData;
+  xh_switch_value = xh-handlerSwitchValue;
+  xh_terminate_handler = xh-terminateHandler;
+  xh_unexpected_handler = xh-unexpectedHandler;
+  info.ttype_base = (_Unwind_Ptr) xh-catchTemp;
+}
 
   __try 
-{ __unexpected (xh-unexpectedHandler); } 
+{ __unexpected (xh_unexpected_handler); }
   __catch(...) 
 {
   // Get the exception thrown from unexpected.
diff --git a/libstdc++-v3/libsupc++/unwind-cxx.h 
b/libstdc++-v3/libsupc++/unwind-cxx.h
index a7df603..1ca6d94 100644
--- a/libstdc++-v3/libsupc++/unwind-cxx.h
+++ b/libstdc++-v3/libsupc++/unwind-cxx.h
@@ -81,7 +81,7 @@ struct __cxa_exception
   // Stack of exceptions in cleanups.
   __cxa_exception* nextPropagatingException;
 
-  // The nuber of active cleanup handlers