| Index: tests/toolchain/eh_throw_tests.cc
 | 
| diff --git a/tests/toolchain/eh_throw_tests.cc b/tests/toolchain/eh_throw_tests.cc
 | 
| index aae794f618892f08c213d9fc9b93048c19f89d34..0c0baaca0269caf30d09861bec5a6d516ddc5ed9 100644
 | 
| --- a/tests/toolchain/eh_throw_tests.cc
 | 
| +++ b/tests/toolchain/eh_throw_tests.cc
 | 
| @@ -472,6 +472,93 @@ void test_exception_spec_bad_throw_from_unexpected_handler() {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +#if SUPPORTS_CXX11
 | 
| +
 | 
| +// Test std::current_exception() and std::rethrow_exception(), which
 | 
| +// were added in C++11.  The std::exception_ptr type allows capturing
 | 
| +// a reference to an exception, which can have a lifetime outside a
 | 
| +// catch() block and so is refcounted.  This is called a "dependent
 | 
| +// exception" (__cxa_dependent_exception) inside libsupc++/libcxxabi.
 | 
| +void test_dependent_exception() {
 | 
| +  assert(!std::current_exception());
 | 
| +
 | 
| +  std::exception_ptr exc_ptr;
 | 
| +  int *ptr_to_value;
 | 
| +  try {
 | 
| +    throw MyException(400);
 | 
| +  } catch (MyException &exc) {
 | 
| +    ptr_to_value = &exc.value;
 | 
| +    exc_ptr = std::current_exception();
 | 
| +  }
 | 
| +
 | 
| +  try {
 | 
| +    std::rethrow_exception(exc_ptr);
 | 
| +  } catch (MyException &exc) {
 | 
| +    assert(exc.value == 400);
 | 
| +    // The exception is refcounted and not copied.
 | 
| +    assert(&exc.value == ptr_to_value);
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +
 | 
| +__attribute__((noinline))
 | 
| +void rethrow_through_dtor(bool *ptr) {
 | 
| +  Dtor dtor(ptr);
 | 
| +  std::rethrow_exception(std::current_exception());
 | 
| +}
 | 
| +
 | 
| +// Similar to test_dtor(), but testing a dependent exception (i.e. one
 | 
| +// thrown with std::rethrow_exception()).
 | 
| +//
 | 
| +// This tests that the C++ runtime library handles dependent
 | 
| +// exceptions correctly when the first matching landingpad is a
 | 
| +// cleanup handler.
 | 
| +void test_dependent_exception_and_dtor() {
 | 
| +  try {
 | 
| +    throw MyException(500);
 | 
| +  } catch (MyException &exc) {
 | 
| +    bool caught = false;
 | 
| +    try {
 | 
| +      rethrow_through_dtor(&caught);
 | 
| +    } catch (MyException &exc2) {
 | 
| +      assert(caught);
 | 
| +      return;
 | 
| +    }
 | 
| +  }
 | 
| +  assert(false);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void throw_dependent_exception() {
 | 
| +  try {
 | 
| +    throw RethrowExc();
 | 
| +  } catch (...) {
 | 
| +    std::rethrow_exception(std::current_exception());
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +// Test the case in which a std::set_unexpected() handler throws an
 | 
| +// exception using std::rethrow_exception().
 | 
| +//
 | 
| +// This tests that __cxa_call_unexpected() handles dependent
 | 
| +// exceptions correctly.
 | 
| +void test_dependent_exception_and_exception_spec() {
 | 
| +  std::unexpected_handler old_unexpected_handler =
 | 
| +      std::set_unexpected(throw_dependent_exception);
 | 
| +  bool caught = false;
 | 
| +  try {
 | 
| +    func_with_exception_spec();
 | 
| +  } catch (RethrowExc &) {
 | 
| +    caught = true;
 | 
| +  }
 | 
| +  assert(caught);
 | 
| +  // Clean up.
 | 
| +  std::set_unexpected(old_unexpected_handler);
 | 
| +}
 | 
| +
 | 
| +#endif
 | 
| +
 | 
| +
 | 
|  #define RUN_TEST(CALL) printf("Running %s\n", #CALL); CALL;
 | 
|  
 | 
|  int main() {
 | 
| @@ -492,6 +579,11 @@ int main() {
 | 
|    RUN_TEST(test_exception_spec());
 | 
|    RUN_TEST(test_exception_spec_rethrow_inside_unexpected_handler());
 | 
|    RUN_TEST(test_exception_spec_convert_to_bad_exception());
 | 
| +#if SUPPORTS_CXX11
 | 
| +  RUN_TEST(test_dependent_exception());
 | 
| +  RUN_TEST(test_dependent_exception_and_dtor());
 | 
| +  RUN_TEST(test_dependent_exception_and_exception_spec());
 | 
| +#endif
 | 
|    // This leaves behind an active exception because of its use of
 | 
|    // longjmp() to exit from a std::set_terminate() handler, so put it
 | 
|    // last, just in case that accidentally affects other tests.
 | 
| 
 |