This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [c++0x] nested_exception


2009/5/11 Paolo Carlini:
> The patch looks pretty good to me: since we are in Stage 1 and in any
> case you are not adding any new exported symbols, I think it would make
> sense to check in the patch as-is, or with small modifications, even if
> the specs are not finalised. I would only suggest double checking for
> overlong lines, that trivial functions are inline, and preparing a
> ChangeLog entry.

Hi Paolo, thanks for the review.

I'll commit the attached patch, which adds some 'inline' keywords,
fixes the overlong line and also adjusts the manual.

        * libsupc++/exception: Include nested_exception.h in C++0x mode.
        * libsupc++/nested_exception.h: New.
        * libsupc++/Makefile.am: Add new header.
        * libsupc++/Makefile.in: Regenerate.
        * testsuite/18_support/nested_exception/rethrow_nested.cc: New.
        * testsuite/18_support/nested_exception/throw_with_nested.cc: New.
        * testsuite/18_support/nested_exception/cons.cc: New.
        * testsuite/18_support/nested_exception/nested_ptr.cc: New.
        * testsuite/18_support/nested_exception/rethrow_if_nested.cc: New.
        * doc/xml/manual/status_cxx200x.xml: Adjust.


Cheers,
Jonathan
Index: libsupc++/Makefile.am
===================================================================
--- libsupc++/Makefile.am	(revision 147392)
+++ libsupc++/Makefile.am	(working copy)
@@ -33,7 +33,7 @@ noinst_LTLIBRARIES = libsupc++convenienc
 
 headers = \
 	exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.h \
-	initializer_list exception_ptr.h
+	initializer_list exception_ptr.h nested_exception.h
 
 if GLIBCXX_HOSTED
   c_sources = \
Index: libsupc++/Makefile.in
===================================================================
--- libsupc++/Makefile.in	(revision 147392)
+++ libsupc++/Makefile.in	(working copy)
@@ -367,7 +367,7 @@ toolexeclib_LTLIBRARIES = libsupc++.la
 noinst_LTLIBRARIES = libsupc++convenience.la
 headers = \
 	exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.h \
-	initializer_list exception_ptr.h
+	initializer_list exception_ptr.h nested_exception.h
 
 @GLIBCXX_HOSTED_TRUE@c_sources = \
 @GLIBCXX_HOSTED_TRUE@	cp-demangle.c 
Index: libsupc++/exception
===================================================================
--- libsupc++/exception	(revision 147392)
+++ libsupc++/exception	(working copy)
@@ -146,6 +146,7 @@ _GLIBCXX_END_NAMESPACE
 #if (defined(__GXX_EXPERIMENTAL_CXX0X__) \
      && defined(_GLIBCXX_ATOMIC_BUILTINS_4))
 #include <exception_ptr.h>
+#include <nested_exception.h>
 #endif
 
 #endif
Index: libsupc++/nested_exception.h
===================================================================
--- libsupc++/nested_exception.h	(revision 0)
+++ libsupc++/nested_exception.h	(revision 0)
@@ -0,0 +1,177 @@
+// Nested Exception support header (nested_exception class) for -*- C++ -*-
+
+// Copyright (C) 2009 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file nested_exception.h
+ *  This is an internal header file, included by other headers and the
+ *  implementation. You should not attempt to use it directly.
+ */
+
+#ifndef _GLIBCXX_NESTED_EXCEPTION_H
+#define _GLIBCXX_NESTED_EXCEPTION_H 1
+
+#pragma GCC visibility push(default)
+
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
+# include <c++0x_warning.h>
+#else
+
+#include <bits/c++config.h>
+
+#if !defined(_GLIBCXX_ATOMIC_BUILTINS_4)
+#  error This platform does not support exception propagation.
+#endif
+
+extern "C++" {
+
+namespace std
+{
+  /**
+   * @addtogroup exceptions
+   * @{
+   */
+
+  /// nested_exception
+  class nested_exception
+  {
+  public:
+    nested_exception() throw() : _M_ptr(current_exception()) { }
+
+    nested_exception(const nested_exception&) throw() = default;
+
+    nested_exception& operator=(const nested_exception&) throw() = default;
+
+    virtual ~nested_exception() = default;
+
+    void
+    rethrow_nested() const __attribute__ ((__noreturn__))
+    { rethrow_exception(_M_ptr); }
+
+    exception_ptr
+    nested_ptr() const
+    { return _M_ptr; }
+
+  private:
+    exception_ptr _M_ptr;
+  };
+
+  template<typename _Except>
+    struct _Nested_exception : public _Except, public nested_exception
+    {
+      explicit
+      _Nested_exception(_Except&& __ex)
+      : _Except(static_cast<_Except&&>(__ex))
+      { }
+    };
+
+  template<typename _Ex>
+    struct __get_nested_helper
+    {
+      static const nested_exception*
+      _S_get(const _Ex& __ex)
+      {
+        return dynamic_cast<const nested_exception*>(&__ex);
+      }
+    };
+
+  template<typename _Ex>
+    struct __get_nested_helper<_Ex*>
+    {
+      static const nested_exception*
+      _S_get(const _Ex* __ex)
+      {
+        return dynamic_cast<const nested_exception*>(__ex);
+      }
+    };
+
+  template<typename _Ex>
+    inline const nested_exception*
+    __get_nested_exception(const _Ex& __ex)
+    {
+      return __get_nested_helper<_Ex>::_S_get(__ex);
+    }
+
+  template<typename _Ex>
+    void
+    __throw_with_nested(_Ex&&, const nested_exception* = 0)
+    __attribute__ ((__noreturn__));
+
+  template<typename _Ex>
+    void
+    __throw_with_nested(_Ex&&, ...) __attribute__ ((__noreturn__));
+
+  // This function should never be called, but is needed to avoid a warning
+  // about ambiguous base classes when instantiating throw_with_nested<_Ex>()
+  // with a type that has an accessible nested_exception base.
+  template<typename _Ex>
+    inline void
+    __throw_with_nested(_Ex&& __ex, const nested_exception* = 0)
+    {
+      throw __ex;
+    }
+
+  template<typename _Ex>
+    inline void
+    __throw_with_nested(_Ex&& __ex, ...)
+    {
+      throw _Nested_exception<_Ex>(static_cast<_Ex&&>(__ex));
+    }
+  
+  template<typename _Ex>
+    void
+    throw_with_nested(_Ex __ex) __attribute__ ((__noreturn__));
+
+  template<typename _Ex>
+    inline void
+    throw_with_nested(_Ex __ex)
+    {
+      if (__get_nested_exception(__ex))
+        throw __ex;
+      __throw_with_nested(static_cast<_Ex&&>(__ex), &__ex);
+    }
+
+  template<typename _Ex>
+    inline void
+    rethrow_if_nested(const _Ex& __ex)
+    {
+      if (const nested_exception* __nested = __get_nested_exception(__ex))
+        __nested->rethrow_nested();
+    }
+
+  // see n2619
+  inline void
+  rethrow_if_nested(const nested_exception& __ex)
+  {
+    __ex.rethrow_nested();
+  }
+
+  // @} group exceptions
+} // namespace std
+
+} // extern "C++"
+
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
+#pragma GCC visibility pop
+
+#endif // _GLIBCXX_NESTED_EXCEPTION_H
Index: testsuite/18_support/nested_exception/rethrow_nested.cc
===================================================================
--- testsuite/18_support/nested_exception/rethrow_nested.cc	(revision 0)
+++ testsuite/18_support/nested_exception/rethrow_nested.cc	(revision 0)
@@ -0,0 +1,53 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-atomic-builtins "" }
+
+// Copyright (C) 2009 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 <testsuite_hooks.h>
+
+void test01() 
+{
+  bool test __attribute__((unused)) = false;
+
+  try
+  {
+    try
+    {
+      throw 42;
+    }
+    catch (...)
+    {
+      std::nested_exception e;
+      e.rethrow_nested();
+    }
+  }
+  catch(const int& i)
+  {
+    test = true;
+    VERIFY( i == 42 );
+  }
+
+  VERIFY( test );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/18_support/nested_exception/throw_with_nested.cc
===================================================================
--- testsuite/18_support/nested_exception/throw_with_nested.cc	(revision 0)
+++ testsuite/18_support/nested_exception/throw_with_nested.cc	(revision 0)
@@ -0,0 +1,79 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-atomic-builtins "" }
+
+// Copyright (C) 2009 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 <testsuite_hooks.h>
+
+struct derived : std::nested_exception { };
+
+struct not_derived { virtual ~not_derived() = default; };
+
+void test01() 
+{
+  bool test __attribute__((unused)) = false;
+
+  try
+  {
+    std::throw_with_nested(derived());
+  }
+  catch (const std::nested_exception& e)
+  {
+    VERIFY( !e.nested_ptr() );
+    try
+    {
+      throw;
+    }
+    catch (const derived&)
+    {
+      test = true;
+    }
+  }
+  VERIFY( test );
+}
+
+void test02() 
+{
+  bool test __attribute__((unused)) = false;
+
+  try
+  {
+    std::throw_with_nested(not_derived());
+  }
+  catch (const std::nested_exception& e)
+  {
+    VERIFY( !e.nested_ptr() );
+    try
+    {
+      throw;
+    }
+    catch (const not_derived&)
+    {
+      test = true;
+    }
+  }
+  VERIFY( test );
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
Index: testsuite/18_support/nested_exception/cons.cc
===================================================================
--- testsuite/18_support/nested_exception/cons.cc	(revision 0)
+++ testsuite/18_support/nested_exception/cons.cc	(revision 0)
@@ -0,0 +1,53 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-atomic-builtins "" }
+
+// Copyright (C) 2009 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 <testsuite_hooks.h>
+
+void test01() 
+{
+  bool test __attribute__((unused)) = true;
+
+  std::nested_exception e;
+
+  VERIFY( !e.nested_ptr() );
+}
+
+void test02() 
+{
+  bool test __attribute__((unused)) = true;
+
+  try
+  {
+    throw 42;
+  }
+  catch (...)
+  {
+    std::nested_exception e;
+    VERIFY( e.nested_ptr() == std::current_exception() );
+  }
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
Index: testsuite/18_support/nested_exception/nested_ptr.cc
===================================================================
--- testsuite/18_support/nested_exception/nested_ptr.cc	(revision 0)
+++ testsuite/18_support/nested_exception/nested_ptr.cc	(revision 0)
@@ -0,0 +1,71 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-atomic-builtins "" }
+
+// Copyright (C) 2009 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 <testsuite_hooks.h>
+
+void test01() 
+{
+  bool test __attribute__((unused)) = true;
+
+  try
+  {
+    throw std::nested_exception();
+  }
+  catch (const std::nested_exception& e)
+  {
+    VERIFY( !e.nested_ptr() );
+  }
+}
+
+void test02() 
+{
+  bool test __attribute__((unused)) = true;
+
+  try
+  {
+    throw 42;
+  }
+  catch (...)
+  {
+    try
+    {
+      throw std::nested_exception();
+    }
+    catch (const std::nested_exception& e)
+    {
+      try
+      {
+	std::rethrow_exception( e.nested_ptr() );
+      }
+      catch(const int& i)
+      {
+	VERIFY( i == 42 );
+      }
+    }
+  }
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
Index: testsuite/18_support/nested_exception/rethrow_if_nested.cc
===================================================================
--- testsuite/18_support/nested_exception/rethrow_if_nested.cc	(revision 0)
+++ testsuite/18_support/nested_exception/rethrow_if_nested.cc	(revision 0)
@@ -0,0 +1,110 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-atomic-builtins "" }
+
+// Copyright (C) 2009 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 <testsuite_hooks.h>
+
+struct derived : std::nested_exception { };
+
+struct base { virtual ~base() = default; };
+
+struct derived2 : base, std::nested_exception { };
+
+void test01() 
+{
+  bool test __attribute__((unused)) = false;
+
+  try
+  {
+    throw 42;
+  }
+  catch (...)
+  {
+    derived d;
+    try
+    {
+      std::rethrow_if_nested(d);
+    }
+    catch (const int& i)
+    {
+      test = true;
+      VERIFY( i == 42 );
+    }
+  }
+
+  VERIFY( test );
+}
+
+void test02() 
+{
+  bool test __attribute__((unused)) = false;
+
+  try
+  {
+    throw base();
+  }
+  catch (const base& b)
+  {
+    std::rethrow_if_nested(b);
+    test = true;
+  }
+
+  VERIFY( test );
+}
+
+void test03() 
+{
+  bool test __attribute__((unused)) = false;
+
+  try
+  {
+    throw 42;
+  }
+  catch (...)
+  {
+    try
+    {
+      throw derived2();
+    }
+    catch (const base& b)
+    {
+      try
+      {
+        std::rethrow_if_nested(b);
+      }
+      catch (const int& i)
+      {
+        VERIFY( i == 42 );
+        test = true;
+      }
+    }
+  }
+
+  VERIFY( test );
+}
+
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  return 0;
+}
Index: doc/xml/manual/status_cxx200x.xml
===================================================================
--- doc/xml/manual/status_cxx200x.xml	(revision 147392)
+++ doc/xml/manual/status_cxx200x.xml	(working copy)
@@ -235,10 +235,9 @@ particular release.
       <entry></entry>
     </row>
     <row>
-      <?dbhtml bgcolor="#C8B0B0" ?> 
       <entry>18.8.6</entry>
       <entry>Class <code>nested_exception</code></entry>
-      <entry>N</entry>
+      <entry>Y</entry>
       <entry></entry>
     </row>
     <row>

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]